Skip to content

Commit 09aab92

Browse files
committed
Add OpenUrlRedirect tests for Url.Host field
1 parent f2356de commit 09aab92

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
| stdlib.go:188:23:188:28 | target | stdlib.go:186:13:186:33 | call to FormValue | stdlib.go:188:23:188:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:186:13:186:33 | call to FormValue | user-provided value |
1111
| stdlib.go:196:23:196:33 | selection of Path | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:196:23:196:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value |
1212
| stdlib.go:198:23:198:42 | call to EscapedPath | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:198:23:198:42 | call to EscapedPath | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value |
13+
| stdlib.go:201:23:201:33 | selection of Path | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:201:23:201:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value |
14+
| stdlib.go:203:23:203:37 | call to String | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:203:23:203:37 | call to String | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value |
15+
| stdlib.go:212:23:212:28 | selection of Path | stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:212:23:212:28 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:210:12:210:30 | call to FormValue | user-provided value |
16+
| stdlib.go:214:23:214:32 | call to String | stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:214:23:214:32 | call to String | This path to an untrusted URL redirection depends on a $@. | stdlib.go:210:12:210:30 | call to FormValue | user-provided value |
1317
edges
1418
| OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | provenance | Src:MaD:2 Config Sink:MaD:1 |
1519
| stdlib.go:13:13:13:18 | selection of Form | stdlib.go:13:13:13:32 | call to Get | provenance | Src:MaD:2 Config |
@@ -55,9 +59,41 @@ edges
5559
| stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config |
5660
| stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 |
5761
| stdlib.go:196:23:196:28 | target | stdlib.go:198:23:198:28 | target | provenance | |
62+
| stdlib.go:196:23:196:28 | target | stdlib.go:199:3:199:8 | target | provenance | |
5863
| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config |
5964
| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:198:23:198:28 | target | provenance | |
65+
| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:199:3:199:8 | target | provenance | |
6066
| stdlib.go:198:23:198:28 | target | stdlib.go:198:23:198:42 | call to EscapedPath | provenance | Config Sink:MaD:1 |
67+
| stdlib.go:199:3:199:8 | implicit dereference | stdlib.go:199:3:199:8 | target [postupdate] | provenance | Config |
68+
| stdlib.go:199:3:199:8 | target | stdlib.go:199:3:199:8 | implicit dereference | provenance | Config |
69+
| stdlib.go:199:3:199:8 | target | stdlib.go:201:23:201:28 | target | provenance | |
70+
| stdlib.go:199:3:199:8 | target [postupdate] | stdlib.go:199:3:199:8 | implicit dereference | provenance | Config |
71+
| stdlib.go:199:3:199:8 | target [postupdate] | stdlib.go:201:23:201:28 | target | provenance | |
72+
| stdlib.go:201:23:201:28 | implicit dereference | stdlib.go:201:23:201:28 | target [postupdate] | provenance | Config |
73+
| stdlib.go:201:23:201:28 | implicit dereference | stdlib.go:201:23:201:33 | selection of Path | provenance | Config Sink:MaD:1 |
74+
| stdlib.go:201:23:201:28 | target | stdlib.go:201:23:201:28 | implicit dereference | provenance | Config |
75+
| stdlib.go:201:23:201:28 | target | stdlib.go:201:23:201:33 | selection of Path | provenance | Config Sink:MaD:1 |
76+
| stdlib.go:201:23:201:28 | target | stdlib.go:203:23:203:28 | target | provenance | |
77+
| stdlib.go:201:23:201:28 | target [postupdate] | stdlib.go:201:23:201:28 | implicit dereference | provenance | Config |
78+
| stdlib.go:201:23:201:28 | target [postupdate] | stdlib.go:203:23:203:28 | target | provenance | |
79+
| stdlib.go:203:23:203:28 | target | stdlib.go:203:23:203:37 | call to String | provenance | Config Sink:MaD:1 |
80+
| stdlib.go:210:3:210:3 | implicit dereference | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Config |
81+
| stdlib.go:210:3:210:3 | implicit dereference [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Config |
82+
| stdlib.go:210:3:210:3 | implicit dereference [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] [pointer] | provenance | |
83+
| stdlib.go:210:3:210:3 | u [postupdate] | stdlib.go:210:3:210:3 | implicit dereference | provenance | Config |
84+
| stdlib.go:210:3:210:3 | u [postupdate] | stdlib.go:212:23:212:23 | u | provenance | |
85+
| stdlib.go:210:3:210:3 | u [postupdate] [pointer] | stdlib.go:212:23:212:23 | u [pointer] | provenance | |
86+
| stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:210:3:210:3 | implicit dereference [postupdate] | provenance | Src:MaD:3 Config |
87+
| stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Src:MaD:3 Config |
88+
| stdlib.go:212:23:212:23 | implicit dereference | stdlib.go:212:23:212:23 | u [postupdate] | provenance | Config |
89+
| stdlib.go:212:23:212:23 | implicit dereference | stdlib.go:212:23:212:28 | selection of Path | provenance | Config Sink:MaD:1 |
90+
| stdlib.go:212:23:212:23 | u | stdlib.go:212:23:212:23 | implicit dereference | provenance | Config |
91+
| stdlib.go:212:23:212:23 | u | stdlib.go:212:23:212:28 | selection of Path | provenance | Config Sink:MaD:1 |
92+
| stdlib.go:212:23:212:23 | u | stdlib.go:214:23:214:23 | u | provenance | |
93+
| stdlib.go:212:23:212:23 | u [pointer] | stdlib.go:212:23:212:23 | implicit dereference | provenance | |
94+
| stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:212:23:212:23 | implicit dereference | provenance | Config |
95+
| stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:214:23:214:23 | u | provenance | |
96+
| stdlib.go:214:23:214:23 | u | stdlib.go:214:23:214:32 | call to String | provenance | Config Sink:MaD:1 |
6197
models
6298
| 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual |
6399
| 2 | Source: net/http; Request; true; Form; ; ; ; remote; manual |
@@ -119,4 +155,28 @@ nodes
119155
| stdlib.go:196:23:196:33 | selection of Path | semmle.label | selection of Path |
120156
| stdlib.go:198:23:198:28 | target | semmle.label | target |
121157
| stdlib.go:198:23:198:42 | call to EscapedPath | semmle.label | call to EscapedPath |
158+
| stdlib.go:199:3:199:8 | implicit dereference | semmle.label | implicit dereference |
159+
| stdlib.go:199:3:199:8 | target | semmle.label | target |
160+
| stdlib.go:199:3:199:8 | target [postupdate] | semmle.label | target [postupdate] |
161+
| stdlib.go:201:23:201:28 | implicit dereference | semmle.label | implicit dereference |
162+
| stdlib.go:201:23:201:28 | target | semmle.label | target |
163+
| stdlib.go:201:23:201:28 | target [postupdate] | semmle.label | target [postupdate] |
164+
| stdlib.go:201:23:201:33 | selection of Path | semmle.label | selection of Path |
165+
| stdlib.go:203:23:203:28 | target | semmle.label | target |
166+
| stdlib.go:203:23:203:37 | call to String | semmle.label | call to String |
167+
| stdlib.go:210:3:210:3 | implicit dereference | semmle.label | implicit dereference |
168+
| stdlib.go:210:3:210:3 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
169+
| stdlib.go:210:3:210:3 | u [postupdate] | semmle.label | u [postupdate] |
170+
| stdlib.go:210:3:210:3 | u [postupdate] [pointer] | semmle.label | u [postupdate] [pointer] |
171+
| stdlib.go:210:12:210:30 | call to FormValue | semmle.label | call to FormValue |
172+
| stdlib.go:212:23:212:23 | implicit dereference | semmle.label | implicit dereference |
173+
| stdlib.go:212:23:212:23 | u | semmle.label | u |
174+
| stdlib.go:212:23:212:23 | u [pointer] | semmle.label | u [pointer] |
175+
| stdlib.go:212:23:212:23 | u [postupdate] | semmle.label | u [postupdate] |
176+
| stdlib.go:212:23:212:28 | selection of Path | semmle.label | selection of Path |
177+
| stdlib.go:214:23:214:23 | u | semmle.label | u |
178+
| stdlib.go:214:23:214:32 | call to String | semmle.label | call to String |
122179
subpaths
180+
testFailures
181+
| stdlib.go:201:23:201:33 | selection of Path | Fixed missing result: Alert |
182+
| stdlib.go:203:23:203:37 | call to String | Unexpected result: Alert |

go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,25 @@ func serveStdlib() {
196196
http.Redirect(w, r, target.Path, 301) // $ Alert
197197
// BAD: EscapedPath() does not help with that
198198
http.Redirect(w, r, target.EscapedPath(), 301) // $ Alert
199+
target.Host = "example.com"
200+
// BAD: Host field was overwritten but Path field remains untrusted
201+
http.Redirect(w, r, target.Path, 301) // $ MISSING: Alert
202+
// GOOD: untrusted Host field was overwritten
203+
http.Redirect(w, r, target.String(), 301)
199204
})
200205

201206
http.HandleFunc("/ex11", func(w http.ResponseWriter, r *http.Request) {
207+
r.ParseForm()
208+
209+
u, _ := url.Parse("http://bing.com/search?q=dotnet")
210+
u.Host = r.FormValue("host") // $ Source
211+
// GOOD: Path field is trusted
212+
http.Redirect(w, r, u.Path, 301) // $ SPURIOUS: Alert
213+
// BAD: Host field is untrusted
214+
http.Redirect(w, r, u.String(), 301) // $ Alert
215+
})
216+
217+
http.HandleFunc("/ex12", func(w http.ResponseWriter, r *http.Request) {
202218
// GOOD: all these fields and methods are disregarded for OpenRedirect attacks:
203219
buf := make([]byte, 100)
204220
r.Body.Read(buf)

0 commit comments

Comments
 (0)