mirror of
https://github.com/github/codeql.git
synced 2026-01-29 14:23:03 +01:00
Fix conflicting
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
|
||||
<p>If unsanitized user input is written to a log entry, a malicious user may be able to forge new log entries.</p>
|
||||
|
||||
<p>Forgery can occur if a user provides some input creating the appearance of multiple
|
||||
log entries. This can include unescaped new-line characters, or HTML or other markup.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
User input should be suitably sanitized before it is logged.
|
||||
</p>
|
||||
<p>
|
||||
If the log entries are plain text then line breaks should be removed from user input, using for example
|
||||
<code>replace(old, new)</code> or similar. Care should also be taken that user input is clearly marked
|
||||
in log entries, and that a malicious user cannot cause confusion in other ways.
|
||||
</p>
|
||||
<p>
|
||||
For log entries that will be displayed in HTML, user input should be HTML encoded before being logged, to prevent forgery and
|
||||
other forms of HTML injection.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the example, the name provided by the user is recorded using the log output function (<code>logging.info</code> or <code>app.logger.info</code>, etc.).
|
||||
In these four cases, the name provided by the user is not provided The processing is recorded. If a malicious user provides <code>Guest%0D%0AUser name: Admin</code>
|
||||
as a parameter, the log entry will be divided into two lines, the first line is <code>User name: Guest</code> code>, the second line is <code>User name: Admin</code>.
|
||||
</p>
|
||||
<sample src="LogInjectionBad.py" />
|
||||
|
||||
<p>
|
||||
In a good example, the program uses the <code>replace</code> function to provide parameter processing to the user, and replace <code>\r\n</code> and <code>\n</code>
|
||||
with empty characters. To a certain extent, the occurrence of log injection vulnerabilities is reduced.
|
||||
</p>
|
||||
|
||||
<sample src="LogInjectionGood.py" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>OWASP: <a href="https://owasp.org/www-community/attacks/Log_Injection">Log Injection</a>.</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
20
python/ql/src/experimental/Security/CWE-117/LogInjection.ql
Normal file
20
python/ql/src/experimental/Security/CWE-117/LogInjection.ql
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @name Log Injection
|
||||
* @description Building log entries from user-controlled data is vulnerable to
|
||||
* insertion of forged log entries by a malicious user.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id py/log-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-117
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.semmle.python.security.injection.LogInjection
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from LogInjectionFlowConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows to log entry.", source.getNode(),
|
||||
"User-provided value"
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""
|
||||
@Desc :Log Injection
|
||||
"""
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
from django.utils.log import request_logger
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/bad1')
|
||||
def bad1():
|
||||
name = request.args.get('name')
|
||||
app.logger.info('User name: ' + name) # Bad
|
||||
return 'bad1'
|
||||
|
||||
@app.route('/bad2')
|
||||
def bad2():
|
||||
name = request.args.get('name')
|
||||
logging.info('User name: ' + name) # Bad
|
||||
return 'bad2'
|
||||
|
||||
@app.route('/bad3')
|
||||
def bad3():
|
||||
name = request.args.get('name')
|
||||
request_logger.warn('User name: ' + name) # Bad
|
||||
return 'bad3'
|
||||
|
||||
@app.route('/bad4')
|
||||
def bad4():
|
||||
name = request.args.get('name')
|
||||
logtest = logging.getLogger('test')
|
||||
logtest.debug('User name: ' + name) # Bad
|
||||
return 'bad4'
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.debug = True
|
||||
handler = logging.FileHandler('log')
|
||||
app.logger.addHandler(handler)
|
||||
app.run()
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""
|
||||
@Desc :Log Injection
|
||||
"""
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/good1')
|
||||
def good1():
|
||||
name = request.args.get('name')
|
||||
name = name.replace('\r\n','').replace('\n','')
|
||||
logging.info('User name: ' + name) # Good
|
||||
return 'good1'
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.debug = True
|
||||
handler = logging.FileHandler('log')
|
||||
app.logger.addHandler(handler)
|
||||
app.run()
|
||||
Reference in New Issue
Block a user