Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6922074

Browse files
author
Robert Marsh
committed
Merge branch 'master' into rdmarsh/cpp/ir-flow-through-outparams
2 parents 677f0f0 + 180e9d4 commit 6922074

152 files changed

Lines changed: 9655 additions & 4798 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

change-notes/1.24/analysis-csharp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ The following changes in version 1.24 affect C# analysis in all applications.
1818
| **Query** | **Expected impact** | **Change** |
1919
|------------------------------|------------------------|-----------------------------------|
2020
| Useless assignment to local variable (`cs/useless-assignment-to-local`) | Fewer false positive results | Results have been removed when the variable is named `_` in a `foreach` statement. |
21+
| Potentially dangerous use of non-short-circuit logic (`cs/non-short-circuit`) | Fewer false positive results | Results have been removed when the expression contains an `out` parameter. |
2122
| Dereferenced variable may be null (`cs/dereferenced-value-may-be-null`) | More results | Results are reported from parameters with a default value of `null`. |
2223

2324
## Removal of old queries

change-notes/1.24/analysis-java.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ The following changes in version 1.24 affect Java analysis in all applications.
1010

1111
| **Query** | **Tags** | **Purpose** |
1212
|-----------------------------|-----------|--------------------------------------------------------------------|
13-
| Disabled Spring CSRF protection (`java/spring-disabled-csrf-protection`) | security, external/cwe/cwe-352 | Finds disabled Cross-Site Request Forgery (CSRF) protection in Spring. |
13+
| Disabled Spring CSRF protection (`java/spring-disabled-csrf-protection`) | security, external/cwe/cwe-352 | Finds disabled Cross-Site Request Forgery (CSRF) protection in Spring. Results are shown on LGTM by default. |
1414
| Failure to use HTTPS or SFTP URL in Maven artifact upload/download (`java/maven/non-https-url`) | security, external/cwe/cwe-300, external/cwe/cwe-319, external/cwe/cwe-494, external/cwe/cwe-829 | Finds use of insecure protocols during Maven dependency resolution. Results are shown on LGTM by default. |
15+
| LDAP query built from user-controlled sources (`java/ldap-injection`) | security, external/cwe/cwe-090 | Finds LDAP queries vulnerable to injection of unsanitized user-controlled input. Results are shown on LGTM by default. |
1516
| Left shift by more than the type width (`java/lshift-larger-than-type-width`) | correctness | Finds left shifts of ints by 32 bits or more and left shifts of longs by 64 bits or more. Results are shown on LGTM by default. |
16-
| Suspicious date format (`java/suspicious-date-format`) | correctness | Finds date format patterns that use placeholders that are likely to be incorrect. |
17+
| Suspicious date format (`java/suspicious-date-format`) | correctness | Finds date format patterns that use placeholders that are likely to be incorrect. Results are shown on LGTM by default. |
1718

1819
## Changes to existing queries
1920

change-notes/1.24/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
| Expression has no effect (`js/useless-expression`) | Fewer false positive results | The query now recognizes block-level flow type annotations and ignores the first statement of a try block. |
4343
| Use of call stack introspection in strict mode (`js/strict-mode-call-stack-introspection`) | Fewer false positive results | The query no longer flags expression statements. |
4444
| Missing CSRF middleware (`js/missing-token-validation`) | Fewer false positive results | The query reports fewer duplicates and only flags handlers that explicitly access cookie data. |
45+
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional ways dangerous paths can be constructed. |
4546

4647
## Changes to libraries
4748

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
20412041
result = getSuccMid()
20422042
or
20432043
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
2044-
exists(PathNodeMid mid |
2044+
exists(PathNodeMid mid, PathNodeSink sink |
20452045
mid = getSuccMid() and
2046-
mid.getNode() = result.getNode() and
2046+
mid.getNode() = sink.getNode() and
20472047
mid.getAp() instanceof AccessPathNil and
2048-
result instanceof PathNodeSink and
2049-
result.getConfiguration() = unbind(mid.getConfiguration())
2048+
sink.getConfiguration() = unbind(mid.getConfiguration()) and
2049+
result = sink
20502050
)
20512051
}
20522052

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
20412041
result = getSuccMid()
20422042
or
20432043
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
2044-
exists(PathNodeMid mid |
2044+
exists(PathNodeMid mid, PathNodeSink sink |
20452045
mid = getSuccMid() and
2046-
mid.getNode() = result.getNode() and
2046+
mid.getNode() = sink.getNode() and
20472047
mid.getAp() instanceof AccessPathNil and
2048-
result instanceof PathNodeSink and
2049-
result.getConfiguration() = unbind(mid.getConfiguration())
2048+
sink.getConfiguration() = unbind(mid.getConfiguration()) and
2049+
result = sink
20502050
)
20512051
}
20522052

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
20412041
result = getSuccMid()
20422042
or
20432043
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
2044-
exists(PathNodeMid mid |
2044+
exists(PathNodeMid mid, PathNodeSink sink |
20452045
mid = getSuccMid() and
2046-
mid.getNode() = result.getNode() and
2046+
mid.getNode() = sink.getNode() and
20472047
mid.getAp() instanceof AccessPathNil and
2048-
result instanceof PathNodeSink and
2049-
result.getConfiguration() = unbind(mid.getConfiguration())
2048+
sink.getConfiguration() = unbind(mid.getConfiguration()) and
2049+
result = sink
20502050
)
20512051
}
20522052

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
20412041
result = getSuccMid()
20422042
or
20432043
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
2044-
exists(PathNodeMid mid |
2044+
exists(PathNodeMid mid, PathNodeSink sink |
20452045
mid = getSuccMid() and
2046-
mid.getNode() = result.getNode() and
2046+
mid.getNode() = sink.getNode() and
20472047
mid.getAp() instanceof AccessPathNil and
2048-
result instanceof PathNodeSink and
2049-
result.getConfiguration() = unbind(mid.getConfiguration())
2048+
sink.getConfiguration() = unbind(mid.getConfiguration()) and
2049+
result = sink
20502050
)
20512051
}
20522052

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
20412041
result = getSuccMid()
20422042
or
20432043
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
2044-
exists(PathNodeMid mid |
2044+
exists(PathNodeMid mid, PathNodeSink sink |
20452045
mid = getSuccMid() and
2046-
mid.getNode() = result.getNode() and
2046+
mid.getNode() = sink.getNode() and
20472047
mid.getAp() instanceof AccessPathNil and
2048-
result instanceof PathNodeSink and
2049-
result.getConfiguration() = unbind(mid.getConfiguration())
2048+
sink.getConfiguration() = unbind(mid.getConfiguration()) and
2049+
result = sink
20502050
)
20512051
}
20522052

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ private import cpp
66
private import semmle.code.cpp.dataflow.internal.FlowVar
77
private import semmle.code.cpp.models.interfaces.DataFlow
88
private import semmle.code.cpp.controlflow.Guards
9-
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
109

