Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: deprecated
---
* The class `SqlInjection::NumericOrBooleanSanitizer` has been deprecated. Use `SimpleTypeSanitizer` from `semmle.go.security.Sanitizers` instead.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The query `go/request-forgery` will no longer report alerts when the user input is of a simple type, like a number or a boolean.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import semmle.go.dataflow.barrierguardutil.RedirectCheckBarrierGuard
import semmle.go.dataflow.barrierguardutil.RegexpCheck
import semmle.go.dataflow.barrierguardutil.UrlCheck
import semmle.go.dataflow.ExternalFlow
private import semmle.go.security.Sanitizers

/** Provides classes and predicates for the request forgery query. */
module RequestForgery {
Expand Down Expand Up @@ -114,6 +115,11 @@ module RequestForgery {
* considered a barrier guard for `url`.
*/
class UrlCheckAsBarrierGuard extends UrlCheckBarrier, Sanitizer { }

/**
* A simple-typed node, considered a sanitizer for request forgery.
*/
private class DefaultSanitizer extends Sanitizer instanceof SimpleTypeSanitizer { }
}

/** A sink for request forgery, considered as a sink for safe URL flow. */
Expand Down
16 changes: 16 additions & 0 deletions go/ql/lib/semmle/go/security/Sanitizers.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Classes to represent sanitizers commonly used in dataflow and taint tracking
* configurations.
*/

import go

/**
* A node whose type is a simple type unlikely to carry taint, such as a
* numeric or boolean type.
*/
class SimpleTypeSanitizer extends DataFlow::Node {
SimpleTypeSanitizer() {
this.getType() instanceof NumericType or this.getType() instanceof BoolType
}
}
10 changes: 5 additions & 5 deletions go/ql/lib/semmle/go/security/SqlInjectionCustomizations.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import go
private import semmle.go.security.Sanitizers

/**
* Provides extension points for customizing the taint tracking configuration for reasoning about
Expand Down Expand Up @@ -39,12 +40,11 @@ module SqlInjection {
/** A NoSql query, considered as a taint sink for SQL injection. */
class NoSqlQueryAsSink extends Sink instanceof NoSql::Query { }

/** DEPRECATED: Use `SimpleTypeSanitizer` from semmle.go.security.Sanitizers instead. */
deprecated class NumericOrBooleanSanitizer = SimpleTypeSanitizer;

/**
* A numeric- or boolean-typed node, considered a sanitizer for sql injection.
*/
class NumericOrBooleanSanitizer extends Sanitizer {
NumericOrBooleanSanitizer() {
this.getType() instanceof NumericType or this.getType() instanceof BoolType
}
}
private class DefaultSanitizer extends Sanitizer instanceof SimpleTypeSanitizer { }
}
96 changes: 48 additions & 48 deletions go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
#select
| 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 |
| tst.go:18:2:18:18 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:18:11:18:17 | tainted | The $@ of this request depends on a $@. | tst.go:18:11:18:17 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:20:2:20:19 | call to Head | tst.go:10:13:10:35 | call to FormValue | tst.go:20:12:20:18 | tainted | The $@ of this request depends on a $@. | tst.go:20:12:20:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:22:2:22:38 | call to Post | tst.go:10:13:10:35 | call to FormValue | tst.go:22:12:22:18 | tainted | The $@ of this request depends on a $@. | tst.go:22:12:22:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:24:2:24:28 | call to PostForm | tst.go:10:13:10:35 | call to FormValue | tst.go:24:16:24:22 | tainted | The $@ of this request depends on a $@. | tst.go:24:16:24:22 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:28:2:28:15 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:27:35:27:41 | tainted | The $@ of this request depends on a $@. | tst.go:27:35:27:41 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:31:2:31:15 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:30:68:30:74 | tainted | The $@ of this request depends on a $@. | tst.go:30:68:30:74 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:33:2:33:20 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:33:13:33:19 | tainted | The $@ of this request depends on a $@. | tst.go:33:13:33:19 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:34:2:34:21 | call to Head | tst.go:10:13:10:35 | call to FormValue | tst.go:34:14:34:20 | tainted | The $@ of this request depends on a $@. | tst.go:34:14:34:20 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:35:2:35:40 | call to Post | tst.go:10:13:10:35 | call to FormValue | tst.go:35:14:35:20 | tainted | The $@ of this request depends on a $@. | tst.go:35:14:35:20 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:36:2:36:30 | call to PostForm | tst.go:10:13:10:35 | call to FormValue | tst.go:36:18:36:24 | tainted | The $@ of this request depends on a $@. | tst.go:36:18:36:24 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:38:2:38:30 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:38:11:38:29 | ...+... | The $@ of this request depends on a $@. | tst.go:38:11:38:29 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:40:2:40:41 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:40:11:40:40 | ...+... | The $@ of this request depends on a $@. | tst.go:40:11:40:40 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:48:2:48:21 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:48:11:48:20 | call to String | The $@ of this request depends on a $@. | tst.go:48:11:48:20 | call to String | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value |
| tst.go:19:2:19:18 | call to Get | tst.go:11:13:11:35 | call to FormValue | tst.go:19:11:19:17 | tainted | The $@ of this request depends on a $@. | tst.go:19:11:19:17 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:21:2:21:19 | call to Head | tst.go:11:13:11:35 | call to FormValue | tst.go:21:12:21:18 | tainted | The $@ of this request depends on a $@. | tst.go:21:12:21:18 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:23:2:23:38 | call to Post | tst.go:11:13:11:35 | call to FormValue | tst.go:23:12:23:18 | tainted | The $@ of this request depends on a $@. | tst.go:23:12:23:18 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:25:2:25:28 | call to PostForm | tst.go:11:13:11:35 | call to FormValue | tst.go:25:16:25:22 | tainted | The $@ of this request depends on a $@. | tst.go:25:16:25:22 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:29:2:29:15 | call to Do | tst.go:11:13:11:35 | call to FormValue | tst.go:28:35:28:41 | tainted | The $@ of this request depends on a $@. | tst.go:28:35:28:41 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:32:2:32:15 | call to Do | tst.go:11:13:11:35 | call to FormValue | tst.go:31:68:31:74 | tainted | The $@ of this request depends on a $@. | tst.go:31:68:31:74 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:34:2:34:20 | call to Get | tst.go:11:13:11:35 | call to FormValue | tst.go:34:13:34:19 | tainted | The $@ of this request depends on a $@. | tst.go:34:13:34:19 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:35:2:35:21 | call to Head | tst.go:11:13:11:35 | call to FormValue | tst.go:35:14:35:20 | tainted | The $@ of this request depends on a $@. | tst.go:35:14:35:20 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:36:2:36:40 | call to Post | tst.go:11:13:11:35 | call to FormValue | tst.go:36:14:36:20 | tainted | The $@ of this request depends on a $@. | tst.go:36:14:36:20 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:37:2:37:30 | call to PostForm | tst.go:11:13:11:35 | call to FormValue | tst.go:37:18:37:24 | tainted | The $@ of this request depends on a $@. | tst.go:37:18:37:24 | tainted | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:39:2:39:30 | call to Get | tst.go:11:13:11:35 | call to FormValue | tst.go:39:11:39:29 | ...+... | The $@ of this request depends on a $@. | tst.go:39:11:39:29 | ...+... | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:41:2:41:41 | call to Get | tst.go:11:13:11:35 | call to FormValue | tst.go:41:11:41:40 | ...+... | The $@ of this request depends on a $@. | tst.go:41:11:41:40 | ...+... | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| tst.go:49:2:49:21 | call to Get | tst.go:11:13:11:35 | call to FormValue | tst.go:49:11:49:20 | call to String | The $@ of this request depends on a $@. | tst.go:49:11:49:20 | call to String | URL | tst.go:11:13:11:35 | call to FormValue | user-provided value |
| 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 |
| 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 |
| 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 |
Expand All @@ -24,24 +24,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 |
edges
| RequestForgery.go:8:12:8:34 | call to FormValue | RequestForgery.go:11:24:11:65 | ...+... | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:18:11:18:17 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:20:12:20:18 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:22:12:22:18 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:24:16:24:22 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:27:35:27:41 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:30:68:30:74 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:33:13:33:19 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:34:14:34:20 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:35:14:35:20 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:36:18:36:24 | tainted | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:38:11:38:29 | ...+... | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:40:11:40:40 | ...+... | provenance | Src:MaD:1 |
| tst.go:10:13:10:35 | call to FormValue | tst.go:47:11:47:18 | tainted2 | provenance | Src:MaD:1 |
| tst.go:47:2:47:2 | implicit dereference [postupdate] | tst.go:47:2:47:2 | u [postupdate] | provenance | |
| tst.go:47:2:47:2 | u [postupdate] | tst.go:48:11:48:11 | u | provenance | |
| tst.go:47:11:47:18 | tainted2 | tst.go:47:2:47:2 | implicit dereference [postupdate] | provenance | Config |
| tst.go:47:11:47:18 | tainted2 | tst.go:47:2:47:2 | u [postupdate] | provenance | Config |
| tst.go:48:11:48:11 | u | tst.go:48:11:48:20 | call to String | provenance | MaD:3 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:19:11:19:17 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:21:12:21:18 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:23:12:23:18 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:25:16:25:22 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:28:35:28:41 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:31:68:31:74 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:34:13:34:19 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:35:14:35:20 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:36:14:36:20 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:37:18:37:24 | tainted | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:39:11:39:29 | ...+... | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:41:11:41:40 | ...+... | provenance | Src:MaD:1 |
| tst.go:11:13:11:35 | call to FormValue | tst.go:48:11:48:18 | tainted2 | provenance | Src:MaD:1 |
| tst.go:48:2:48:2 | implicit dereference [postupdate] | tst.go:48:2:48:2 | u [postupdate] | provenance | |
| tst.go:48:2:48:2 | u [postupdate] | tst.go:49:11:49:11 | u | provenance | |
| tst.go:48:11:48:18 | tainted2 | tst.go:48:2:48:2 | implicit dereference [postupdate] | provenance | Config |
| tst.go:48:11:48:18 | tainted2 | tst.go:48:2:48:2 | u [postupdate] | provenance | Config |
| tst.go:49:11:49:11 | u | tst.go:49:11:49:20 | call to String | provenance | MaD:3 |
| websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | provenance | Src:MaD:2 |
| websocket.go:74:21:74:31 | call to Referer | websocket.go:78:36:78:49 | untrustedInput | provenance | Src:MaD:2 |
| websocket.go:88:21:88:31 | call to Referer | websocket.go:91:31:91:44 | untrustedInput | provenance | Src:MaD:2 |
Expand All @@ -58,24 +58,24 @@ models
nodes
| RequestForgery.go:8:12:8:34 | call to FormValue | semmle.label | call to FormValue |
| RequestForgery.go:11:24:11:65 | ...+... | semmle.label | ...+... |
| tst.go:10:13:10:35 | call to FormValue | semmle.label | call to FormValue |
| tst.go:18:11:18:17 | tainted | semmle.label | tainted |
| tst.go:20:12:20:18 | tainted | semmle.label | tainted |
| tst.go:22:12:22:18 | tainted | semmle.label | tainted |
| tst.go:24:16:24:22 | tainted | semmle.label | tainted |
| tst.go:27:35:27:41 | tainted | semmle.label | tainted |
| tst.go:30:68:30:74 | tainted | semmle.label | tainted |
| tst.go:33:13:33:19 | tainted | semmle.label | tainted |
| tst.go:34:14:34:20 | tainted | semmle.label | tainted |
| tst.go:11:13:11:35 | call to FormValue | semmle.label | call to FormValue |
| tst.go:19:11:19:17 | tainted | semmle.label | tainted |
| tst.go:21:12:21:18 | tainted | semmle.label | tainted |
| tst.go:23:12:23:18 | tainted | semmle.label | tainted |
| tst.go:25:16:25:22 | tainted | semmle.label | tainted |
| tst.go:28:35:28:41 | tainted | semmle.label | tainted |
| tst.go:31:68:31:74 | tainted | semmle.label | tainted |
| tst.go:34:13:34:19 | tainted | semmle.label | tainted |
| tst.go:35:14:35:20 | tainted | semmle.label | tainted |
| tst.go:36:18:36:24 | tainted | semmle.label | tainted |
| tst.go:38:11:38:29 | ...+... | semmle.label | ...+... |
| tst.go:40:11:40:40 | ...+... | semmle.label | ...+... |
| tst.go:47:2:47:2 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
| tst.go:47:2:47:2 | u [postupdate] | semmle.label | u [postupdate] |
| tst.go:47:11:47:18 | tainted2 | semmle.label | tainted2 |
| tst.go:48:11:48:11 | u | semmle.label | u |
| tst.go:48:11:48:20 | call to String | semmle.label | call to String |
| tst.go:36:14:36:20 | tainted | semmle.label | tainted |
| tst.go:37:18:37:24 | tainted | semmle.label | tainted |
| tst.go:39:11:39:29 | ...+... | semmle.label | ...+... |
| tst.go:41:11:41:40 | ...+... | semmle.label | ...+... |
| tst.go:48:2:48:2 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
| tst.go:48:2:48:2 | u [postupdate] | semmle.label | u [postupdate] |
| tst.go:48:11:48:18 | tainted2 | semmle.label | tainted2 |
| tst.go:49:11:49:11 | u | semmle.label | u |
| tst.go:49:11:49:20 | call to String | semmle.label | call to String |
| websocket.go:60:21:60:31 | call to Referer | semmle.label | call to Referer |
| websocket.go:65:27:65:40 | untrustedInput | semmle.label | untrustedInput |
| websocket.go:74:21:74:31 | call to Referer | semmle.label | call to Referer |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["main", "", False, "intSource", "", "", "ReturnValue", "remote", "manual"]
9 changes: 9 additions & 0 deletions go/ql/test/query-tests/Security/CWE-918/tst.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"context"
"fmt"
"net/http"
"net/url"
)
Expand Down Expand Up @@ -46,8 +47,16 @@ func handler2(w http.ResponseWriter, req *http.Request) {
u, _ := url.Parse("http://example.com/relative-path")
u.Host = tainted2
http.Get(u.String()) // $ Alert

// Simple types are considered sanitized.
url := fmt.Sprintf("%s/%d", "some-url", intSource())
http.Get("http://" + url)
}

func main() {

}

func intSource() int64 {
return 0
}