Skip to content

Commit a2fd4ee

Browse files
committed
Java: Diff-informed information leak queries
1 parent 05b8e18 commit a2fd4ee

File tree

3 files changed

+61
-8
lines changed

3 files changed

+61
-8
lines changed

java/ql/lib/semmle/code/java/security/InformationLeak.qll

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,44 @@ import semmle.code.java.dataflow.DataFlow
55
private import semmle.code.java.dataflow.ExternalFlow
66
import semmle.code.java.security.XSS
77

8-
/** A sink that represent a method that outputs data to an HTTP response. */
9-
abstract class InformationLeakSink extends DataFlow::Node { }
8+
/**
9+
* A sink that represent a method that outputs data to an HTTP response. Extend
10+
* this class to add more sinks that should be considered information leak
11+
* points by every query. To find the full set of information-leak sinks, use
12+
* `InformationLeakSink` instead.
13+
*/
14+
abstract class AbstractInformationLeakSink extends DataFlow::Node { }
15+
16+
/**
17+
* A sink that represent a method that outputs data to an HTTP response. To add
18+
* more sinks, extend `AbstractInformationLeakSink` rather than this class.
19+
*/
20+
final class InformationLeakSink extends DataFlow::Node instanceof InformationLeakDiffInformed<xssNotDiffInformed/0>::InformationLeakSink
21+
{ }
1022

1123
/** A default sink representing methods outputing data to an HTTP response. */
12-
private class DefaultInformationLeakSink extends InformationLeakSink {
13-
DefaultInformationLeakSink() {
14-
sinkNode(this, "information-leak") or
15-
this instanceof XssSink
24+
private class DefaultInformationLeakSink extends AbstractInformationLeakSink {
25+
DefaultInformationLeakSink() { sinkNode(this, "information-leak") }
26+
}
27+
28+
/**
29+
* A module for finding information-leak sinks faster in a diff-informed query.
30+
* The `hasSourceInDiffRange` parameter should hold if the overall data-flow
31+
* configuration of the query has any sources in the diff range.
32+
*/
33+
module InformationLeakDiffInformed<xssNullaryPredicate/0 hasSourceInDiffRange> {
34+
final private class Node = DataFlow::Node;
35+
36+
/**
37+
* A diff-informed replacement for the top-level `InformationLeakSink`,
38+
* omitting for efficiency some sinks that would never be reported by a
39+
* diff-informed query.
40+
*/
41+
final class InformationLeakSink extends Node {
42+
InformationLeakSink() {
43+
this instanceof AbstractInformationLeakSink
44+
or
45+
this instanceof XssDiffInformed<hasSourceInDiffRange/0>::XssSink
46+
}
1647
}
1748
}

java/ql/lib/semmle/code/java/security/SensitiveDataExposureThroughErrorMessageQuery.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ private class GetMessageFlowSource extends ApiSourceNode {
2020
private module GetMessageFlowSourceToHttpResponseSinkFlowConfig implements DataFlow::ConfigSig {
2121
predicate isSource(DataFlow::Node src) { src instanceof GetMessageFlowSource }
2222

23-
predicate isSink(DataFlow::Node sink) { sink instanceof InformationLeakSink }
23+
predicate isSink(DataFlow::Node sink) {
24+
sink instanceof
25+
InformationLeakDiffInformed<GetMessageFlowSourceToHttpResponseSinkFlow::hasSourceInDiffRange/0>::InformationLeakSink
26+
}
27+
28+
predicate observeDiffInformedIncrementalMode() { any() }
2429
}
2530

2631
private module GetMessageFlowSourceToHttpResponseSinkFlow =

java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ private module ServletWriterSourceToPrintStackTraceMethodFlowConfig implements D
2525
sink.asExpr() = ma.getAnArgument() and ma.getMethod() instanceof PrintStackTraceMethod
2626
)
2727
}
28+
29+
predicate observeDiffInformedIncrementalMode() { any() }
30+
31+
Location getASelectedSinkLocation(DataFlow::Node sink) {
32+
exists(MethodCall ma | result = ma.getLocation() |
33+
sink.asExpr() = ma.getAnArgument() and ma.getMethod() instanceof PrintStackTraceMethod
34+
)
35+
}
2836
}
2937

3038
private module ServletWriterSourceToPrintStackTraceMethodFlow =
@@ -69,7 +77,16 @@ private predicate stackTraceExpr(Expr exception, MethodCall stackTraceString) {
6977
private module StackTraceStringToHttpResponseSinkFlowConfig implements DataFlow::ConfigSig {
7078
predicate isSource(DataFlow::Node src) { stackTraceExpr(_, src.asExpr()) }
7179

72-
predicate isSink(DataFlow::Node sink) { sink instanceof InformationLeakSink }
80+
predicate isSink(DataFlow::Node sink) {
81+
sink instanceof
82+
InformationLeakDiffInformed<StackTraceStringToHttpResponseSinkFlow::hasSourceInDiffRange/0>::InformationLeakSink
83+
}
84+
85+
predicate observeDiffInformedIncrementalMode() { any() }
86+
87+
Location getASelectedSourceLocation(DataFlow::Node source) {
88+
exists(Expr e | stackTraceExpr(e, source.asExpr()) and result = e.getLocation())
89+
}
7390
}
7491

7592
private module StackTraceStringToHttpResponseSinkFlow =

0 commit comments

Comments
 (0)