1110
cached
1211
private newtype TNode =
@@ -689,9 +688,9 @@ class BarrierGuard extends GuardCondition {
689688

690689
/** Gets a node guarded by this guard. */
691690
final ExprNode getAGuardedNode() {
692-
exists(GVN value, boolean branch |
693-
result.getExpr() = value.getAnExpr() and
694-
this.checks(value.getAnExpr(), branch) and
691+
exists(SsaDefinition def, Variable v, boolean branch |
692+
result.getExpr() = def.getAUse(v) and
693+
this.checks(def.getAUse(v), branch) and
695694
this.controls(result.getExpr().getBasicBlock(), branch)
696695
)
697696
}

cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,40 @@ private predicate predictableInstruction(Instruction instr) {
2121
predictableInstruction(instr.(UnaryInstruction).getUnary())
2222
}
2323

24+
/**
25+
* Functions that we should only allow taint to flow through (to the return
26+
* value) if all but the source argument are 'predictable'. This is done to
27+
* emulate the old security library's implementation rather than due to any
28+
* strong belief that this is the right approach.
29+
*
30+
* Note that the list itself is not very principled; it consists of all the
31+
* functions listed in the old security library's [default] `isPureFunction`
32+
* that have more than one argument, but are not in the old taint tracking
33+
* library's `returnArgument` predicate. In addition, `strlen` is included
34+
* because it's also a special case in flow to return values.
35+
*/
36+
predicate predictableOnlyFlow(string name) {
37+
name = "strcasestr" or
38+
name = "strchnul" or
39+
name = "strchr" or
40+
name = "strchrnul" or
41+
name = "strcmp" or
42+
name = "strcspn" or
43+
name = "strlen" or // special case
44+
name = "strncmp" or
45+
name = "strndup" or
46+
name = "strnlen" or
47+
name = "strrchr" or
48+
name = "strspn" or
49+
name = "strstr" or
50+
name = "strtod" or
51+
name = "strtof" or
52+
name = "strtol" or
53+
name = "strtoll" or
54+
name = "strtoq" or
55+
name = "strtoul"
56+
}
57+
2458
private DataFlow::Node getNodeForSource(Expr source) {
2559
isUserInput(source, _) and
2660
(
@@ -123,15 +157,16 @@ private predicate nodeIsBarrier(DataFlow::Node node) {
123157

124158
private predicate instructionTaintStep(Instruction i1, Instruction i2) {
125159
// Expressions computed from tainted data are also tainted
126-
i2 =
127-
any(CallInstruction call |
128-
isPureFunction(call.getStaticCallTarget().getName()) and
129-
call.getAnArgument() = i1 and
130-
forall(Instruction arg | arg = call.getAnArgument() | arg = i1 or predictableInstruction(arg)) and
131-
// flow through `strlen` tends to cause dubious results, if the length is
132-
// bounded.
133-
not call.getStaticCallTarget().getName() = "strlen"
134-
)
160+
exists(CallInstruction call, int argIndex | call = i2 |
161+
isPureFunction(call.getStaticCallTarget().getName()) and
162+
i1 = getACallArgumentOrIndirection(call, argIndex) and
163+
forall(Instruction arg | arg = call.getAnArgument() |
164+
arg = getACallArgumentOrIndirection(call, argIndex) or predictableInstruction(arg)
165+
) and
166+
// flow through `strlen` tends to cause dubious results, if the length is
167+
// bounded.
168+
not call.getStaticCallTarget().getName() = "strlen"
169+
)
135170
or
136171
// Flow through pointer dereference
137172
i2.(LoadInstruction).getSourceAddress() = i1
@@ -174,7 +209,8 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
174209
any(CallInstruction call |
175210
exists(int indexIn |
176211
modelTaintToReturnValue(call.getStaticCallTarget(), indexIn) and
177-
i1 = getACallArgumentOrIndirection(call, indexIn)
212+
i1 = getACallArgumentOrIndirection(call, indexIn) and
213+
not predictableOnlyFlow(call.getStaticCallTarget().getName())
178214
)
179215
)
180216
or

0 commit comments

Comments
 (0)