Merge pull request #14608 from Kwstubbs/golang-cookie-reflectedxss-sanitizer

Go: GoAdd Cookie Sanitizer to Reflected XSS
This commit is contained in:
Owen Mansel-Chan
2023-10-27 21:47:39 +01:00
committed by GitHub
7 changed files with 150 additions and 137 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added [Request.Cookie](https://pkg.go.dev/net/http#Request.Cookie) to reflected XSS sanitizers.

View File

@@ -22,6 +22,18 @@ module ReflectedXss {
/** A shared XSS sanitizer as a sanitizer for reflected XSS. */
private class SharedXssSanitizer extends Sanitizer instanceof SharedXss::Sanitizer { }
/**
* A request.Cookie method returns the request cookie, which is not user controlled in reflected XSS context.
*/
class CookieSanitizer extends Sanitizer {
CookieSanitizer() {
exists(Method m, DataFlow::CallNode call | call = m.getACall() |
m.hasQualifiedName("net/http", "Request", "Cookie") and
this = call.getResult(0)
)
}
}
/**
* A third-party controllable input, considered as a flow source for reflected XSS.
*/

View File

@@ -1,123 +1,127 @@
edges
| test.go:11:2:11:42 | ... := ...[0] | test.go:14:42:14:53 | selection of Value |
| test.go:14:22:14:54 | call to UnescapeString | test.go:14:15:14:55 | type conversion |
| test.go:14:42:14:53 | selection of Value | test.go:14:22:14:54 | call to UnescapeString |
| test.go:16:2:16:36 | ... := ...[0] | test.go:17:15:17:31 | type conversion |
| test.go:16:2:16:36 | ... := ...[0] | test.go:28:22:28:25 | node |
| test.go:16:24:16:35 | selection of Body | test.go:16:2:16:36 | ... := ...[0] |
| test.go:19:2:19:48 | ... := ...[0] | test.go:20:15:20:32 | type conversion |
| test.go:19:36:19:47 | selection of Body | test.go:19:2:19:48 | ... := ...[0] |
| test.go:22:2:22:50 | ... := ...[0] | test.go:23:15:23:35 | type conversion |
| test.go:22:33:22:44 | selection of Body | test.go:22:2:22:50 | ... := ...[0] |
| test.go:25:2:25:62 | ... := ...[0] | test.go:26:15:26:36 | type conversion |
| test.go:25:45:25:56 | selection of Body | test.go:25:2:25:62 | ... := ...[0] |
| test.go:30:15:30:45 | call to NewTokenizer | test.go:31:15:31:23 | tokenizer |
| test.go:30:15:30:45 | call to NewTokenizer | test.go:32:15:32:23 | tokenizer |
| test.go:30:15:30:45 | call to NewTokenizer | test.go:33:17:33:25 | tokenizer |
| test.go:30:15:30:45 | call to NewTokenizer | test.go:35:15:35:23 | tokenizer |
| test.go:30:15:30:45 | call to NewTokenizer | test.go:36:22:36:30 | tokenizer |
| test.go:30:33:30:44 | selection of Body | test.go:30:15:30:45 | call to NewTokenizer |
| test.go:31:15:31:23 | tokenizer | test.go:31:15:31:34 | call to Buffered |
| test.go:32:15:32:23 | tokenizer | test.go:32:15:32:29 | call to Raw |
| test.go:33:2:33:35 | ... := ...[1] | test.go:34:15:34:19 | value |
| test.go:33:17:33:25 | tokenizer | test.go:33:2:33:35 | ... := ...[1] |
| test.go:35:15:35:23 | tokenizer | test.go:35:15:35:30 | call to Text |
| test.go:36:22:36:30 | tokenizer | test.go:36:22:36:38 | call to Token |
| test.go:36:22:36:38 | call to Token | test.go:36:15:36:44 | type conversion |
| test.go:38:23:38:77 | call to NewTokenizerFragment | test.go:39:15:39:31 | tokenizerFragment |
| test.go:38:49:38:60 | selection of Body | test.go:38:23:38:77 | call to NewTokenizerFragment |
| test.go:39:15:39:31 | tokenizerFragment | test.go:39:15:39:42 | call to Buffered |
| test.go:41:6:41:14 | definition of cleanNode | test.go:44:22:44:31 | &... |
| test.go:41:6:41:14 | definition of cleanNode | test.go:44:22:44:31 | &... |
| test.go:41:6:41:14 | definition of cleanNode | test.go:44:23:44:31 | cleanNode |
| test.go:42:2:42:43 | ... := ...[0] | test.go:43:24:43:34 | taintedNode |
| test.go:42:31:42:42 | selection of Body | test.go:42:2:42:43 | ... := ...[0] |
| test.go:43:24:43:34 | taintedNode | test.go:41:6:41:14 | definition of cleanNode |
| test.go:44:22:44:31 | &... | test.go:44:22:44:31 | &... |
| test.go:44:22:44:31 | &... | test.go:44:22:44:31 | &... |
| test.go:44:22:44:31 | &... | test.go:44:23:44:31 | cleanNode |
| test.go:44:22:44:31 | &... [pointer] | test.go:44:22:44:31 | &... |
| test.go:44:22:44:31 | &... [pointer] | test.go:44:22:44:31 | &... |
| test.go:44:22:44:31 | &... [pointer] | test.go:44:23:44:31 | cleanNode |
| test.go:44:23:44:31 | cleanNode | test.go:44:22:44:31 | &... [pointer] |
| test.go:46:6:46:15 | definition of cleanNode2 | test.go:49:22:49:32 | &... |
| test.go:46:6:46:15 | definition of cleanNode2 | test.go:49:22:49:32 | &... |
| test.go:46:6:46:15 | definition of cleanNode2 | test.go:49:23:49:32 | cleanNode2 |
| test.go:47:2:47:44 | ... := ...[0] | test.go:48:26:48:37 | taintedNode2 |
| test.go:47:32:47:43 | selection of Body | test.go:47:2:47:44 | ... := ...[0] |
| test.go:48:26:48:37 | taintedNode2 | test.go:46:6:46:15 | definition of cleanNode2 |
| test.go:49:22:49:32 | &... | test.go:49:22:49:32 | &... |
| test.go:49:22:49:32 | &... | test.go:49:22:49:32 | &... |
| test.go:49:22:49:32 | &... | test.go:49:23:49:32 | cleanNode2 |
| test.go:49:22:49:32 | &... [pointer] | test.go:49:22:49:32 | &... |
| test.go:49:22:49:32 | &... [pointer] | test.go:49:22:49:32 | &... |
| test.go:49:22:49:32 | &... [pointer] | test.go:49:23:49:32 | cleanNode2 |
| test.go:49:23:49:32 | cleanNode2 | test.go:49:22:49:32 | &... [pointer] |
| test.go:12:12:12:22 | selection of URL | test.go:12:12:12:30 | call to Query |
| test.go:12:12:12:30 | call to Query | test.go:12:12:12:44 | call to Get |
| test.go:12:12:12:44 | call to Get | test.go:15:42:15:47 | param1 |
| test.go:15:22:15:48 | call to UnescapeString | test.go:15:15:15:49 | type conversion |
| test.go:15:42:15:47 | param1 | test.go:15:22:15:48 | call to UnescapeString |
| test.go:17:2:17:36 | ... := ...[0] | test.go:18:15:18:31 | type conversion |
| test.go:17:2:17:36 | ... := ...[0] | test.go:29:22:29:25 | node |
| test.go:17:24:17:35 | selection of Body | test.go:17:2:17:36 | ... := ...[0] |
| test.go:20:2:20:48 | ... := ...[0] | test.go:21:15:21:32 | type conversion |
| test.go:20:36:20:47 | selection of Body | test.go:20:2:20:48 | ... := ...[0] |
| test.go:23:2:23:50 | ... := ...[0] | test.go:24:15:24:35 | type conversion |
| test.go:23:33:23:44 | selection of Body | test.go:23:2:23:50 | ... := ...[0] |
| test.go:26:2:26:62 | ... := ...[0] | test.go:27:15:27:36 | type conversion |
| test.go:26:45:26:56 | selection of Body | test.go:26:2:26:62 | ... := ...[0] |
| test.go:31:15:31:45 | call to NewTokenizer | test.go:32:15:32:23 | tokenizer |
| test.go:31:15:31:45 | call to NewTokenizer | test.go:33:15:33:23 | tokenizer |
| test.go:31:15:31:45 | call to NewTokenizer | test.go:34:17:34:25 | tokenizer |
| test.go:31:15:31:45 | call to NewTokenizer | test.go:36:15:36:23 | tokenizer |
| test.go:31:15:31:45 | call to NewTokenizer | test.go:37:22:37:30 | tokenizer |
| test.go:31:33:31:44 | selection of Body | test.go:31:15:31:45 | call to NewTokenizer |
| test.go:32:15:32:23 | tokenizer | test.go:32:15:32:34 | call to Buffered |
| test.go:33:15:33:23 | tokenizer | test.go:33:15:33:29 | call to Raw |
| test.go:34:2:34:35 | ... := ...[1] | test.go:35:15:35:19 | value |
| test.go:34:17:34:25 | tokenizer | test.go:34:2:34:35 | ... := ...[1] |
| test.go:36:15:36:23 | tokenizer | test.go:36:15:36:30 | call to Text |
| test.go:37:22:37:30 | tokenizer | test.go:37:22:37:38 | call to Token |
| test.go:37:22:37:38 | call to Token | test.go:37:15:37:44 | type conversion |
| test.go:39:23:39:77 | call to NewTokenizerFragment | test.go:40:15:40:31 | tokenizerFragment |
| test.go:39:49:39:60 | selection of Body | test.go:39:23:39:77 | call to NewTokenizerFragment |
| test.go:40:15:40:31 | tokenizerFragment | test.go:40:15:40:42 | call to Buffered |
| test.go:42:6:42:14 | definition of cleanNode | test.go:45:22:45:31 | &... |
| test.go:42:6:42:14 | definition of cleanNode | test.go:45:22:45:31 | &... |
| test.go:42:6:42:14 | definition of cleanNode | test.go:45:23:45:31 | cleanNode |
| test.go:43:2:43:43 | ... := ...[0] | test.go:44:24:44:34 | taintedNode |
| test.go:43:31:43:42 | selection of Body | test.go:43:2:43:43 | ... := ...[0] |
| test.go:44:24:44:34 | taintedNode | test.go:42:6:42:14 | definition of cleanNode |
| test.go:45:22:45:31 | &... | test.go:45:22:45:31 | &... |
| test.go:45:22:45:31 | &... | test.go:45:22:45:31 | &... |
| test.go:45:22:45:31 | &... | test.go:45:23:45:31 | cleanNode |
| test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... |
| test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... |
| test.go:45:22:45:31 | &... [pointer] | test.go:45:23:45:31 | cleanNode |
| test.go:45:23:45:31 | cleanNode | test.go:45:22:45:31 | &... [pointer] |
| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... |
| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... |
| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:23:50:32 | cleanNode2 |
| test.go:48:2:48:44 | ... := ...[0] | test.go:49:26:49:37 | taintedNode2 |
| test.go:48:32:48:43 | selection of Body | test.go:48:2:48:44 | ... := ...[0] |
| test.go:49:26:49:37 | taintedNode2 | test.go:47:6:47:15 | definition of cleanNode2 |
| test.go:50:22:50:32 | &... | test.go:50:22:50:32 | &... |
| test.go:50:22:50:32 | &... | test.go:50:22:50:32 | &... |
| test.go:50:22:50:32 | &... | test.go:50:23:50:32 | cleanNode2 |
| test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... |
| test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... |
| test.go:50:22:50:32 | &... [pointer] | test.go:50:23:50:32 | cleanNode2 |
| test.go:50:23:50:32 | cleanNode2 | test.go:50:22:50:32 | &... [pointer] |
nodes
| test.go:11:2:11:42 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:14:15:14:55 | type conversion | semmle.label | type conversion |
| test.go:14:22:14:54 | call to UnescapeString | semmle.label | call to UnescapeString |
| test.go:14:42:14:53 | selection of Value | semmle.label | selection of Value |
| test.go:16:2:16:36 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:16:24:16:35 | selection of Body | semmle.label | selection of Body |
| test.go:17:15:17:31 | type conversion | semmle.label | type conversion |
| test.go:19:2:19:48 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:19:36:19:47 | selection of Body | semmle.label | selection of Body |
| test.go:20:15:20:32 | type conversion | semmle.label | type conversion |
| test.go:22:2:22:50 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:22:33:22:44 | selection of Body | semmle.label | selection of Body |
| test.go:23:15:23:35 | type conversion | semmle.label | type conversion |
| test.go:25:2:25:62 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:25:45:25:56 | selection of Body | semmle.label | selection of Body |
| test.go:26:15:26:36 | type conversion | semmle.label | type conversion |
| test.go:28:22:28:25 | node | semmle.label | node |
| test.go:30:15:30:45 | call to NewTokenizer | semmle.label | call to NewTokenizer |
| test.go:30:33:30:44 | selection of Body | semmle.label | selection of Body |
| test.go:31:15:31:23 | tokenizer | semmle.label | tokenizer |
| test.go:31:15:31:34 | call to Buffered | semmle.label | call to Buffered |
| test.go:12:12:12:22 | selection of URL | semmle.label | selection of URL |
| test.go:12:12:12:30 | call to Query | semmle.label | call to Query |
| test.go:12:12:12:44 | call to Get | semmle.label | call to Get |
| test.go:15:15:15:49 | type conversion | semmle.label | type conversion |
| test.go:15:22:15:48 | call to UnescapeString | semmle.label | call to UnescapeString |
| test.go:15:42:15:47 | param1 | semmle.label | param1 |
| test.go:17:2:17:36 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:17:24:17:35 | selection of Body | semmle.label | selection of Body |
| test.go:18:15:18:31 | type conversion | semmle.label | type conversion |
| test.go:20:2:20:48 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:20:36:20:47 | selection of Body | semmle.label | selection of Body |
| test.go:21:15:21:32 | type conversion | semmle.label | type conversion |
| test.go:23:2:23:50 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:23:33:23:44 | selection of Body | semmle.label | selection of Body |
| test.go:24:15:24:35 | type conversion | semmle.label | type conversion |
| test.go:26:2:26:62 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:26:45:26:56 | selection of Body | semmle.label | selection of Body |
| test.go:27:15:27:36 | type conversion | semmle.label | type conversion |
| test.go:29:22:29:25 | node | semmle.label | node |
| test.go:31:15:31:45 | call to NewTokenizer | semmle.label | call to NewTokenizer |
| test.go:31:33:31:44 | selection of Body | semmle.label | selection of Body |
| test.go:32:15:32:23 | tokenizer | semmle.label | tokenizer |
| test.go:32:15:32:29 | call to Raw | semmle.label | call to Raw |
| test.go:33:2:33:35 | ... := ...[1] | semmle.label | ... := ...[1] |
| test.go:33:17:33:25 | tokenizer | semmle.label | tokenizer |
| test.go:34:15:34:19 | value | semmle.label | value |
| test.go:35:15:35:23 | tokenizer | semmle.label | tokenizer |
| test.go:35:15:35:30 | call to Text | semmle.label | call to Text |
| test.go:36:15:36:44 | type conversion | semmle.label | type conversion |
| test.go:36:22:36:30 | tokenizer | semmle.label | tokenizer |
| test.go:36:22:36:38 | call to Token | semmle.label | call to Token |
| test.go:38:23:38:77 | call to NewTokenizerFragment | semmle.label | call to NewTokenizerFragment |
| test.go:38:49:38:60 | selection of Body | semmle.label | selection of Body |
| test.go:39:15:39:31 | tokenizerFragment | semmle.label | tokenizerFragment |
| test.go:39:15:39:42 | call to Buffered | semmle.label | call to Buffered |
| test.go:41:6:41:14 | definition of cleanNode | semmle.label | definition of cleanNode |
| test.go:42:2:42:43 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:42:31:42:42 | selection of Body | semmle.label | selection of Body |
| test.go:43:24:43:34 | taintedNode | semmle.label | taintedNode |
| test.go:44:22:44:31 | &... | semmle.label | &... |
| test.go:44:22:44:31 | &... | semmle.label | &... |
| test.go:44:22:44:31 | &... [pointer] | semmle.label | &... [pointer] |
| test.go:44:23:44:31 | cleanNode | semmle.label | cleanNode |
| test.go:46:6:46:15 | definition of cleanNode2 | semmle.label | definition of cleanNode2 |
| test.go:47:2:47:44 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:47:32:47:43 | selection of Body | semmle.label | selection of Body |
| test.go:48:26:48:37 | taintedNode2 | semmle.label | taintedNode2 |
| test.go:49:22:49:32 | &... | semmle.label | &... |
| test.go:49:22:49:32 | &... | semmle.label | &... |
| test.go:49:22:49:32 | &... [pointer] | semmle.label | &... [pointer] |
| test.go:49:23:49:32 | cleanNode2 | semmle.label | cleanNode2 |
| test.go:32:15:32:34 | call to Buffered | semmle.label | call to Buffered |
| test.go:33:15:33:23 | tokenizer | semmle.label | tokenizer |
| test.go:33:15:33:29 | call to Raw | semmle.label | call to Raw |
| test.go:34:2:34:35 | ... := ...[1] | semmle.label | ... := ...[1] |
| test.go:34:17:34:25 | tokenizer | semmle.label | tokenizer |
| test.go:35:15:35:19 | value | semmle.label | value |
| test.go:36:15:36:23 | tokenizer | semmle.label | tokenizer |
| test.go:36:15:36:30 | call to Text | semmle.label | call to Text |
| test.go:37:15:37:44 | type conversion | semmle.label | type conversion |
| test.go:37:22:37:30 | tokenizer | semmle.label | tokenizer |
| test.go:37:22:37:38 | call to Token | semmle.label | call to Token |
| test.go:39:23:39:77 | call to NewTokenizerFragment | semmle.label | call to NewTokenizerFragment |
| test.go:39:49:39:60 | selection of Body | semmle.label | selection of Body |
| test.go:40:15:40:31 | tokenizerFragment | semmle.label | tokenizerFragment |
| test.go:40:15:40:42 | call to Buffered | semmle.label | call to Buffered |
| test.go:42:6:42:14 | definition of cleanNode | semmle.label | definition of cleanNode |
| test.go:43:2:43:43 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:43:31:43:42 | selection of Body | semmle.label | selection of Body |
| test.go:44:24:44:34 | taintedNode | semmle.label | taintedNode |
| test.go:45:22:45:31 | &... | semmle.label | &... |
| test.go:45:22:45:31 | &... | semmle.label | &... |
| test.go:45:22:45:31 | &... [pointer] | semmle.label | &... [pointer] |
| test.go:45:23:45:31 | cleanNode | semmle.label | cleanNode |
| test.go:47:6:47:15 | definition of cleanNode2 | semmle.label | definition of cleanNode2 |
| test.go:48:2:48:44 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:48:32:48:43 | selection of Body | semmle.label | selection of Body |
| test.go:49:26:49:37 | taintedNode2 | semmle.label | taintedNode2 |
| test.go:50:22:50:32 | &... | semmle.label | &... |
| test.go:50:22:50:32 | &... | semmle.label | &... |
| test.go:50:22:50:32 | &... [pointer] | semmle.label | &... [pointer] |
| test.go:50:23:50:32 | cleanNode2 | semmle.label | cleanNode2 |
subpaths
#select
| test.go:14:15:14:55 | type conversion | test.go:11:2:11:42 | ... := ...[0] | test.go:14:15:14:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:11:2:11:42 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:17:15:17:31 | type conversion | test.go:16:24:16:35 | selection of Body | test.go:17:15:17:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:16:24:16:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:20:15:20:32 | type conversion | test.go:19:36:19:47 | selection of Body | test.go:20:15:20:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:19:36:19:47 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:23:15:23:35 | type conversion | test.go:22:33:22:44 | selection of Body | test.go:23:15:23:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:22:33:22:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:26:15:26:36 | type conversion | test.go:25:45:25:56 | selection of Body | test.go:26:15:26:36 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:25:45:25:56 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:28:22:28:25 | node | test.go:16:24:16:35 | selection of Body | test.go:28:22:28:25 | node | Cross-site scripting vulnerability due to $@. | test.go:16:24:16:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:31:15:31:34 | call to Buffered | test.go:30:33:30:44 | selection of Body | test.go:31:15:31:34 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:32:15:32:29 | call to Raw | test.go:30:33:30:44 | selection of Body | test.go:32:15:32:29 | call to Raw | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:34:15:34:19 | value | test.go:30:33:30:44 | selection of Body | test.go:34:15:34:19 | value | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:35:15:35:30 | call to Text | test.go:30:33:30:44 | selection of Body | test.go:35:15:35:30 | call to Text | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:36:15:36:44 | type conversion | test.go:30:33:30:44 | selection of Body | test.go:36:15:36:44 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:39:15:39:42 | call to Buffered | test.go:38:49:38:60 | selection of Body | test.go:39:15:39:42 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:38:49:38:60 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:44:22:44:31 | &... | test.go:42:31:42:42 | selection of Body | test.go:44:22:44:31 | &... | Cross-site scripting vulnerability due to $@. | test.go:42:31:42:42 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:49:22:49:32 | &... | test.go:47:32:47:43 | selection of Body | test.go:49:22:49:32 | &... | Cross-site scripting vulnerability due to $@. | test.go:47:32:47:43 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:15:15:15:49 | type conversion | test.go:12:12:12:22 | selection of URL | test.go:15:15:15:49 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:12:12:12:22 | selection of URL | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:18:15:18:31 | type conversion | test.go:17:24:17:35 | selection of Body | test.go:18:15:18:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:17:24:17:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:21:15:21:32 | type conversion | test.go:20:36:20:47 | selection of Body | test.go:21:15:21:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:20:36:20:47 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:24:15:24:35 | type conversion | test.go:23:33:23:44 | selection of Body | test.go:24:15:24:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:23:33:23:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:27:15:27:36 | type conversion | test.go:26:45:26:56 | selection of Body | test.go:27:15:27:36 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:26:45:26:56 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:29:22:29:25 | node | test.go:17:24:17:35 | selection of Body | test.go:29:22:29:25 | node | Cross-site scripting vulnerability due to $@. | test.go:17:24:17:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:32:15:32:34 | call to Buffered | test.go:31:33:31:44 | selection of Body | test.go:32:15:32:34 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:33:15:33:29 | call to Raw | test.go:31:33:31:44 | selection of Body | test.go:33:15:33:29 | call to Raw | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:35:15:35:19 | value | test.go:31:33:31:44 | selection of Body | test.go:35:15:35:19 | value | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:36:15:36:30 | call to Text | test.go:31:33:31:44 | selection of Body | test.go:36:15:36:30 | call to Text | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:37:15:37:44 | type conversion | test.go:31:33:31:44 | selection of Body | test.go:37:15:37:44 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:40:15:40:42 | call to Buffered | test.go:39:49:39:60 | selection of Body | test.go:40:15:40:42 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:39:49:39:60 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:45:22:45:31 | &... | test.go:43:31:43:42 | selection of Body | test.go:45:22:45:31 | &... | Cross-site scripting vulnerability due to $@. | test.go:43:31:43:42 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |
| test.go:50:22:50:32 | &... | test.go:48:32:48:43 | selection of Body | test.go:50:22:50:32 | &... | Cross-site scripting vulnerability due to $@. | test.go:48:32:48:43 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | |

View File

@@ -1,10 +1,10 @@
edges
| test.go:55:2:55:42 | ... := ...[0] | test.go:56:29:56:40 | selection of Value |
| test.go:56:29:56:40 | selection of Value | test.go:56:11:56:41 | call to EscapeString |
| test.go:56:2:56:42 | ... := ...[0] | test.go:57:29:57:40 | selection of Value |
| test.go:57:29:57:40 | selection of Value | test.go:57:11:57:41 | call to EscapeString |
nodes
| test.go:55:2:55:42 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:56:11:56:41 | call to EscapeString | semmle.label | call to EscapeString |
| test.go:56:29:56:40 | selection of Value | semmle.label | selection of Value |
| test.go:56:2:56:42 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:57:11:57:41 | call to EscapeString | semmle.label | call to EscapeString |
| test.go:57:29:57:40 | selection of Value | semmle.label | selection of Value |
subpaths
#select
| test.go:56:11:56:41 | call to EscapeString | test.go:55:2:55:42 | ... := ...[0] | test.go:56:11:56:41 | call to EscapeString | This query depends on a $@. | test.go:55:2:55:42 | ... := ...[0] | user-provided value |
| test.go:57:11:57:41 | call to EscapeString | test.go:56:2:56:42 | ... := ...[0] | test.go:57:11:57:41 | call to EscapeString | This query depends on a $@. | test.go:56:2:56:42 | ... := ...[0] | user-provided value |

View File

@@ -2,16 +2,17 @@ package test
import (
"database/sql"
"golang.org/x/net/html"
"net/http"
"golang.org/x/net/html"
)
func test(request *http.Request, writer http.ResponseWriter) {
cookie, _ := request.Cookie("SomeCookie")
writer.Write([]byte(html.EscapeString(cookie.Value))) // GOOD: escaped.
param1 := request.URL.Query().Get("param1")
writer.Write([]byte(html.EscapeString(param1))) // GOOD: escaped.
writer.Write([]byte(html.UnescapeString(cookie.Value))) // BAD: unescaped.
writer.Write([]byte(html.UnescapeString(param1))) // BAD: unescaped.
node, _ := html.Parse(request.Body)
writer.Write([]byte(node.Data)) // BAD: writing unescaped HTML data

View File

@@ -9,9 +9,6 @@ edges
| contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data |
| contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data |
| contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data |
| reflectedxsstest.go:27:2:27:38 | ... := ...[0] | reflectedxsstest.go:28:50:28:55 | cookie |
| reflectedxsstest.go:28:17:28:56 | call to Sprintf | reflectedxsstest.go:28:10:28:57 | type conversion |
| reflectedxsstest.go:28:50:28:55 | cookie | reflectedxsstest.go:28:17:28:56 | call to Sprintf |
| reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:32:34:32:37 | file |
| reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:46:34:60 | selection of Filename |
| reflectedxsstest.go:32:2:32:38 | ... := ...[0] | reflectedxsstest.go:33:49:33:55 | content |
@@ -62,10 +59,6 @@ nodes
| contenttype.go:91:4:91:7 | data | semmle.label | data |
| contenttype.go:113:10:113:28 | call to FormValue | semmle.label | call to FormValue |
| contenttype.go:114:50:114:53 | data | semmle.label | data |
| reflectedxsstest.go:27:2:27:38 | ... := ...[0] | semmle.label | ... := ...[0] |
| reflectedxsstest.go:28:10:28:57 | type conversion | semmle.label | type conversion |
| reflectedxsstest.go:28:17:28:56 | call to Sprintf | semmle.label | call to Sprintf |
| reflectedxsstest.go:28:50:28:55 | cookie | semmle.label | cookie |
| reflectedxsstest.go:31:2:31:44 | ... := ...[0] | semmle.label | ... := ...[0] |
| reflectedxsstest.go:31:2:31:44 | ... := ...[1] | semmle.label | ... := ...[1] |
| reflectedxsstest.go:32:2:32:38 | ... := ...[0] | semmle.label | ... := ...[0] |
@@ -119,7 +112,6 @@ subpaths
| contenttype.go:79:11:79:14 | data | contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:73:10:73:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | |
| contenttype.go:91:4:91:7 | data | contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:88:10:88:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | |
| contenttype.go:114:50:114:53 | data | contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:113:10:113:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | |
| reflectedxsstest.go:28:10:28:57 | type conversion | reflectedxsstest.go:27:2:27:38 | ... := ...[0] | reflectedxsstest.go:28:10:28:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:27:2:27:38 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | |
| reflectedxsstest.go:33:10:33:57 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:33:10:33:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | |
| reflectedxsstest.go:34:10:34:62 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:10:34:62 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | |
| reflectedxsstest.go:44:10:44:55 | type conversion | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:44:10:44:55 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | |

View File

@@ -25,7 +25,7 @@ func ServeJsonDirect(w http.ResponseWriter, r http.Request) {
func ErrTest(w http.ResponseWriter, r http.Request) {
cookie, err := r.Cookie("somecookie")
w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // BAD: Cookie's value is user-controlled
w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // GOOD: Cookie's value is not user-controlled in reflected xss.
w.Write([]byte(fmt.Sprintf("Cookie check error: %v", err))) // GOOD: Cookie's err return is harmless
http.Error(w, fmt.Sprintf("Cookie result: %v", cookie), 500) // Good: only plain text is written.
file, header, err := r.FormFile("someFile")