Skip to content

Commit 9ad152f

Browse files
added qhelp file
1 parent 360014f commit 9ad152f

File tree

2 files changed

+64
-18
lines changed

2 files changed

+64
-18
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>If unsanitized user input is written to a log entry, a malicious user may
7+
be able to forge new log entries.</p>
8+
9+
<p>Forgery can occur if a user provides some input with characters that are interpreted
10+
when the log output is displayed. If the log is displayed as a plain text file, then new
11+
line characters can be used by a malicious user. If the log is displayed as HTML, then
12+
arbitrary HTML may be included to spoof log entries.</p>
13+
</overview>
14+
15+
<recommendation>
16+
<p>
17+
User input should be suitably encoded before it is logged.
18+
</p>
19+
<p>
20+
If the log entries are plain text then line breaks should be removed from user input, using
21+
<code>strings.Replace</code> or similar. Care should also be taken that user input is clearly marked
22+
in log entries, and that a malicious user cannot cause confusion in other ways.
23+
</p>
24+
<p>
25+
For log entries that will be displayed in HTML, user input should be HTML encoded using
26+
<code>html.EscapeString</code> or similar before being logged, to prevent forgery and
27+
other forms of HTML injection.
28+
</p>
29+
30+
</recommendation>
31+
32+
<example>
33+
<p>
34+
In the following example, a user name, provided by the user, is logged using a logging framework without any sanitization.
35+
</p>
36+
<sample src="example/example_bad.go" />
37+
<p>
38+
In the next example, <code>strings.Replace</code> is used to ensure no line endings are present in the user input.
39+
</p>
40+
<sample src="example/example_good.go" />
41+
</example>
42+
43+
<references>
44+
<li>OWASP: <a href="https://www.owasp.org/index.php/Log_Injection">Log Injection</a>.</li>
45+
</references>
46+
</qhelp>

go/ql/src/experimental/CWE-117/LogSanitizer.ql

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
/**
2-
* LogSanitizer.ql
3-
*
4-
* Filter/suppress log-injection findings when the taint flow can be shown to
5-
* pass through a sanitizer (including zap custom encoders).
6-
*
7-
* NOTE: This is a conservative template. Integrate with your existing
8-
* taint-tracking / source/sink predicates used by your log-injection rules.
2+
* @name Log entries created from user input
3+
* @description Building log entries from user-controlled sources is vulnerable to
4+
* insertion of forged log entries by a malicious user.
5+
* @kind path-problem
6+
* @problem.severity error
7+
* @id go/log-injection
8+
* @tags security
9+
* experimental
10+
* external/cwe/cwe-287
911
*/
1012

13+
import go
14+
import semmle.go.security.LogInjection
15+
import LogInjection::Flow::PathGraph
16+
17+
from LogInjection::Flow::PathNode source, LogInjection::Flow::PathNode sink
18+
where LogInjection::Flow::flowPath(source, sink)
19+
select sink.getNode(), source, sink, "This log entry depends on a $@.", source.getNode(),
20+
"user-provided value"
21+
1122
import go
1223
import go.security.dataflow.TaintTracking as T
13-
// adjust imports above if your repo uses a different taint package
1424

15-
// Reuse the library predicates
1625
import LogSanitizer
1726

18-
/**
19-
* A wrapper sink used for demonstration. Replace with the actual log sink
20-
* definitions used by your log-injection query if you want precise suppression.
21-
*/
2227
class LogSink extends T.Sink {
2328
LogSink() { this = T.Sink("LogSink") }
2429
}
2530

26-
/**
27-
* Find flows from sources to log sinks but ignore flows that pass through a sanitizer.
28-
* This query demonstrates the pattern — adapt to concrete source/sink definitions.
29-
*/
3031
from T.Source src, T.Sink sink, Function sanitizerFn
3132
where
3233
src.flowsTo(sink) and
3334
not exists(sanitizerFn |
3435
isSanitizer(sanitizerFn) and
35-
// sanitizer function appears somewhere on the flow path
3636
src.flowsTo(sanitizerFn) and
3737
sanitizerFn.flowsTo(sink)
3838
)

0 commit comments

Comments
 (0)