Skip to content

Commit 0b8353e

Browse files
authored
Merge pull request github#13602 from pwntester/ruby/add_gqlgen_support
Go: Add support for the gqlgen library
2 parents bdf1aa0 + 0ea0d54 commit 0b8353e

File tree

13 files changed

+297
-0
lines changed

13 files changed

+297
-0
lines changed
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
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>

go/ql/test/library-tests/semmle/go/frameworks/gqlgen/graph/generated.go

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/ql/test/library-tests/semmle/go/frameworks/gqlgen/graph/model/models_gen.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package graph
2+
3+
// This file will not be regenerated automatically.
4+
//
5+
// It serves as dependency injection for your app, add any dependencies you require here.
6+
7+
type Resolver struct{}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# GraphQL schema example
2+
#
3+
# https://gqlgen.com/getting-started/
4+
5+
type Todo {
6+
id: ID!
7+
text: String!
8+
done: Boolean!
9+
user: User!
10+
}
11+
12+
type User {
13+
id: ID!
14+
name: String!
15+
}
16+
17+
type Query {
18+
todos: [Todo!]!
19+
}
20+
21+
input NewTodo {
22+
text: String!
23+
userId: String!
24+
}
25+
26+
type Mutation {
27+
createTodo(input: NewTodo!): Todo!
28+
}

0 commit comments

Comments
 (0)