Skip to content

Commit c9ce2c8

Browse files
committed
Add test for assignment to Url.Host field
1 parent 8b04d0a commit c9ce2c8

File tree

2 files changed

+57
-28
lines changed

2 files changed

+57
-28
lines changed

go/ql/test/experimental/CWE-918/SSRF.expected

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#select
2-
| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value. |
3-
| builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value. |
4-
| builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value. |
5-
| builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value. |
6-
| builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value. |
2+
| builtin.go:23:12:23:63 | call to Get | builtin.go:20:12:20:34 | call to FormValue | builtin.go:23:21:23:62 | ...+... | The URL of this request depends on a user-provided value. |
3+
| builtin.go:89:12:89:53 | call to Dial | builtin.go:84:21:84:31 | call to Referer | builtin.go:89:27:89:40 | untrustedInput | The URL of this request depends on a user-provided value. |
4+
| builtin.go:103:13:103:40 | call to DialConfig | builtin.go:98:21:98:31 | call to Referer | builtin.go:102:36:102:49 | untrustedInput | The URL of this request depends on a user-provided value. |
5+
| builtin.go:115:3:115:39 | call to Dial | builtin.go:112:21:112:31 | call to Referer | builtin.go:115:15:115:28 | untrustedInput | The URL of this request depends on a user-provided value. |
6+
| builtin.go:133:3:133:62 | call to DialContext | builtin.go:130:21:130:31 | call to Referer | builtin.go:133:38:133:51 | untrustedInput | The URL of this request depends on a user-provided value. |
7+
| builtin.go:156:12:156:33 | call to Get | builtin.go:151:16:151:36 | call to FormValue | builtin.go:156:21:156:32 | call to String | The URL of this request depends on a user-provided value. |
78
| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value. |
89
| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value. |
910
| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value. |
@@ -17,11 +18,18 @@
1718
| new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value. |
1819
| new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value. |
1920
edges
20-
| builtin.go:19:12:19:34 | call to FormValue | builtin.go:22:21:22:62 | ...+... | provenance | Src:MaD:7 |
21-
| builtin.go:83:21:83:31 | call to Referer | builtin.go:88:27:88:40 | untrustedInput | provenance | Src:MaD:8 |
22-
| builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | provenance | Src:MaD:8 |
23-
| builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | provenance | Src:MaD:8 |
24-
| builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | provenance | Src:MaD:8 |
21+
| builtin.go:20:12:20:34 | call to FormValue | builtin.go:23:21:23:62 | ...+... | provenance | Src:MaD:7 |
22+
| builtin.go:84:21:84:31 | call to Referer | builtin.go:89:27:89:40 | untrustedInput | provenance | Src:MaD:8 |
23+
| builtin.go:98:21:98:31 | call to Referer | builtin.go:102:36:102:49 | untrustedInput | provenance | Src:MaD:8 |
24+
| builtin.go:112:21:112:31 | call to Referer | builtin.go:115:15:115:28 | untrustedInput | provenance | Src:MaD:8 |
25+
| builtin.go:130:21:130:31 | call to Referer | builtin.go:133:38:133:51 | untrustedInput | provenance | Src:MaD:8 |
26+
| builtin.go:151:16:151:36 | call to FormValue | builtin.go:154:13:154:22 | unsafehost | provenance | Src:MaD:7 |
27+
| builtin.go:154:2:154:4 | implicit dereference | builtin.go:156:21:156:23 | url | provenance | |
28+
| builtin.go:154:2:154:4 | url | builtin.go:154:2:154:4 | implicit dereference | provenance | |
29+
| builtin.go:154:2:154:4 | url | builtin.go:156:21:156:23 | url | provenance | |
30+
| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | implicit dereference | provenance | Config |
31+
| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | url | provenance | Config |
32+
| builtin.go:156:21:156:23 | url | builtin.go:156:21:156:32 | call to String | provenance | MaD:12 |
2533
| new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:48:31:56 | selection of word | provenance | Src:MaD:3 |
2634
| new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:32:48:32:56 | selection of safe | provenance | Src:MaD:3 |
2735
| new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:35:49:35:57 | selection of word | provenance | Src:MaD:3 |
@@ -37,7 +45,7 @@ edges
3745
| new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | provenance | Src:MaD:1 |
3846
| new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | provenance | Src:MaD:2 |
3947
| new-tests.go:62:2:62:39 | ... := ...[0] | new-tests.go:63:17:63:23 | reqBody | provenance | |
40-
| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | provenance | Src:MaD:6 MaD:12 |
48+
| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | provenance | Src:MaD:6 MaD:13 |
4149
| new-tests.go:63:17:63:23 | reqBody | new-tests.go:63:26:63:30 | &... [postupdate] | provenance | MaD:10 |
4250
| new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:68:48:68:56 | selection of word | provenance | |
4351
| new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:69:48:69:56 | selection of safe | provenance | |
@@ -51,12 +59,12 @@ edges
5159
| new-tests.go:74:12:74:58 | []type{args} [array] | new-tests.go:74:12:74:58 | call to Sprintf | provenance | MaD:11 |
5260
| new-tests.go:74:49:74:57 | selection of word | new-tests.go:74:12:74:58 | []type{args} [array] | provenance | |
5361
| new-tests.go:74:49:74:57 | selection of word | new-tests.go:74:12:74:58 | call to Sprintf | provenance | FunctionModel |
54-
| new-tests.go:78:18:78:24 | selection of URL | new-tests.go:78:18:78:32 | call to Query | provenance | Src:MaD:9 MaD:13 |
55-
| new-tests.go:78:18:78:32 | call to Query | new-tests.go:78:18:78:46 | call to Get | provenance | MaD:14 |
62+
| new-tests.go:78:18:78:24 | selection of URL | new-tests.go:78:18:78:32 | call to Query | provenance | Src:MaD:9 MaD:14 |
63+
| new-tests.go:78:18:78:32 | call to Query | new-tests.go:78:18:78:46 | call to Get | provenance | MaD:15 |
5664
| new-tests.go:78:18:78:46 | call to Get | new-tests.go:79:11:79:46 | ...+... | provenance | |
5765
| new-tests.go:81:18:81:67 | call to TrimPrefix | new-tests.go:82:11:82:46 | ...+... | provenance | |
5866
| new-tests.go:81:37:81:43 | selection of URL | new-tests.go:81:37:81:48 | selection of Path | provenance | Src:MaD:9 |
59-
| new-tests.go:81:37:81:48 | selection of Path | new-tests.go:81:18:81:67 | call to TrimPrefix | provenance | MaD:15 |
67+
| new-tests.go:81:37:81:48 | selection of Path | new-tests.go:81:18:81:67 | call to TrimPrefix | provenance | MaD:16 |
6068
| new-tests.go:86:10:86:20 | call to Vars | new-tests.go:88:11:88:46 | ...+... | provenance | Src:MaD:5 |
6169
| new-tests.go:95:18:95:45 | call to URLParam | new-tests.go:96:11:96:46 | ...+... | provenance | Src:MaD:4 |
6270
models
@@ -71,21 +79,28 @@ models
7179
| 9 | Source: net/http; Request; true; URL; ; ; ; remote; manual |
7280
| 10 | Summary: encoding/json; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual |
7381
| 11 | Summary: fmt; ; false; Sprintf; ; ; Argument[1].ArrayElement; ReturnValue; taint; manual |
74-
| 12 | Summary: io/ioutil; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual |
75-
| 13 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual |
76-
| 14 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual |
77-
| 15 | Summary: strings; ; false; TrimPrefix; ; ; Argument[0]; ReturnValue; taint; manual |
82+
| 12 | Summary: fmt; Stringer; true; String; ; ; Argument[receiver]; ReturnValue; taint; manual |
83+
| 13 | Summary: io/ioutil; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual |
84+
| 14 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual |
85+
| 15 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual |
86+
| 16 | Summary: strings; ; false; TrimPrefix; ; ; Argument[0]; ReturnValue; taint; manual |
7887
nodes
79-
| builtin.go:19:12:19:34 | call to FormValue | semmle.label | call to FormValue |
80-
| builtin.go:22:21:22:62 | ...+... | semmle.label | ...+... |
81-
| builtin.go:83:21:83:31 | call to Referer | semmle.label | call to Referer |
82-
| builtin.go:88:27:88:40 | untrustedInput | semmle.label | untrustedInput |
83-
| builtin.go:97:21:97:31 | call to Referer | semmle.label | call to Referer |
84-
| builtin.go:101:36:101:49 | untrustedInput | semmle.label | untrustedInput |
85-
| builtin.go:111:21:111:31 | call to Referer | semmle.label | call to Referer |
86-
| builtin.go:114:15:114:28 | untrustedInput | semmle.label | untrustedInput |
87-
| builtin.go:129:21:129:31 | call to Referer | semmle.label | call to Referer |
88-
| builtin.go:132:38:132:51 | untrustedInput | semmle.label | untrustedInput |
88+
| builtin.go:20:12:20:34 | call to FormValue | semmle.label | call to FormValue |
89+
| builtin.go:23:21:23:62 | ...+... | semmle.label | ...+... |
90+
| builtin.go:84:21:84:31 | call to Referer | semmle.label | call to Referer |
91+
| builtin.go:89:27:89:40 | untrustedInput | semmle.label | untrustedInput |
92+
| builtin.go:98:21:98:31 | call to Referer | semmle.label | call to Referer |
93+
| builtin.go:102:36:102:49 | untrustedInput | semmle.label | untrustedInput |
94+
| builtin.go:112:21:112:31 | call to Referer | semmle.label | call to Referer |
95+
| builtin.go:115:15:115:28 | untrustedInput | semmle.label | untrustedInput |
96+
| builtin.go:130:21:130:31 | call to Referer | semmle.label | call to Referer |
97+
| builtin.go:133:38:133:51 | untrustedInput | semmle.label | untrustedInput |
98+
| builtin.go:151:16:151:36 | call to FormValue | semmle.label | call to FormValue |
99+
| builtin.go:154:2:154:4 | implicit dereference | semmle.label | implicit dereference |
100+
| builtin.go:154:2:154:4 | url | semmle.label | url |
101+
| builtin.go:154:13:154:22 | unsafehost | semmle.label | unsafehost |
102+
| builtin.go:156:21:156:23 | url | semmle.label | url |
103+
| builtin.go:156:21:156:32 | call to String | semmle.label | call to String |
89104
| new-tests.go:26:26:26:30 | &... [postupdate] | semmle.label | &... [postupdate] |
90105
| new-tests.go:31:11:31:57 | []type{args} [array] | semmle.label | []type{args} [array] |
91106
| new-tests.go:31:11:31:57 | call to Sprintf | semmle.label | call to Sprintf |

go/ql/test/experimental/CWE-918/builtin.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"log"
1010
"net/http"
11+
"net/url"
1112
"regexp"
1213
"strings"
1314

@@ -145,3 +146,16 @@ func test() {
145146
log.Println(http.ListenAndServe(":80", nil))
146147

147148
}
149+
150+
func handler2(w http.ResponseWriter, req *http.Request) {
151+
unsafehost := req.FormValue("host") // $ Source
152+
153+
url, _ := url.Parse("http://example.com/data")
154+
url.Host = unsafehost
155+
// BAD: `target` is controlled by the attacker
156+
_, err := http.Get(url.String()) // $ Alert
157+
if err != nil {
158+
// error handling
159+
}
160+
// process request response
161+
}

0 commit comments

Comments
 (0)