diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index a947101b354..a14339943d5 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -1,9 +1,10 @@ #select -| 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. | -| 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. | -| 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. | -| 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. | -| 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. | +| 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. | +| 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. | +| 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. | +| 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. | +| 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. | +| 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. | | 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. | | 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. | | 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 @@ | 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. | | 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. | edges -| builtin.go:19:12:19:34 | call to FormValue | builtin.go:22:21:22:62 | ...+... | provenance | Src:MaD:7 | -| builtin.go:83:21:83:31 | call to Referer | builtin.go:88:27:88:40 | untrustedInput | provenance | Src:MaD:8 | -| builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | provenance | Src:MaD:8 | -| builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | provenance | Src:MaD:8 | -| builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:20:12:20:34 | call to FormValue | builtin.go:23:21:23:62 | ...+... | provenance | Src:MaD:7 | +| builtin.go:84:21:84:31 | call to Referer | builtin.go:89:27:89:40 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:98:21:98:31 | call to Referer | builtin.go:102:36:102:49 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:112:21:112:31 | call to Referer | builtin.go:115:15:115:28 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:130:21:130:31 | call to Referer | builtin.go:133:38:133:51 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:151:16:151:36 | call to FormValue | builtin.go:154:13:154:22 | unsafehost | provenance | Src:MaD:7 | +| builtin.go:154:2:154:4 | implicit dereference | builtin.go:156:21:156:23 | url | provenance | | +| builtin.go:154:2:154:4 | url | builtin.go:154:2:154:4 | implicit dereference | provenance | | +| builtin.go:154:2:154:4 | url | builtin.go:156:21:156:23 | url | provenance | | +| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | implicit dereference | provenance | Config | +| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | url | provenance | Config | +| builtin.go:156:21:156:23 | url | builtin.go:156:21:156:32 | call to String | provenance | MaD:12 | | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:48:31:56 | selection of word | provenance | Src:MaD:3 | | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:32:48:32:56 | selection of safe | provenance | Src:MaD:3 | | 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 | new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | provenance | Src:MaD:1 | | new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | provenance | Src:MaD:2 | | new-tests.go:62:2:62:39 | ... := ...[0] | new-tests.go:63:17:63:23 | reqBody | provenance | | -| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | provenance | Src:MaD:6 MaD:12 | +| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | provenance | Src:MaD:6 MaD:13 | | new-tests.go:63:17:63:23 | reqBody | new-tests.go:63:26:63:30 | &... [postupdate] | provenance | MaD:10 | | new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:68:48:68:56 | selection of word | provenance | | | new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:69:48:69:56 | selection of safe | provenance | | @@ -51,12 +59,12 @@ edges | new-tests.go:74:12:74:58 | []type{args} [array] | new-tests.go:74:12:74:58 | call to Sprintf | provenance | MaD:11 | | new-tests.go:74:49:74:57 | selection of word | new-tests.go:74:12:74:58 | []type{args} [array] | provenance | | | new-tests.go:74:49:74:57 | selection of word | new-tests.go:74:12:74:58 | call to Sprintf | provenance | FunctionModel | -| 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 | -| new-tests.go:78:18:78:32 | call to Query | new-tests.go:78:18:78:46 | call to Get | provenance | MaD:14 | +| 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 | +| new-tests.go:78:18:78:32 | call to Query | new-tests.go:78:18:78:46 | call to Get | provenance | MaD:15 | | new-tests.go:78:18:78:46 | call to Get | new-tests.go:79:11:79:46 | ...+... | provenance | | | new-tests.go:81:18:81:67 | call to TrimPrefix | new-tests.go:82:11:82:46 | ...+... | provenance | | | new-tests.go:81:37:81:43 | selection of URL | new-tests.go:81:37:81:48 | selection of Path | provenance | Src:MaD:9 | -| new-tests.go:81:37:81:48 | selection of Path | new-tests.go:81:18:81:67 | call to TrimPrefix | provenance | MaD:15 | +| new-tests.go:81:37:81:48 | selection of Path | new-tests.go:81:18:81:67 | call to TrimPrefix | provenance | MaD:16 | | new-tests.go:86:10:86:20 | call to Vars | new-tests.go:88:11:88:46 | ...+... | provenance | Src:MaD:5 | | new-tests.go:95:18:95:45 | call to URLParam | new-tests.go:96:11:96:46 | ...+... | provenance | Src:MaD:4 | models @@ -71,21 +79,28 @@ models | 9 | Source: net/http; Request; true; URL; ; ; ; remote; manual | | 10 | Summary: encoding/json; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual | | 11 | Summary: fmt; ; false; Sprintf; ; ; Argument[1].ArrayElement; ReturnValue; taint; manual | -| 12 | Summary: io/ioutil; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual | -| 13 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual | -| 14 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | -| 15 | Summary: strings; ; false; TrimPrefix; ; ; Argument[0]; ReturnValue; taint; manual | +| 12 | Summary: fmt; Stringer; true; String; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 13 | Summary: io/ioutil; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual | +| 14 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 15 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 16 | Summary: strings; ; false; TrimPrefix; ; ; Argument[0]; ReturnValue; taint; manual | nodes -| builtin.go:19:12:19:34 | call to FormValue | semmle.label | call to FormValue | -| builtin.go:22:21:22:62 | ...+... | semmle.label | ...+... | -| builtin.go:83:21:83:31 | call to Referer | semmle.label | call to Referer | -| builtin.go:88:27:88:40 | untrustedInput | semmle.label | untrustedInput | -| builtin.go:97:21:97:31 | call to Referer | semmle.label | call to Referer | -| builtin.go:101:36:101:49 | untrustedInput | semmle.label | untrustedInput | -| builtin.go:111:21:111:31 | call to Referer | semmle.label | call to Referer | -| builtin.go:114:15:114:28 | untrustedInput | semmle.label | untrustedInput | -| builtin.go:129:21:129:31 | call to Referer | semmle.label | call to Referer | -| builtin.go:132:38:132:51 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:20:12:20:34 | call to FormValue | semmle.label | call to FormValue | +| builtin.go:23:21:23:62 | ...+... | semmle.label | ...+... | +| builtin.go:84:21:84:31 | call to Referer | semmle.label | call to Referer | +| builtin.go:89:27:89:40 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:98:21:98:31 | call to Referer | semmle.label | call to Referer | +| builtin.go:102:36:102:49 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:112:21:112:31 | call to Referer | semmle.label | call to Referer | +| builtin.go:115:15:115:28 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:130:21:130:31 | call to Referer | semmle.label | call to Referer | +| builtin.go:133:38:133:51 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:151:16:151:36 | call to FormValue | semmle.label | call to FormValue | +| builtin.go:154:2:154:4 | implicit dereference | semmle.label | implicit dereference | +| builtin.go:154:2:154:4 | url | semmle.label | url | +| builtin.go:154:13:154:22 | unsafehost | semmle.label | unsafehost | +| builtin.go:156:21:156:23 | url | semmle.label | url | +| builtin.go:156:21:156:32 | call to String | semmle.label | call to String | | new-tests.go:26:26:26:30 | &... [postupdate] | semmle.label | &... [postupdate] | | new-tests.go:31:11:31:57 | []type{args} [array] | semmle.label | []type{args} [array] | | new-tests.go:31:11:31:57 | call to Sprintf | semmle.label | call to Sprintf | diff --git a/go/ql/test/experimental/CWE-918/builtin.go b/go/ql/test/experimental/CWE-918/builtin.go index 463f4b3d09b..6c39f24dc47 100644 --- a/go/ql/test/experimental/CWE-918/builtin.go +++ b/go/ql/test/experimental/CWE-918/builtin.go @@ -8,6 +8,7 @@ import ( "fmt" "log" "net/http" + "net/url" "regexp" "strings" @@ -145,3 +146,16 @@ func test() { log.Println(http.ListenAndServe(":80", nil)) } + +func handler2(w http.ResponseWriter, req *http.Request) { + unsafehost := req.FormValue("host") // $ Source + + url, _ := url.Parse("http://example.com/data") + url.Host = unsafehost + // BAD: `target` is controlled by the attacker + _, err := http.Get(url.String()) // $ Alert + if err != nil { + // error handling + } + // process request response +}