Skip to content

Commit e3d75c4

Browse files
authored
Merge branch 'main' into py-mad-xss
2 parents cf65ab8 + 69b98c7 commit e3d75c4

File tree

87 files changed

+1712
-223
lines changed

Some content is hidden

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

87 files changed

+1712
-223
lines changed

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,7 +2706,7 @@ module Impl<FullStateConfigSig Config> {
27062706

27072707
ParamNodeEx getParamNode() { result = p }
27082708

2709-
override string toString() { result = p + ": " + ap }
2709+
override string toString() { result = p + concat(" : " + ppReprType(t)) + " " + ap }
27102710

27112711
predicate hasLocationInfo(
27122712
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -2758,12 +2758,21 @@ module Impl<FullStateConfigSig Config> {
27582758
)
27592759
}
27602760

2761+
private predicate forceUnfold(AccessPathApprox apa) {
2762+
forceHighPrecision(apa.getHead())
2763+
or
2764+
exists(Content c2 |
2765+
apa = TConsCons(_, _, c2, _) and
2766+
forceHighPrecision(c2)
2767+
)
2768+
}
2769+
27612770
/**
27622771
* Holds with `unfold = false` if a precise head-tail representation of `apa` is
27632772
* expected to be expensive. Holds with `unfold = true` otherwise.
27642773
*/
27652774
private predicate evalUnfold(AccessPathApprox apa, boolean unfold) {
2766-
if forceHighPrecision(apa.getHead())
2775+
if forceUnfold(apa)
27672776
then unfold = true
27682777
else
27692778
exists(int aps, int nodes, int apLimit, int tupleLimit |
@@ -3092,6 +3101,12 @@ module Impl<FullStateConfigSig Config> {
30923101
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
30933102
}
30943103

3104+
private string ppSummaryCtx() {
3105+
this instanceof PathNodeSink and result = ""
3106+
or
3107+
result = " <" + this.(PathNodeMid).getSummaryCtx().toString() + ">"
3108+
}
3109+
30953110
/** Gets a textual representation of this element. */
30963111
string toString() { result = this.getNodeEx().toString() + this.ppType() + this.ppAp() }
30973112

@@ -3100,7 +3115,9 @@ module Impl<FullStateConfigSig Config> {
31003115
* representation of the call context.
31013116
*/
31023117
string toStringWithContext() {
3103-
result = this.getNodeEx().toString() + this.ppType() + this.ppAp() + this.ppCtx()
3118+
result =
3119+
this.getNodeEx().toString() + this.ppType() + this.ppAp() + this.ppCtx() +
3120+
this.ppSummaryCtx()
31043121
}
31053122

31063123
/**

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,7 +2706,7 @@ module Impl<FullStateConfigSig Config> {
27062706

27072707
ParamNodeEx getParamNode() { result = p }
27082708

2709-
override string toString() { result = p + ": " + ap }
2709+
override string toString() { result = p + concat(" : " + ppReprType(t)) + " " + ap }
27102710

27112711
predicate hasLocationInfo(
27122712
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -2758,12 +2758,21 @@ module Impl<FullStateConfigSig Config> {
27582758
)
27592759
}
27602760

2761+
private predicate forceUnfold(AccessPathApprox apa) {
2762+
forceHighPrecision(apa.getHead())
2763+
or
2764+
exists(Content c2 |
2765+
apa = TConsCons(_, _, c2, _) and
2766+
forceHighPrecision(c2)
2767+
)
2768+
}
2769+
27612770
/**
27622771
* Holds with `unfold = false` if a precise head-tail representation of `apa` is
27632772
* expected to be expensive. Holds with `unfold = true` otherwise.
27642773
*/
27652774
private predicate evalUnfold(AccessPathApprox apa, boolean unfold) {
2766-
if forceHighPrecision(apa.getHead())
2775+
if forceUnfold(apa)
27672776
then unfold = true
27682777
else
27692778
exists(int aps, int nodes, int apLimit, int tupleLimit |
@@ -3092,6 +3101,12 @@ module Impl<FullStateConfigSig Config> {
30923101
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
30933102
}
30943103

3104+
private string ppSummaryCtx() {
3105+
this instanceof PathNodeSink and result = ""
3106+
or
3107+
result = " <" + this.(PathNodeMid).getSummaryCtx().toString() + ">"
3108+
}
3109+
30953110
/** Gets a textual representation of this element. */
30963111
string toString() { result = this.getNodeEx().toString() + this.ppType() + this.ppAp() }
30973112

@@ -3100,7 +3115,9 @@ module Impl<FullStateConfigSig Config> {
31003115
* representation of the call context.
31013116
*/
31023117
string toStringWithContext() {
3103-
result = this.getNodeEx().toString() + this.ppType() + this.ppAp() + this.ppCtx()
3118+
result =
3119+
this.getNodeEx().toString() + this.ppType() + this.ppAp() + this.ppCtx() +
3120+
this.ppSummaryCtx()
31043121
}
31053122

31063123
/**

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,7 +2706,7 @@ module Impl<FullStateConfigSig Config> {
27062706

27072707
ParamNodeEx getParamNode() { result = p }
27082708

2709-
override string toString() { result = p + ": " + ap }
2709+
override string toString() { result = p + concat(" : " + ppReprType(t)) + " " + ap }
27102710

27112711
predicate hasLocationInfo(
27122712
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -2758,12 +2758,21 @@ module Impl<FullStateConfigSig Config> {
27582758
)
27592759
}
27602760

2761+
private predicate forceUnfold(AccessPathApprox apa) {
2762+
forceHighPrecision(apa.getHead())
2763+
or
2764+
exists(Content c2 |
2765+
apa = TConsCons(_, _, c2, _) and
2766+
forceHighPrecision(c2)
2767+
)
2768+
}
2769+
27612770
/**
27622771
* Holds with `unfold = false` if a precise head-tail representation of `apa` is
27632772
* expected to be expensive. Holds with `unfold = true` otherwise.
27642773
*/
27652774
private predicate evalUnfold(AccessPathApprox apa, boolean unfold) {
2766-
if forceHighPrecision(apa.getHead())
2775+
if forceUnfold(apa)
27672776
then unfold = true
27682777
else
27692778
exists(int aps, int nodes, int apLimit, int tupleLimit |
@@ -3092,6 +3101,12 @@ module Impl<FullStateConfigSig Config> {
30923101
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
30933102
}
30943103

3104+
private string ppSummaryCtx() {
3105+
this instanceof PathNodeSink and result = ""
3106+
or
3107+
result = " <" + this.(PathNodeMid).getSummaryCtx().toString() + ">"
3108+
}
3109+
30953110
/** Gets a textual representation of this element. */
30963111
string toString() { result = this.getNodeEx().toString() + this.ppType() + this.ppAp() }
30973112

@@ -3100,7 +3115,9 @@ module Impl<FullStateConfigSig Config> {
31003115
* representation of the call context.
31013116
*/
31023117
string toStringWithContext() {
3103-
result = this.getNodeEx().toString() + this.ppType() + this.ppAp() + this.ppCtx()
3118+
result =
3119+
this.getNodeEx().toString() + this.ppType() + this.ppAp() + this.ppCtx() +
3120+
this.ppSummaryCtx()
31043121
}
31053122

31063123
/**
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* Support for [gqlgen](https://github.com/99designs/gqlgen) has been added.

go/ql/lib/go.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import semmle.go.frameworks.Gin
4242
import semmle.go.frameworks.Glog
4343
import semmle.go.frameworks.GoMicro
4444
import semmle.go.frameworks.GoRestfulHttp
45+
import semmle.go.frameworks.Gqlgen
4546
import semmle.go.frameworks.K8sIoApimachineryPkgRuntime
4647
import semmle.go.frameworks.K8sIoApiCoreV1
4748
import semmle.go.frameworks.K8sIoClientGo

go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,7 +2706,7 @@ module Impl<FullStateConfigSig Config> {
27062706

27072707
ParamNodeEx getParamNode() { result = p }
27082708

2709-
override string toString() { result = p + ": " + ap }
2709+
override string toString() { result = p + concat(" : " + ppReprType(t)) + " " + ap }
27102710

27112711
predicate hasLocationInfo(
27122712
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -2758,12 +2758,21 @@ module Impl<FullStateConfigSig Config> {
27582758
)
27592759
}
27602760

2761+
private predicate forceUnfold(AccessPathApprox apa) {
2762+
forceHighPrecision(apa.getHead())
2763+
or
2764+
exists(Content c2 |
2765+
apa = TConsCons(_, _, c2, _) and
2766+
forceHighPrecision(c2)
2767+
)
2768+
}
2769+
27612770
/**
27622771
* Holds with `unfold = false` if a precise head-tail representation of `apa` is
27632772
* expected to be expensive. Holds with `unfold = true` otherwise.
27642773
*/
27652774
private predicate evalUnfold(AccessPathApprox apa, boolean unfold) {
2766-
if forceHighPrecision(apa.getHead())
2775+
if forceUnfold(apa)
27672776
then unfold = true
27682777
else
27692778
exists(int aps, int nodes, int apLimit, int tupleLimit |
@@ -3092,6 +3101,12 @@ module Impl<FullStateConfigSig Config> {
30923101
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
30933102
}
30943103

3104+
private string ppSummaryCtx() {
3105+
this instanceof PathNodeSink and result = ""
3106+
or
3107+
result = " <" + this.(PathNodeMid).getSummaryCtx().toString() + ">"
3108+
}
3109+
30953110
/** Gets a textual representation of this element. */
30963111
string toString() { result = this.getNodeEx().toString() + this.ppType() + this.ppAp() }
30973112

@@ -3100,7 +3115,9 @@ module Impl<FullStateConfigSig Config> {
31003115
* representation of the call context.
31013116
*/
31023117
string toStringWithContext() {
3103-
result = this.getNodeEx().toString() + this.ppType() + this.ppAp() + this.ppCtx()
3118+
result =
3119+
this.getNodeEx().toString() + this.ppType() + this.ppAp() + this.ppCtx() +
3120+
this.ppSummaryCtx()
31043121
}
31053122

31063123
/**
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/** Provides models of commonly used functions and types in the gqlgen packages. */
2+
3+
import go
4+
5+
/** Provides models of commonly used functions and types in the gqlgen packages. */
6+
module Gqlgen {
7+
/** An autogenerated file containing gqlgen code. */
8+
private class GqlgenGeneratedFile extends File {
9+
GqlgenGeneratedFile() {
10+
exists(DataFlow::CallNode call |
11+
call.getReceiver().getType().hasQualifiedName("github.com/99designs/gqlgen/graphql", _) and
12+
call.getFile() = this
13+
)
14+
}
15+
}
16+
17+
/** A resolver interface. */
18+
private class ResolverInterface extends Type {
19+
ResolverInterface() {
20+
this.getQualifiedName().matches("%Resolver") and
21+
this.getEntity().getDeclaration().getFile() instanceof GqlgenGeneratedFile
22+
}
23+
}
24+
25+
/** A resolver implementation. */
26+
private class ResolverInterfaceMethod extends Method {
27+
ResolverInterfaceMethod() { this.getReceiver().getType() instanceof ResolverInterface }
28+
}
29+
30+
/** A resolver method which is exposed as a Graphql endpoint */
31+
private class ResolverImplementationMethod extends Method {
32+
ResolverImplementationMethod() { this.implements(any(ResolverInterfaceMethod r)) }
33+
34+
Parameter getAnUntrustedParameter() {
35+
result.getFunction() = this.getFuncDecl() and
36+
not result.getType().hasQualifiedName("context", "Context") and
37+
result.getIndex() > 0
38+
}
39+
}
40+
41+
/** A parameter of a resolver method which receives untrusted input. */
42+
class ResolverParameter extends UntrustedFlowSource::Range instanceof DataFlow::ParameterNode {
43+
ResolverParameter() {
44+
this.asParameter() = any(ResolverImplementationMethod h).getAnUntrustedParameter()
45+
}
46+
}
47+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module pwntester/gqlgen-todos
2+
3+
go 1.19
4+
5+
require (
6+
github.com/99designs/gqlgen v0.17.3
7+
github.com/vektah/gqlparser/v2 v2.5.4
8+
)
9+
10+
require (
11+
github.com/agnivade/levenshtein v1.1.1 // indirect
12+
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
13+
github.com/gorilla/websocket v1.5.0 // indirect
14+
github.com/hashicorp/golang-lru v0.5.0 // indirect
15+
github.com/kr/text v0.2.0 // indirect
16+
github.com/matryer/moq v0.2.3 // indirect
17+
github.com/mitchellh/mapstructure v1.5.0 // indirect
18+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
19+
github.com/russross/blackfriday/v2 v2.1.0 // indirect
20+
github.com/stretchr/testify v1.6.0 // indirect
21+
github.com/urfave/cli/v2 v2.25.5 // indirect
22+
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
23+
golang.org/x/mod v0.6.0-dev // indirect
24+
golang.org/x/sys v0.8.0 // indirect
25+
golang.org/x/tools v0.1.9 // indirect
26+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
27+
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
28+
gopkg.in/yaml.v2 v2.4.0 // indirect
29+
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
failures
2+
testFailures
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import go
2+
import TestUtilities.InlineExpectationsTest
3+
4+
module ResolveParameterTest implements TestSig {
5+
string getARelevantTag() { result = "resolverParameter" }
6+
7+
predicate hasActualResult(Location location, string element, string tag, string value) {
8+
tag = "resolverParameter" and
9+
exists(Gqlgen::ResolverParameter p |
10+
element = p.toString() and
11+
value = "\"" + p.toString() + "\"" and
12+
p.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
13+
location.getStartColumn(), location.getEndLine(), location.getEndColumn())
14+
)
15+
}
16+
}
17+
18+
import MakeTest<ResolveParameterTest>

0 commit comments

Comments
 (0)