Skip to content

Commit 391e9f7

Browse files
authored
Merge pull request #20000 from owen-mc/go/request-forgery
Go: Add `Head` and `Client.Head` from `net/http` as request forgery sinks
2 parents 03e8865 + a5333ae commit 391e9f7

File tree

7 files changed

+111
-81
lines changed

7 files changed

+111
-81
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added models for the `Head` function and the `Client.Head` method, from the `net/http` package, to the `Http::ClientRequest` class. This means that they will be recognized as sinks for the query `go/request-forgery` and the experimental query `go/ssrf`.

go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,11 @@ module NetHttp {
179179
private class RequestCall extends Http::ClientRequest::Range, DataFlow::CallNode {
180180
RequestCall() {
181181
exists(string functionName |
182-
(
183-
this.getTarget().hasQualifiedName("net/http", functionName)
184-
or
185-
this.getTarget().(Method).hasQualifiedName("net/http", "Client", functionName)
186-
) and
187-
(functionName = "Get" or functionName = "Post" or functionName = "PostForm")
182+
this.getTarget().hasQualifiedName("net/http", functionName)
183+
or
184+
this.getTarget().(Method).hasQualifiedName("net/http", "Client", functionName)
185+
|
186+
functionName = ["Get", "Head", "Post", "PostForm"]
188187
)
189188
}
190189

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,61 @@
11
#select
22
| RequestForgery.go:11:15:11:66 | call to Get | RequestForgery.go:8:12:8:34 | call to FormValue | RequestForgery.go:11:24:11:65 | ...+... | The $@ of this request depends on a $@. | RequestForgery.go:11:24:11:65 | ...+... | URL | RequestForgery.go:8:12:8:34 | call to FormValue | user-provided value |
33
| tst.go:14:2:14:18 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:14:11:14:17 | tainted | The $@ of this request depends on a $@. | tst.go:14:11:14:17 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
4+
| tst.go:16:2:16:19 | call to Head | tst.go:10:13:10:35 | call to FormValue | tst.go:16:12:16:18 | tainted | The $@ of this request depends on a $@. | tst.go:16:12:16:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
45
| tst.go:18:2:18:38 | call to Post | tst.go:10:13:10:35 | call to FormValue | tst.go:18:12:18:18 | tainted | The $@ of this request depends on a $@. | tst.go:18:12:18:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
5-
| tst.go:22:2:22:14 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:21:34:21:40 | tainted | The $@ of this request depends on a $@. | tst.go:21:34:21:40 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
6-
| tst.go:25:2:25:14 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:24:66:24:72 | tainted | The $@ of this request depends on a $@. | tst.go:24:66:24:72 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
7-
| tst.go:27:2:27:30 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:27:11:27:29 | ...+... | The $@ of this request depends on a $@. | tst.go:27:11:27:29 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
8-
| tst.go:29:2:29:41 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:29:11:29:40 | ...+... | The $@ of this request depends on a $@. | tst.go:29:11:29:40 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
9-
| tst.go:37:2:37:21 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:37:11:37:20 | call to String | The $@ of this request depends on a $@. | tst.go:37:11:37:20 | call to String | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
6+
| tst.go:20:2:20:28 | call to PostForm | tst.go:10:13:10:35 | call to FormValue | tst.go:20:16:20:22 | tainted | The $@ of this request depends on a $@. | tst.go:20:16:20:22 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
7+
| tst.go:24:2:24:15 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:23:35:23:41 | tainted | The $@ of this request depends on a $@. | tst.go:23:35:23:41 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
8+
| tst.go:27:2:27:15 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:26:68:26:74 | tainted | The $@ of this request depends on a $@. | tst.go:26:68:26:74 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
9+
| tst.go:29:2:29:20 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:29:13:29:19 | tainted | The $@ of this request depends on a $@. | tst.go:29:13:29:19 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
10+
| tst.go:30:2:30:21 | call to Head | tst.go:10:13:10:35 | call to FormValue | tst.go:30:14:30:20 | tainted | The $@ of this request depends on a $@. | tst.go:30:14:30:20 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
11+
| tst.go:31:2:31:40 | call to Post | tst.go:10:13:10:35 | call to FormValue | tst.go:31:14:31:20 | tainted | The $@ of this request depends on a $@. | tst.go:31:14:31:20 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
12+
| tst.go:32:2:32:30 | call to PostForm | tst.go:10:13:10:35 | call to FormValue | tst.go:32:18:32:24 | tainted | The $@ of this request depends on a $@. | tst.go:32:18:32:24 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
13+
| tst.go:34:2:34:30 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:34:11:34:29 | ...+... | The $@ of this request depends on a $@. | tst.go:34:11:34:29 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
14+
| tst.go:36:2:36:41 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:36:11:36:40 | ...+... | The $@ of this request depends on a $@. | tst.go:36:11:36:40 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
15+
| tst.go:44:2:44:21 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:44:11:44:20 | call to String | The $@ of this request depends on a $@. | tst.go:44:11:44:20 | call to String | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
1016
| websocket.go:65:12:65:53 | call to Dial | websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:65:27:65:40 | untrustedInput | WebSocket URL | websocket.go:60:21:60:31 | call to Referer | user-provided value |
1117
| websocket.go:79:13:79:40 | call to DialConfig | websocket.go:74:21:74:31 | call to Referer | websocket.go:78:36:78:49 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:78:36:78:49 | untrustedInput | WebSocket URL | websocket.go:74:21:74:31 | call to Referer | user-provided value |
1218
| websocket.go:91:3:91:50 | call to Dial | websocket.go:88:21:88:31 | call to Referer | websocket.go:91:31:91:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:91:31:91:44 | untrustedInput | WebSocket URL | websocket.go:88:21:88:31 | call to Referer | user-provided value |
1319
| websocket.go:110:3:110:39 | call to Dial | websocket.go:107:21:107:31 | call to Referer | websocket.go:110:15:110:28 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:110:15:110:28 | untrustedInput | WebSocket URL | websocket.go:107:21:107:31 | call to Referer | user-provided value |
1420
| websocket.go:129:3:129:62 | call to DialContext | websocket.go:126:21:126:31 | call to Referer | websocket.go:129:38:129:51 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:129:38:129:51 | untrustedInput | WebSocket URL | websocket.go:126:21:126:31 | call to Referer | user-provided value |
1521
| websocket.go:155:3:155:45 | call to Dial | websocket.go:154:21:154:31 | call to Referer | websocket.go:155:31:155:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:155:31:155:44 | untrustedInput | WebSocket URL | websocket.go:154:21:154:31 | call to Referer | user-provided value |
1622
| websocket.go:162:3:162:45 | call to Dial | websocket.go:160:21:160:31 | call to Referer | websocket.go:162:31:162:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:162:31:162:44 | untrustedInput | WebSocket URL | websocket.go:160:21:160:31 | call to Referer | user-provided value |
17-
| websocket.go:197:3:197:32 | call to BuildProxy | websocket.go:195:21:195:31 | call to Referer | websocket.go:197:18:197:31 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:197:18:197:31 | untrustedInput | WebSocket URL | websocket.go:195:21:195:31 | call to Referer | user-provided value |
18-
| websocket.go:204:3:204:25 | call to New | websocket.go:202:21:202:31 | call to Referer | websocket.go:204:11:204:24 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:204:11:204:24 | untrustedInput | WebSocket URL | websocket.go:202:21:202:31 | call to Referer | user-provided value |
23+
| websocket.go:197:7:197:36 | call to BuildProxy | websocket.go:195:21:195:31 | call to Referer | websocket.go:197:22:197:35 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:197:22:197:35 | untrustedInput | WebSocket URL | websocket.go:195:21:195:31 | call to Referer | user-provided value |
24+
| websocket.go:204:7:204:29 | call to New | websocket.go:202:21:202:31 | call to Referer | websocket.go:204:15:204:28 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:204:15:204:28 | untrustedInput | WebSocket URL | websocket.go:202:21:202:31 | call to Referer | user-provided value |
1925
edges
2026
| RequestForgery.go:8:12:8:34 | call to FormValue | RequestForgery.go:11:24:11:65 | ...+... | provenance | Src:MaD:1 |
2127
| tst.go:10:13:10:35 | call to FormValue | tst.go:14:11:14:17 | tainted | provenance | Src:MaD:1 |
28+
| tst.go:10:13:10:35 | call to FormValue | tst.go:16:12:16:18 | tainted | provenance | Src:MaD:1 |
2229
| tst.go:10:13:10:35 | call to FormValue | tst.go:18:12:18:18 | tainted | provenance | Src:MaD:1 |
23-
| tst.go:10:13:10:35 | call to FormValue | tst.go:21:34:21:40 | tainted | provenance | Src:MaD:1 |
24-
| tst.go:10:13:10:35 | call to FormValue | tst.go:24:66:24:72 | tainted | provenance | Src:MaD:1 |
25-
| tst.go:10:13:10:35 | call to FormValue | tst.go:27:11:27:29 | ...+... | provenance | Src:MaD:1 |
26-
| tst.go:10:13:10:35 | call to FormValue | tst.go:29:11:29:40 | ...+... | provenance | Src:MaD:1 |
27-
| tst.go:10:13:10:35 | call to FormValue | tst.go:36:11:36:17 | tainted | provenance | Src:MaD:1 |
28-
| tst.go:35:2:35:2 | definition of u [pointer] | tst.go:36:2:36:2 | u [pointer] | provenance | |
29-
| tst.go:36:2:36:2 | implicit dereference | tst.go:35:2:35:2 | definition of u [pointer] | provenance | |
30-
| tst.go:36:2:36:2 | implicit dereference | tst.go:36:2:36:2 | u | provenance | |
31-
| tst.go:36:2:36:2 | implicit dereference | tst.go:37:11:37:11 | u | provenance | |
32-
| tst.go:36:2:36:2 | u | tst.go:36:2:36:2 | implicit dereference | provenance | |
33-
| tst.go:36:2:36:2 | u | tst.go:37:11:37:11 | u | provenance | |
34-
| tst.go:36:2:36:2 | u [pointer] | tst.go:36:2:36:2 | implicit dereference | provenance | |
35-
| tst.go:36:11:36:17 | tainted | tst.go:36:2:36:2 | u | provenance | Config |
36-
| tst.go:36:11:36:17 | tainted | tst.go:37:11:37:11 | u | provenance | Config |
37-
| tst.go:37:11:37:11 | u | tst.go:37:11:37:20 | call to String | provenance | MaD:3 |
30+
| tst.go:10:13:10:35 | call to FormValue | tst.go:20:16:20:22 | tainted | provenance | Src:MaD:1 |
31+
| tst.go:10:13:10:35 | call to FormValue | tst.go:23:35:23:41 | tainted | provenance | Src:MaD:1 |
32+
| tst.go:10:13:10:35 | call to FormValue | tst.go:26:68:26:74 | tainted | provenance | Src:MaD:1 |
33+
| tst.go:10:13:10:35 | call to FormValue | tst.go:29:13:29:19 | tainted | provenance | Src:MaD:1 |
34+
| tst.go:10:13:10:35 | call to FormValue | tst.go:30:14:30:20 | tainted | provenance | Src:MaD:1 |
35+
| tst.go:10:13:10:35 | call to FormValue | tst.go:31:14:31:20 | tainted | provenance | Src:MaD:1 |
36+
| tst.go:10:13:10:35 | call to FormValue | tst.go:32:18:32:24 | tainted | provenance | Src:MaD:1 |
37+
| tst.go:10:13:10:35 | call to FormValue | tst.go:34:11:34:29 | ...+... | provenance | Src:MaD:1 |
38+
| tst.go:10:13:10:35 | call to FormValue | tst.go:36:11:36:40 | ...+... | provenance | Src:MaD:1 |
39+
| tst.go:10:13:10:35 | call to FormValue | tst.go:43:11:43:17 | tainted | provenance | Src:MaD:1 |
40+
| tst.go:42:2:42:2 | definition of u [pointer] | tst.go:43:2:43:2 | u [pointer] | provenance | |
41+
| tst.go:43:2:43:2 | implicit dereference | tst.go:42:2:42:2 | definition of u [pointer] | provenance | |
42+
| tst.go:43:2:43:2 | implicit dereference | tst.go:43:2:43:2 | u | provenance | |
43+
| tst.go:43:2:43:2 | implicit dereference | tst.go:44:11:44:11 | u | provenance | |
44+
| tst.go:43:2:43:2 | u | tst.go:43:2:43:2 | implicit dereference | provenance | |
45+
| tst.go:43:2:43:2 | u | tst.go:44:11:44:11 | u | provenance | |
46+
| tst.go:43:2:43:2 | u [pointer] | tst.go:43:2:43:2 | implicit dereference | provenance | |
47+
| tst.go:43:11:43:17 | tainted | tst.go:43:2:43:2 | u | provenance | Config |
48+
| tst.go:43:11:43:17 | tainted | tst.go:44:11:44:11 | u | provenance | Config |
49+
| tst.go:44:11:44:11 | u | tst.go:44:11:44:20 | call to String | provenance | MaD:3 |
3850
| websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | provenance | Src:MaD:2 |
3951
| websocket.go:74:21:74:31 | call to Referer | websocket.go:78:36:78:49 | untrustedInput | provenance | Src:MaD:2 |
4052
| websocket.go:88:21:88:31 | call to Referer | websocket.go:91:31:91:44 | untrustedInput | provenance | Src:MaD:2 |
4153
| websocket.go:107:21:107:31 | call to Referer | websocket.go:110:15:110:28 | untrustedInput | provenance | Src:MaD:2 |
4254
| websocket.go:126:21:126:31 | call to Referer | websocket.go:129:38:129:51 | untrustedInput | provenance | Src:MaD:2 |
4355
| websocket.go:154:21:154:31 | call to Referer | websocket.go:155:31:155:44 | untrustedInput | provenance | Src:MaD:2 |
4456
| websocket.go:160:21:160:31 | call to Referer | websocket.go:162:31:162:44 | untrustedInput | provenance | Src:MaD:2 |
45-
| websocket.go:195:21:195:31 | call to Referer | websocket.go:197:18:197:31 | untrustedInput | provenance | Src:MaD:2 |
46-
| websocket.go:202:21:202:31 | call to Referer | websocket.go:204:11:204:24 | untrustedInput | provenance | Src:MaD:2 |
57+
| websocket.go:195:21:195:31 | call to Referer | websocket.go:197:22:197:35 | untrustedInput | provenance | Src:MaD:2 |
58+
| websocket.go:202:21:202:31 | call to Referer | websocket.go:204:15:204:28 | untrustedInput | provenance | Src:MaD:2 |
4759
models
4860
| 1 | Source: net/http; Request; true; FormValue; ; ; ReturnValue; remote; manual |
4961
| 2 | Source: net/http; Request; true; Referer; ; ; ReturnValue; remote; manual |
@@ -53,18 +65,24 @@ nodes
5365
| RequestForgery.go:11:24:11:65 | ...+... | semmle.label | ...+... |
5466
| tst.go:10:13:10:35 | call to FormValue | semmle.label | call to FormValue |
5567
| tst.go:14:11:14:17 | tainted | semmle.label | tainted |
68+
| tst.go:16:12:16:18 | tainted | semmle.label | tainted |
5669
| tst.go:18:12:18:18 | tainted | semmle.label | tainted |
57-
| tst.go:21:34:21:40 | tainted | semmle.label | tainted |
58-
| tst.go:24:66:24:72 | tainted | semmle.label | tainted |
59-
| tst.go:27:11:27:29 | ...+... | semmle.label | ...+... |
60-
| tst.go:29:11:29:40 | ...+... | semmle.label | ...+... |
61-
| tst.go:35:2:35:2 | definition of u [pointer] | semmle.label | definition of u [pointer] |
62-
| tst.go:36:2:36:2 | implicit dereference | semmle.label | implicit dereference |
63-
| tst.go:36:2:36:2 | u | semmle.label | u |
64-
| tst.go:36:2:36:2 | u [pointer] | semmle.label | u [pointer] |
65-
| tst.go:36:11:36:17 | tainted | semmle.label | tainted |
66-
| tst.go:37:11:37:11 | u | semmle.label | u |
67-
| tst.go:37:11:37:20 | call to String | semmle.label | call to String |
70+
| tst.go:20:16:20:22 | tainted | semmle.label | tainted |
71+
| tst.go:23:35:23:41 | tainted | semmle.label | tainted |
72+
| tst.go:26:68:26:74 | tainted | semmle.label | tainted |
73+
| tst.go:29:13:29:19 | tainted | semmle.label | tainted |
74+
| tst.go:30:14:30:20 | tainted | semmle.label | tainted |
75+
| tst.go:31:14:31:20 | tainted | semmle.label | tainted |
76+
| tst.go:32:18:32:24 | tainted | semmle.label | tainted |
77+
| tst.go:34:11:34:29 | ...+... | semmle.label | ...+... |
78+
| tst.go:36:11:36:40 | ...+... | semmle.label | ...+... |
79+
| tst.go:42:2:42:2 | definition of u [pointer] | semmle.label | definition of u [pointer] |
80+
| tst.go:43:2:43:2 | implicit dereference | semmle.label | implicit dereference |
81+
| tst.go:43:2:43:2 | u | semmle.label | u |
82+
| tst.go:43:2:43:2 | u [pointer] | semmle.label | u [pointer] |
83+
| tst.go:43:11:43:17 | tainted | semmle.label | tainted |
84+
| tst.go:44:11:44:11 | u | semmle.label | u |
85+
| tst.go:44:11:44:20 | call to String | semmle.label | call to String |
6886
| websocket.go:60:21:60:31 | call to Referer | semmle.label | call to Referer |
6987
| websocket.go:65:27:65:40 | untrustedInput | semmle.label | untrustedInput |
7088
| websocket.go:74:21:74:31 | call to Referer | semmle.label | call to Referer |
@@ -80,7 +98,7 @@ nodes
8098
| websocket.go:160:21:160:31 | call to Referer | semmle.label | call to Referer |
8199
| websocket.go:162:31:162:44 | untrustedInput | semmle.label | untrustedInput |
82100
| websocket.go:195:21:195:31 | call to Referer | semmle.label | call to Referer |
83-
| websocket.go:197:18:197:31 | untrustedInput | semmle.label | untrustedInput |
101+
| websocket.go:197:22:197:35 | untrustedInput | semmle.label | untrustedInput |
84102
| websocket.go:202:21:202:31 | call to Referer | semmle.label | call to Referer |
85-
| websocket.go:204:11:204:24 | untrustedInput | semmle.label | untrustedInput |
103+
| websocket.go:204:15:204:28 | untrustedInput | semmle.label | untrustedInput |
86104
subpaths

go/ql/test/query-tests/Security/CWE-918/RequestForgery.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import (
55
)
66

77
func handler(w http.ResponseWriter, req *http.Request) {
8-
target := req.FormValue("target")
8+
target := req.FormValue("target") // $ Source
99

1010
// BAD: `target` is controlled by the attacker
11-
resp, err := http.Get("https://" + target + ".example.com/data/")
11+
resp, err := http.Get("https://" + target + ".example.com/data/") // $ Alert
1212
if err != nil {
1313
// error handling
1414
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
query: Security/CWE-918/RequestForgery.ql
2-
postprocess: utils/test/PrettyPrintModels.ql
2+
postprocess:
3+
- utils/test/PrettyPrintModels.ql
4+
- utils/test/InlineExpectationsTestQuery.ql

go/ql/test/query-tests/Security/CWE-918/tst.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,41 @@ import (
77
)
88

99
func handler2(w http.ResponseWriter, req *http.Request) {
10-
tainted := req.FormValue("target")
10+
tainted := req.FormValue("target") // $ Source
1111

1212
http.Get("example.com") // OK
1313

14-
http.Get(tainted) // Not OK
14+
http.Get(tainted) // $ Alert
1515

16-
http.Head(tainted) // OK
16+
http.Head(tainted) // $ Alert
1717

18-
http.Post(tainted, "text/basic", nil) // Not OK
18+
http.Post(tainted, "text/basic", nil) // $ Alert
19+
20+
http.PostForm(tainted, nil) // $ Alert
1921

2022
client := &http.Client{}
21-
rq, _ := http.NewRequest("GET", tainted, nil)
22-
client.Do(rq) // Not OK
23+
rq1, _ := http.NewRequest("GET", tainted, nil) // $ Sink
24+
client.Do(rq1) // $ Alert
25+
26+
rq2, _ := http.NewRequestWithContext(context.Background(), "GET", tainted, nil) // $ Sink
27+
client.Do(rq2) // $ Alert
2328

24-
rq, _ = http.NewRequestWithContext(context.Background(), "GET", tainted, nil)
25-
client.Do(rq) // Not OK
29+
client.Get(tainted) // $ Alert
30+
client.Head(tainted) // $ Alert
31+
client.Post(tainted, "text/basic", nil) // $ Alert
32+
client.PostForm(tainted, nil) // $ Alert
2633

27-
http.Get("http://" + tainted) // Not OK
34+
http.Get("http://" + tainted) // $ Alert
2835

29-
http.Get("http://example.com" + tainted) // Not OK
36+
http.Get("http://example.com" + tainted) // $ Alert
3037

3138
http.Get("http://example.com/" + tainted) // OK
3239

3340
http.Get("http://example.com/?" + tainted) // OK
3441

3542
u, _ := url.Parse("http://example.com/relative-path")
3643
u.Host = tainted
37-
http.Get(u.String()) // Not OK
44+
http.Get(u.String()) // $ Alert
3845
}
3946

4047
func main() {

0 commit comments

Comments
 (0)