Skip to content

Commit 25c60c4

Browse files
committed
v1
1 parent 7723dbc commit 25c60c4

File tree

5 files changed

+459
-0
lines changed

5 files changed

+459
-0
lines changed

go/ql/lib/go.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,4 @@ import semmle.go.frameworks.XPath
6464
import semmle.go.frameworks.Yaml
6565
import semmle.go.frameworks.Zap
6666
import semmle.go.security.FlowSources
67+
import semmle.go.security.FileSystemAccess
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
import go
2+
3+
class FastHttpFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
4+
FastHttpFileSystemAccess() {
5+
exists(DataFlow::Method mcn |
6+
(
7+
mcn.hasQualifiedName("github.com/valyala/fasthttp.RequestCtx", ["SendFileBytes", "SendFile"]) or
8+
mcn.hasQualifiedName("github.com/valyala/fasthttp.Response", ["SendFile"])
9+
) and
10+
this = mcn.getACall()
11+
)
12+
or
13+
exists(DataFlow::Function f |
14+
f.hasQualifiedName("github.com/valyala/fasthttp",
15+
[
16+
"ServeFile", "ServeFileUncompressed", "ServeFileBytes", "ServeFileBytesUncompressed",
17+
"SaveMultipartFile"
18+
]) and
19+
this = f.getACall()
20+
)
21+
}
22+
23+
override DataFlow::Node getAPathArgument() {
24+
this.getTarget().getName() =
25+
[
26+
"ServeFile", "ServeFileUncompressed", "ServeFileBytes", "ServeFileBytesUncompressed",
27+
"SaveMultipartFile"
28+
] and
29+
result = this.getArgument(1)
30+
or
31+
this.getTarget().getName() = ["SendFile", "SendFileBytes"] and
32+
result = this.getArgument(0)
33+
}
34+
}
35+
36+
class HttpServeFile extends FileSystemAccess::Range, DataFlow::CallNode {
37+
HttpServeFile() {
38+
exists(DataFlow::Function mcn |
39+
mcn.hasQualifiedName("net/http", "ServeFile") and
40+
this = mcn.getACall()
41+
)
42+
}
43+
44+
override DataFlow::Node getAPathArgument() { result = this.getArgument(2) }
45+
}
46+
47+
class BeegoFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
48+
BeegoFileSystemAccess() {
49+
exists(DataFlow::Method mcn |
50+
(
51+
mcn.hasQualifiedName("github.com/beego/beego/v2/server/web/context.BeegoOutput", "Download") or
52+
mcn.hasQualifiedName("github.com/beego/beego/v2/server/web.Controller",
53+
"SaveToFileWithBuffer")
54+
) and
55+
this = mcn.getACall()
56+
)
57+
}
58+
59+
override DataFlow::Node getAPathArgument() {
60+
this.getTarget()
61+
.hasQualifiedName("github.com/beego/beego/v2/server/web/context.BeegoOutput", "Download") and
62+
result = this.getArgument(0)
63+
or
64+
this.getTarget()
65+
.hasQualifiedName("github.com/beego/beego/v2/server/web.Controller", "SaveToFileWithBuffer") and
66+
result = this.getArgument(1)
67+
}
68+
}
69+
70+
class EchoFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
71+
EchoFileSystemAccess() {
72+
exists(DataFlow::Method mcn |
73+
mcn.hasQualifiedName("github.com/labstack/echo/v4.Context", ["Attachment", "File"]) and
74+
this = mcn.getACall()
75+
)
76+
}
77+
78+
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
79+
}
80+
81+
class GinFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
82+
GinFileSystemAccess() {
83+
exists(DataFlow::Method mcn |
84+
mcn.hasQualifiedName("github.com/gin-gonic/gin.Context",
85+
["File", "FileAttachment", "SaveUploadedFile"]) and
86+
this = mcn.getACall()
87+
)
88+
}
89+
90+
override DataFlow::Node getAPathArgument() {
91+
this.getTarget().getName() = ["File", "FileAttachment"] and result = this.getArgument(0)
92+
or
93+
this.getTarget().getName() = "SaveUploadedFile" and result = this.getArgument(1)
94+
}
95+
}
96+
97+
class IrisFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
98+
IrisFileSystemAccess() {
99+
exists(DataFlow::Method mcn |
100+
mcn.hasQualifiedName("github.com/kataras/iris/v12/context.Context",
101+
["SendFile", "ServeFile", "SendFileWithRate", "ServeFileWithRate", "UploadFormFiles"]) and
102+
this = mcn.getACall()
103+
or
104+
mcn.hasQualifiedName("github.com/kataras/iris/v12/context.Context", "SaveFormFile") and
105+
this = mcn.getACall()
106+
)
107+
}
108+
109+
override DataFlow::Node getAPathArgument() {
110+
this.getTarget().getName() =
111+
["SendFile", "ServeFile", "SendFileWithRate", "ServeFileWithRate", "UploadFormFiles"] and
112+
result = this.getArgument(0)
113+
or
114+
this.getTarget().getName() = "SaveFormFile" and result = this.getArgument(1)
115+
}
116+
}
117+
118+
class FiberSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
119+
FiberSystemAccess() {
120+
exists(DataFlow::Method mcn |
121+
mcn.hasQualifiedName("github.com/gofiber/fiber/v2.Ctx", ["Attachment", "SendFile"]) and
122+
this = mcn.getACall()
123+
or
124+
mcn.hasQualifiedName("github.com/gofiber/fiber/v2.Ctx", "SaveFile") and
125+
this = mcn.getACall()
126+
)
127+
}
128+
129+
override DataFlow::Node getAPathArgument() {
130+
this.getTarget().getName() = ["Attachment", "SendFile"] and result = this.getArgument(0)
131+
or
132+
this.getTarget().getName() = "SaveFile" and result = this.getArgument(1)
133+
}
134+
}
135+
136+
class AferoSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
137+
AferoSystemAccess() {
138+
exists(DataFlow::Function mcn |
139+
mcn.hasQualifiedName("github.com/spf13/afero",
140+
["WriteReader", "SafeWriteReader", "WriteFile", "ReadFile", "ReadDir"]) and
141+
this = mcn.getACall()
142+
or
143+
mcn.hasQualifiedName("github.com/spf13/afero", "Open") and
144+
this = mcn.getACall()
145+
)
146+
or
147+
exists(DataFlow::Function mcn |
148+
mcn.hasQualifiedName("github.com/spf13/afero",
149+
["WriteReader", "SafeWriteReader", "WriteFile", "ReadFile", "ReadDir"]) and
150+
this = mcn.getACall()
151+
or
152+
mcn.hasQualifiedName("github.com/spf13/afero", "Open") and
153+
this = mcn.getACall()
154+
)
155+
or
156+
exists(DataFlow::Method mcn |
157+
mcn.hasQualifiedName("github.com/spf13/afero.Afero",
158+
["ReadFile", "ReadDir", "WriteReader", "WriteFile", "SafeWriteReader"]) and
159+
this = mcn.getACall()
160+
or
161+
mcn.hasQualifiedName("github.com/spf13/afero.HttpFs", ["Open", "OpenFile", "Create"]) and
162+
this = mcn.getACall()
163+
or
164+
mcn.hasQualifiedName("github.com/spf13/afero.RegexpFs",
165+
["Create", "Open", "Remove", "OpenFile"]) and
166+
this = mcn.getACall()
167+
or
168+
mcn.hasQualifiedName("github.com/spf13/afero.ReadOnlyFs",
169+
["Create", "Open", "Remove", "OpenFile", "ReadDir", "ReadlinkIfPossible"]) and
170+
this = mcn.getACall()
171+
or
172+
mcn.hasQualifiedName("github.com/spf13/afero.OsFs",
173+
["Create", "Open", "Remove", "RemoveAll", "OpenFile", "ReadDir", "ReadlinkIfPossible"]) and
174+
this = mcn.getACall()
175+
or
176+
mcn.hasQualifiedName("github.com/spf13/afero.OsFs",
177+
["Create", "Open", "Remove", "RemoveAll", "OpenFile", "ReadDir", "ReadlinkIfPossible"]) and
178+
this = mcn.getACall()
179+
or
180+
mcn.hasQualifiedName("github.com/spf13/afero.MemMapFs",
181+
["Create", "Open", "OpenFile", "Remove", "RemoveAll"]) and
182+
this = mcn.getACall()
183+
or
184+
mcn.hasQualifiedName("github.com/spf13/afero.BasePathFs",
185+
["Create", "Open", "OpenFile", "Remove", "RemoveAll", "ReadlinkIfPossible"]) and
186+
this = mcn.getACall()
187+
)
188+
}
189+
190+
override DataFlow::Node getAPathArgument() {
191+
if
192+
this.getTarget()
193+
.hasQualifiedName("github.com/spf13/afero",
194+
["WriteReader", "SafeWriteReader", "WriteFile", "ReadFile", "ReadDir"]) or
195+
this.getTarget()
196+
.hasQualifiedName("github.com/spf13/afero",
197+
["WriteReader", "SafeWriteReader", "WriteFile", "ReadFile", "ReadDir"])
198+
then result = this.getArgument(1)
199+
else result = this.getArgument(0)
200+
}
201+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import go
2+
import semmle.go.security.FileSystemAccess
3+
4+
from FileSystemAccess f
5+
select f
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
module aferno
2+
3+
go 1.20
4+
5+
require (
6+
github.com/beego/beego/v2 v2.1.1
7+
github.com/gin-gonic/gin v1.9.1
8+
github.com/gofiber/fiber/v2 v2.48.0
9+
github.com/kataras/iris/v12 v12.2.5
10+
github.com/labstack/echo/v4 v4.11.1
11+
github.com/spf13/afero v1.9.5
12+
github.com/valyala/fasthttp v1.48.0
13+
)
14+
15+
require (
16+
github.com/BurntSushi/toml v1.3.2 // indirect
17+
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect
18+
github.com/CloudyKit/jet/v6 v6.2.0 // indirect
19+
github.com/Joker/jade v1.1.3 // indirect
20+
github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect
21+
github.com/andybalholm/brotli v1.0.5 // indirect
22+
github.com/aymerick/douceur v0.2.0 // indirect
23+
github.com/beorn7/perks v1.0.1 // indirect
24+
github.com/bytedance/sonic v1.9.1 // indirect
25+
github.com/cespare/xxhash/v2 v2.2.0 // indirect
26+
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
27+
github.com/fatih/structs v1.1.0 // indirect
28+
github.com/flosch/pongo2/v4 v4.0.2 // indirect
29+
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
30+
github.com/gin-contrib/sse v0.1.0 // indirect
31+
github.com/go-playground/locales v0.14.1 // indirect
32+
github.com/go-playground/universal-translator v0.18.1 // indirect
33+
github.com/go-playground/validator/v10 v10.14.0 // indirect
34+
github.com/goccy/go-json v0.10.2 // indirect
35+
github.com/golang/protobuf v1.5.3 // indirect
36+
github.com/golang/snappy v0.0.4 // indirect
37+
github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 // indirect
38+
github.com/google/uuid v1.3.0 // indirect
39+
github.com/gorilla/css v1.0.0 // indirect
40+
github.com/hashicorp/golang-lru v0.5.4 // indirect
41+
github.com/iris-contrib/schema v0.0.6 // indirect
42+
github.com/josharian/intern v1.0.0 // indirect
43+
github.com/json-iterator/go v1.1.12 // indirect
44+
github.com/kataras/blocks v0.0.7 // indirect
45+
github.com/kataras/golog v0.1.9 // indirect
46+
github.com/kataras/pio v0.0.12 // indirect
47+
github.com/kataras/sitemap v0.0.6 // indirect
48+
github.com/kataras/tunnel v0.0.4 // indirect
49+
github.com/klauspost/compress v1.16.7 // indirect
50+
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
51+
github.com/labstack/gommon v0.4.0 // indirect
52+
github.com/leodido/go-urn v1.2.4 // indirect
53+
github.com/mailgun/raymond/v2 v2.0.48 // indirect
54+
github.com/mailru/easyjson v0.7.7 // indirect
55+
github.com/mattn/go-colorable v0.1.13 // indirect
56+
github.com/mattn/go-isatty v0.0.19 // indirect
57+
github.com/mattn/go-runewidth v0.0.14 // indirect
58+
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
59+
github.com/microcosm-cc/bluemonday v1.0.25 // indirect
60+
github.com/mitchellh/mapstructure v1.5.0 // indirect
61+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
62+
github.com/modern-go/reflect2 v1.0.2 // indirect
63+
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
64+
github.com/pkg/errors v0.9.1 // indirect
65+
github.com/prometheus/client_golang v1.16.0 // indirect
66+
github.com/prometheus/client_model v0.3.0 // indirect
67+
github.com/prometheus/common v0.42.0 // indirect
68+
github.com/prometheus/procfs v0.10.1 // indirect
69+
github.com/rivo/uniseg v0.2.0 // indirect
70+
github.com/russross/blackfriday/v2 v2.1.0 // indirect
71+
github.com/schollz/closestmatch v2.1.0+incompatible // indirect
72+
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
73+
github.com/sirupsen/logrus v1.8.1 // indirect
74+
github.com/tdewolff/minify/v2 v2.12.8 // indirect
75+
github.com/tdewolff/parse/v2 v2.6.7 // indirect
76+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
77+
github.com/ugorji/go/codec v1.2.11 // indirect
78+
github.com/valyala/bytebufferpool v1.0.0 // indirect
79+
github.com/valyala/fasttemplate v1.2.2 // indirect
80+
github.com/valyala/tcplisten v1.0.0 // indirect
81+
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
82+
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
83+
github.com/yosssi/ace v0.0.5 // indirect
84+
golang.org/x/arch v0.3.0 // indirect
85+
golang.org/x/crypto v0.12.0 // indirect
86+
golang.org/x/net v0.14.0 // indirect
87+
golang.org/x/sys v0.11.0 // indirect
88+
golang.org/x/text v0.12.0 // indirect
89+
golang.org/x/time v0.3.0 // indirect
90+
google.golang.org/protobuf v1.31.0 // indirect
91+
gopkg.in/ini.v1 v1.67.0 // indirect
92+
gopkg.in/yaml.v3 v3.0.1 // indirect
93+
)

0 commit comments

Comments
 (0)