mirror of
https://github.com/github/codeql.git
synced 2026-01-30 14:52:57 +01:00
Merge pull request #573 from npesaresi/feature/SSRF
Yet another SSRF query for Golang
This commit is contained in:
18
ql/src/experimental/CWE-918/SSRF.go
Normal file
18
ql/src/experimental/CWE-918/SSRF.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func handler(w http.ResponseWriter, req *http.Request) {
|
||||
target := req.FormValue("target")
|
||||
|
||||
// BAD: `target` is controlled by the attacker
|
||||
resp, err := http.Get("https://example.com/current_api/" + target)
|
||||
if err != nil {
|
||||
// error handling
|
||||
}
|
||||
|
||||
// process request response
|
||||
use(resp)
|
||||
}
|
||||
50
ql/src/experimental/CWE-918/SSRF.qhelp
Normal file
50
ql/src/experimental/CWE-918/SSRF.qhelp
Normal file
@@ -0,0 +1,50 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Directly incorporating user input into an HTTP request without validating the input can facilitate
|
||||
server side request forgery attacks, where the attacker controls the request target.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
To guard against server side request forgery, it is advisable to avoid putting user input directly into a
|
||||
network request. If using user input is necessary, then it must be validated. It is recommended to only allow
|
||||
user input consisting of alphanumeric characters. Simply URL-encoding other chracters is not always a solution,
|
||||
for example because a downstream entity that is itself vulnerable may decode again before forwarding the request.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
The following example shows an HTTP request parameter being used directly in a URL request without
|
||||
validating the input, which facilitates an SSRF attack. The request <code>http.Get("https://example.com/current_api/"+target)</code> is
|
||||
vulnerable since attackers can choose the value of <code>target</code> to be anything they want. For
|
||||
instance, the attacker can choose <code>"../super_secret_api"</code> as the target, causing the
|
||||
URL to become <code>"https://example.com/super_secret_api"</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A request to <code>https://example.com/super_secret_api</code> may be problematic if that api is not
|
||||
meant to be directly accessible from the attacker's machine.
|
||||
</p>
|
||||
|
||||
<sample src="SSRF.go"/>
|
||||
|
||||
<p>
|
||||
One way to remedy the problem is to validate the user input to only allow alphanumeric values:
|
||||
</p>
|
||||
|
||||
<sample src="SSRFGood.go"/>
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li>OWASP: <a href="https://www.owasp.org/www-community/attacks/Server_Side_Request_Forgery">SSRF</a></li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
21
ql/src/experimental/CWE-918/SSRF.ql
Normal file
21
ql/src/experimental/CWE-918/SSRF.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @name Uncontrolled data used in network request
|
||||
* @description Sending network requests with user-controlled data allows for request forgery attacks.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags security
|
||||
* external/cwe/cwe-918
|
||||
*/
|
||||
|
||||
import go
|
||||
import SSRF
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from
|
||||
ServerSideRequestForgery::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink,
|
||||
DataFlow::Node request
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
request = sink.getNode().(ServerSideRequestForgery::Sink).getARequest()
|
||||
select request, source, sink, "The URL of this request depends on a user-provided value"
|
||||
164
ql/src/experimental/CWE-918/SSRF.qll
Normal file
164
ql/src/experimental/CWE-918/SSRF.qll
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Provides a taint-tracking configuration for reasoning about request forgery
|
||||
* (SSRF) vulnerabilities.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
/**
|
||||
* Provides a taint-tracking configuration for reasoning about request forgery
|
||||
* (SSRF) vulnerabilities.
|
||||
*/
|
||||
module ServerSideRequestForgery {
|
||||
private import semmle.go.frameworks.Gin
|
||||
private import validator
|
||||
private import semmle.go.security.UrlConcatenation
|
||||
private import semmle.go.dataflow.barrierguardutil.RegexpCheck
|
||||
private import semmle.go.dataflow.Properties
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for reasoning about request forgery.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "SSRF" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
// propagate to a URL when its host is assigned to
|
||||
exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") |
|
||||
w.writesField(v.getAUse(), f, pred) and succ = v.getAUse()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node) {
|
||||
super.isSanitizerOut(node) or
|
||||
node instanceof SanitizerEdge
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
|
||||
super.isSanitizerGuard(guard) or guard instanceof SanitizerGuard
|
||||
}
|
||||
}
|
||||
|
||||
/** A data flow source for request forgery vulnerabilities. */
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
/** A data flow sink for request forgery vulnerabilities. */
|
||||
abstract class Sink extends DataFlow::Node {
|
||||
/** Gets a request that uses this sink. */
|
||||
abstract DataFlow::Node getARequest();
|
||||
|
||||
/**
|
||||
* Gets the name of a part of the request that may be tainted by this sink,
|
||||
* such as the URL or the host.
|
||||
*/
|
||||
abstract string getKind();
|
||||
}
|
||||
|
||||
/** A sanitizer for request forgery vulnerabilities. */
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** An outgoing sanitizer edge for request forgery vulnerabilities. */
|
||||
abstract class SanitizerEdge extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer guard for request forgery vulnerabilities.
|
||||
*/
|
||||
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
|
||||
|
||||
/**
|
||||
* An user controlled input, considered as a flow source for request forgery.
|
||||
*/
|
||||
class UntrustedFlowAsSource extends Source instanceof UntrustedFlowSource { }
|
||||
|
||||
/**
|
||||
* The URL of an HTTP request, viewed as a sink for request forgery.
|
||||
*/
|
||||
private class ClientRequestUrlAsSink extends Sink {
|
||||
HTTP::ClientRequest request;
|
||||
|
||||
ClientRequestUrlAsSink() { this = request.getUrl() }
|
||||
|
||||
override DataFlow::Node getARequest() { result = request }
|
||||
|
||||
override string getKind() { result = "URL" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of a WebSocket request, viewed as a sink for request forgery.
|
||||
*/
|
||||
class WebSocketCallAsSink extends Sink {
|
||||
WebSocketRequestCall request;
|
||||
|
||||
WebSocketCallAsSink() { this = request.getRequestUrl() }
|
||||
|
||||
override DataFlow::Node getARequest() { result = request }
|
||||
|
||||
override string getKind() { result = "WebSocket URL" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Result value of prepending a string that prevents any value from controlling the
|
||||
* host of a URL.
|
||||
*/
|
||||
private class PathSanitizer extends SanitizerEdge {
|
||||
PathSanitizer() { sanitizingPrefixEdge(this, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a regexp match function, considered as a barrier guard for sanitizing untrusted URLs.
|
||||
*
|
||||
* This is overapproximate: we do not attempt to reason about the correctness of the regexp.
|
||||
*/
|
||||
class RegexpCheckAsBarrierGuard extends RegexpCheck, SanitizerGuard { }
|
||||
|
||||
/**
|
||||
* An equality check comparing a data-flow node against a constant string, considered as
|
||||
* a barrier guard for sanitizing untrusted URLs.
|
||||
*/
|
||||
class EqualityAsSanitizerGuard extends SanitizerGuard, DataFlow::EqualityTestNode {
|
||||
DataFlow::Node url;
|
||||
|
||||
EqualityAsSanitizerGuard() {
|
||||
exists(this.getAnOperand().getStringValue()) and
|
||||
url = this.getAnOperand()
|
||||
}
|
||||
|
||||
override predicate checks(Expr e, boolean outcome) {
|
||||
e = url.asExpr() and outcome = this.getPolarity()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the tainted variable is a boolean or has numeric type is not possible to exploit a SSRF
|
||||
*/
|
||||
class NumSanitizer extends Sanitizer {
|
||||
NumSanitizer() {
|
||||
this.getType() instanceof NumericType or
|
||||
this.getType() instanceof BoolType
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When we receive a body from a request, we can use certain tags on our struct's fields to hint
|
||||
* the binding function to run some validations for that field. If these binding functions returns
|
||||
* no error, then we consider these fields safe for SSRF.
|
||||
*/
|
||||
class BodySanitizer extends Sanitizer instanceof CheckedAlphanumericStructFieldRead { }
|
||||
|
||||
/**
|
||||
* The method Var of package validator is a sanitizer guard only if the check
|
||||
* of the error binding exists, and the tag to check is one of "alpha", "alphanum", "alphaunicode", "alphanumunicode", "number", "numeric".
|
||||
*/
|
||||
class ValidatorAsSanitizer extends SanitizerGuard instanceof ValidatorVarCheck {
|
||||
override predicate checks(Expr e, boolean branch) { this.checks(e, branch) }
|
||||
}
|
||||
}
|
||||
20
ql/src/experimental/CWE-918/SSRFGood.go
Normal file
20
ql/src/experimental/CWE-918/SSRFGood.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/go-playground/validator"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func goodHandler(w http.ResponseWriter, req *http.Request) {
|
||||
validate := validator.New()
|
||||
target := req.FormValue("target")
|
||||
if validate.Var(target, "alphanum") == nil {
|
||||
// GOOD: `target` is alphanumeric
|
||||
resp, err := http.Get("https://example.com/current_api/" + target)
|
||||
if err != nil {
|
||||
// error handling
|
||||
}
|
||||
// process request response
|
||||
use(resp)
|
||||
}
|
||||
}
|
||||
159
ql/src/experimental/CWE-918/validator.qll
Normal file
159
ql/src/experimental/CWE-918/validator.qll
Normal file
@@ -0,0 +1,159 @@
|
||||
import go
|
||||
private import semmle.go.dataflow.Properties
|
||||
|
||||
/**
|
||||
* Holds if `validationKind` is a validation kind that restricts to alphanumeric characters,
|
||||
* which we consider safe for use in a URL.
|
||||
*/
|
||||
private predicate isAlphanumericValidationKind(string validationKind) {
|
||||
validationKind in [
|
||||
"alpha", "alphanum", "alphaunicode", "alphanumunicode", "number", "numeric", "uuid"
|
||||
]
|
||||
}
|
||||
|
||||
private string getKeyAndValuesRegex() { result = "([a-zA-Z0-9]+):\"([a-zA-Z0-9,]+)\"" }
|
||||
|
||||
/**
|
||||
* A struct field with json tags like `key:"value1,value2"`.
|
||||
*/
|
||||
class FieldWithTags extends FieldDecl {
|
||||
FieldWithTags() { this.getTag().toString().regexpMatch("`([a-zA-Z0-9]+:\"[a-zA-Z0-9,]+\" *)+`") }
|
||||
|
||||
/**
|
||||
* Holds if this field's tag maps `key` to `value`.
|
||||
* For example: the tag `json:"word" binding:"required,alpha"` yields `key: "json", value: "word"`
|
||||
* and `key: "binding" values: "required","alpha"`.
|
||||
*/
|
||||
predicate getTagByKeyValue(string key, string value) {
|
||||
exists(string tag, string key_value, string values |
|
||||
this.getTag().toString() = tag and
|
||||
// Each key_value is like key:"value1,value2"
|
||||
tag.regexpFind(getKeyAndValuesRegex(), _, _) = key_value and
|
||||
// key is the "key" from key:"value1,value2"
|
||||
key_value.regexpCapture(getKeyAndValuesRegex(), 1) = key and
|
||||
// values are the value1,value2 (without the quotation marks) from key:"value1,value2"
|
||||
key_value.regexpCapture(getKeyAndValuesRegex(), 2) = values and
|
||||
// value is value1 or value2 from key:"value1,value2"
|
||||
values.regexpFind("[a-zA-Z0-9]+", _, _) = value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node that reads from a field with a tag indicating it
|
||||
* must be alphanumeric (for example, having the tag `binding:"alpha"`).
|
||||
*/
|
||||
class AlphanumericStructFieldRead extends DataFlow::Node {
|
||||
string key;
|
||||
|
||||
AlphanumericStructFieldRead() {
|
||||
exists(FieldWithTags decl, Field field, string tag |
|
||||
this = field.getARead() and
|
||||
field.getDeclaration() = decl.getNameExpr(0) and
|
||||
decl.getTagByKeyValue(key, tag) and
|
||||
isAlphanumericValidationKind(tag)
|
||||
)
|
||||
}
|
||||
|
||||
string getKey() { result = key }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node that is considered safe because it (a) reads a field with a tag indicating it should be
|
||||
* alphanumeric, and (b) is guarded by a call to a validation function checking that it really
|
||||
* is alphanumeric.
|
||||
*
|
||||
* See `AlphanumericStructFieldRead` and `isAlphanumericValidationKind` for supported tags.
|
||||
* See `StructValidationFunction` for supported binding functions.
|
||||
*/
|
||||
class CheckedAlphanumericStructFieldRead extends AlphanumericStructFieldRead {
|
||||
CheckedAlphanumericStructFieldRead() {
|
||||
exists(StructValidationFunction guard, SelectorExpr selector |
|
||||
guard.getAGuardedNode().asExpr() = selector.getBase() and
|
||||
selector = this.asExpr() and
|
||||
this.getKey() = guard.getValidationKindKey()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that validates a struct, checking that fields conform to restrictions given as a tag.
|
||||
*
|
||||
* The Gin `Context.Bind` family of functions apply checks according to a `binding:` tag, and the
|
||||
* Go-Playground Validator checks fields that have a `validate:` tag.
|
||||
*/
|
||||
private class StructValidationFunction extends DataFlow::BarrierGuard, DataFlow::EqualityTestNode {
|
||||
Expr checked;
|
||||
boolean safeOutcome;
|
||||
string validationKindKey;
|
||||
|
||||
StructValidationFunction() {
|
||||
exists(Function bindFunction, DataFlow::CallNode bindCall, DataFlow::Node resultErr |
|
||||
(
|
||||
// Gin call
|
||||
bindFunction
|
||||
.(Method)
|
||||
.hasQualifiedName("github.com/gin-gonic/gin", "Context",
|
||||
[
|
||||
"BindJSON", "MustBindWith", "BindWith", "Bind", "ShouldBind", "ShouldBindBodyWith",
|
||||
"ShouldBindJSON", "ShouldBindWith"
|
||||
]) and
|
||||
validationKindKey = "binding"
|
||||
or
|
||||
// Validator Struct
|
||||
bindFunction
|
||||
.(Method)
|
||||
.hasQualifiedName("github.com/go-playground/validator", "Validate", "Struct") and
|
||||
validationKindKey = "validate"
|
||||
) and
|
||||
bindCall = bindFunction.getACall() and
|
||||
checked = dereference(bindCall.getAnArgument()) and
|
||||
resultErr = bindCall.getResult().getASuccessor*() and
|
||||
nilProperty().checkOn(this, safeOutcome, resultErr)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate checks(Expr e, boolean branch) { e = checked and branch = safeOutcome }
|
||||
|
||||
/**
|
||||
* Returns the struct tag key from which this validation function draws its validation kind.
|
||||
*
|
||||
* For example, if this returns `xyz` then this function looks for a struct tag like
|
||||
* `` mustBeNumeric string `xyz:"numeric"` ``
|
||||
*/
|
||||
string getValidationKindKey() { result = validationKindKey }
|
||||
}
|
||||
|
||||
/**
|
||||
* If `nd` is an address-of expression `&a`, returns expressions `&a` and `a`. Otherwise, returns `nd` as-is.
|
||||
*/
|
||||
private Expr dereference(DataFlow::Node nd) {
|
||||
nd.asExpr().(AddressExpr).getOperand() = result
|
||||
or
|
||||
nd.asExpr() = result
|
||||
}
|
||||
|
||||
/**
|
||||
* A validation performed by package `validator`'s method `Var` to check that an expression is
|
||||
* alphanumeric (see `isAlphanumericValidationKind` for more information) sanitizes guarded uses
|
||||
* of the same variable.
|
||||
*/
|
||||
class ValidatorVarCheck extends DataFlow::BarrierGuard, DataFlow::EqualityTestNode {
|
||||
DataFlow::CallNode callToValidator;
|
||||
boolean outcome;
|
||||
|
||||
ValidatorVarCheck() {
|
||||
exists(Method validatorMethod, DataFlow::Node resultErr |
|
||||
validatorMethod.hasQualifiedName("github.com/go-playground/validator", "Validate", "Var") and
|
||||
callToValidator = validatorMethod.getACall() and
|
||||
isAlphanumericValidationKind(callToValidator.getArgument(1).getStringValue()) and
|
||||
resultErr = callToValidator.getResult().getASuccessor*() and
|
||||
nilProperty().checkOn(this, outcome, resultErr)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate checks(Expr e, boolean branch) {
|
||||
callToValidator.getArgument(0).asExpr() = e and
|
||||
branch = outcome
|
||||
}
|
||||
}
|
||||
73
ql/test/experimental/CWE-918/SSRF.expected
Normal file
73
ql/test/experimental/CWE-918/SSRF.expected
Normal file
@@ -0,0 +1,73 @@
|
||||
edges
|
||||
| builtin.go:19:12:19:34 | call to FormValue : string | builtin.go:22:21:22:62 | ...+... |
|
||||
| builtin.go:83:21:83:31 | call to Referer : string | builtin.go:88:27:88:40 | untrustedInput |
|
||||
| builtin.go:97:21:97:31 | call to Referer : string | builtin.go:101:36:101:49 | untrustedInput |
|
||||
| builtin.go:111:21:111:31 | call to Referer : string | builtin.go:114:15:114:28 | untrustedInput |
|
||||
| builtin.go:129:21:129:31 | call to Referer : string | builtin.go:132:38:132:51 | untrustedInput |
|
||||
| new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:31:11:31:57 | call to Sprintf |
|
||||
| new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:32:11:32:57 | call to Sprintf |
|
||||
| new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf |
|
||||
| new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... |
|
||||
| new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... |
|
||||
| new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf |
|
||||
| new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf |
|
||||
| new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf |
|
||||
| new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... |
|
||||
| new-tests.go:81:37:81:43 | implicit dereference : URL | new-tests.go:81:37:81:43 | implicit dereference : URL |
|
||||
| new-tests.go:81:37:81:43 | implicit dereference : URL | new-tests.go:81:37:81:43 | selection of URL : pointer type |
|
||||
| new-tests.go:81:37:81:43 | implicit dereference : URL | new-tests.go:82:11:82:46 | ...+... |
|
||||
| new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:81:37:81:43 | implicit dereference : URL |
|
||||
| new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:81:37:81:43 | selection of URL : pointer type |
|
||||
| new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... |
|
||||
| new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... |
|
||||
| new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... |
|
||||
nodes
|
||||
| builtin.go:19:12:19:34 | call to FormValue : string | semmle.label | call to FormValue : string |
|
||||
| builtin.go:22:21:22:62 | ...+... | semmle.label | ...+... |
|
||||
| builtin.go:83:21:83:31 | call to Referer : string | semmle.label | call to Referer : string |
|
||||
| builtin.go:88:27:88:40 | untrustedInput | semmle.label | untrustedInput |
|
||||
| builtin.go:97:21:97:31 | call to Referer : string | semmle.label | call to Referer : string |
|
||||
| builtin.go:101:36:101:49 | untrustedInput | semmle.label | untrustedInput |
|
||||
| builtin.go:111:21:111:31 | call to Referer : string | semmle.label | call to Referer : string |
|
||||
| builtin.go:114:15:114:28 | untrustedInput | semmle.label | untrustedInput |
|
||||
| builtin.go:129:21:129:31 | call to Referer : string | semmle.label | call to Referer : string |
|
||||
| builtin.go:132:38:132:51 | untrustedInput | semmle.label | untrustedInput |
|
||||
| new-tests.go:26:26:26:30 | &... : pointer type | semmle.label | &... : pointer type |
|
||||
| new-tests.go:31:11:31:57 | call to Sprintf | semmle.label | call to Sprintf |
|
||||
| new-tests.go:32:11:32:57 | call to Sprintf | semmle.label | call to Sprintf |
|
||||
| new-tests.go:35:12:35:58 | call to Sprintf | semmle.label | call to Sprintf |
|
||||
| new-tests.go:39:18:39:30 | call to Param : string | semmle.label | call to Param : string |
|
||||
| new-tests.go:47:11:47:46 | ...+... | semmle.label | ...+... |
|
||||
| new-tests.go:49:18:49:30 | call to Query : string | semmle.label | call to Query : string |
|
||||
| new-tests.go:50:11:50:46 | ...+... | semmle.label | ...+... |
|
||||
| new-tests.go:62:31:62:38 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser |
|
||||
| new-tests.go:68:11:68:57 | call to Sprintf | semmle.label | call to Sprintf |
|
||||
| new-tests.go:69:11:69:57 | call to Sprintf | semmle.label | call to Sprintf |
|
||||
| new-tests.go:74:12:74:58 | call to Sprintf | semmle.label | call to Sprintf |
|
||||
| new-tests.go:78:18:78:24 | selection of URL : pointer type | semmle.label | selection of URL : pointer type |
|
||||
| new-tests.go:79:11:79:46 | ...+... | semmle.label | ...+... |
|
||||
| new-tests.go:81:37:81:43 | implicit dereference : URL | semmle.label | implicit dereference : URL |
|
||||
| new-tests.go:81:37:81:43 | selection of URL : pointer type | semmle.label | selection of URL : pointer type |
|
||||
| new-tests.go:82:11:82:46 | ...+... | semmle.label | ...+... |
|
||||
| new-tests.go:86:10:86:20 | call to Vars : map type | semmle.label | call to Vars : map type |
|
||||
| new-tests.go:88:11:88:46 | ...+... | semmle.label | ...+... |
|
||||
| new-tests.go:95:18:95:45 | call to URLParam : string | semmle.label | call to URLParam : string |
|
||||
| new-tests.go:96:11:96:46 | ...+... | semmle.label | ...+... |
|
||||
#select
|
||||
| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue : string | 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 : string | 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 : string | 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 : string | 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 : string | builtin.go:132:38:132:51 | untrustedInput | 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 | &... : pointer type | 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 | &... : pointer type | 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 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value |
|
||||
| new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value |
|
||||
| new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value |
|
||||
| new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value |
|
||||
| new-tests.go:69:2:69:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | The URL of this request depends on a user-provided value |
|
||||
| new-tests.go:74:3:74:59 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | The URL of this request depends on a user-provided value |
|
||||
| new-tests.go:79:2:79:47 | call to Get | new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | The URL of this request depends on a user-provided value |
|
||||
| new-tests.go:82:2:82:47 | call to Get | new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | The URL of this request depends on a user-provided value |
|
||||
| new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars : map type | 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 : string | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value |
|
||||
1
ql/test/experimental/CWE-918/SSRF.qlref
Normal file
1
ql/test/experimental/CWE-918/SSRF.qlref
Normal file
@@ -0,0 +1 @@
|
||||
experimental/CWE-918/SSRF.ql
|
||||
147
ql/test/experimental/CWE-918/builtin.go
Normal file
147
ql/test/experimental/CWE-918/builtin.go
Normal file
@@ -0,0 +1,147 @@
|
||||
package main
|
||||
|
||||
//go:generate depstubber -vendor github.com/gorilla/websocket Dialer
|
||||
//go:generate depstubber -vendor golang.org/x/net/websocket "" Dial,NewConfig,DialConfig
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
gorilla "github.com/gorilla/websocket"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
func handler(w http.ResponseWriter, req *http.Request) {
|
||||
target := req.FormValue("target")
|
||||
|
||||
// BAD: `target` is controlled by the attacker
|
||||
_, err := http.Get("https://" + target + ".example.com/data/")
|
||||
if err != nil {
|
||||
// error handling
|
||||
}
|
||||
// process request response
|
||||
}
|
||||
|
||||
func handler1(w http.ResponseWriter, req *http.Request) {
|
||||
target := req.FormValue("target")
|
||||
|
||||
var subdomain string
|
||||
if target == "EU" {
|
||||
subdomain = "europe"
|
||||
} else {
|
||||
subdomain = "world"
|
||||
}
|
||||
|
||||
// GOOD: `subdomain` is controlled by the server
|
||||
_, err := http.Get("https://" + subdomain + ".example.com/data/")
|
||||
if err != nil {
|
||||
// error handling
|
||||
}
|
||||
// process request response
|
||||
}
|
||||
|
||||
func test() {
|
||||
|
||||
http.HandleFunc("/ex0", func(w http.ResponseWriter, r *http.Request) {
|
||||
untrustedInput := r.Referer()
|
||||
|
||||
origin := "http://localhost/"
|
||||
|
||||
untrustedInputTrimmed := strings.TrimRight(untrustedInput, "\n\r")
|
||||
if untrustedInputTrimmed == "ws://localhost:12345/ws" {
|
||||
// good as input is checked against fixed set of urls.
|
||||
ws, _ := websocket.Dial(untrustedInputTrimmed, "", origin) // OK
|
||||
var msg = make([]byte, 512)
|
||||
var n int
|
||||
n, _ = ws.Read(msg)
|
||||
fmt.Printf("Received: %s.\n", msg[:n])
|
||||
}
|
||||
})
|
||||
|
||||
// x net websocket DialConfig good
|
||||
http.HandleFunc("/ex1", func(w http.ResponseWriter, r *http.Request) {
|
||||
untrustedInput := r.Referer()
|
||||
|
||||
origin := "http://localhost/"
|
||||
// good as input is tested against a regex
|
||||
if m, _ := regexp.MatchString("ws://localhost:12345/*", untrustedInput); m {
|
||||
config, _ := websocket.NewConfig(untrustedInput, origin) // OK? Regex
|
||||
ws2, _ := websocket.DialConfig(config)
|
||||
var msg = make([]byte, 512)
|
||||
var n int
|
||||
n, _ = ws2.Read(msg)
|
||||
fmt.Printf("Received: %s.\n", msg[:n])
|
||||
}
|
||||
})
|
||||
|
||||
// x net websocket dial bad
|
||||
http.HandleFunc("/ex2", func(w http.ResponseWriter, r *http.Request) {
|
||||
untrustedInput := r.Referer()
|
||||
|
||||
origin := "http://localhost/"
|
||||
|
||||
// bad as input is directly passed to dial function
|
||||
ws, _ := websocket.Dial(untrustedInput, "", origin) // SSRF
|
||||
var msg = make([]byte, 512)
|
||||
var n int
|
||||
n, _ = ws.Read(msg)
|
||||
fmt.Printf("Received: %s.\n", msg[:n])
|
||||
})
|
||||
|
||||
// x net websocket dialConfig bad
|
||||
http.HandleFunc("/ex3", func(w http.ResponseWriter, r *http.Request) {
|
||||
untrustedInput := r.Referer()
|
||||
|
||||
origin := "http://localhost/"
|
||||
// bad as input is directly used
|
||||
config, _ := websocket.NewConfig(untrustedInput, origin) // SSRF
|
||||
ws2, _ := websocket.DialConfig(config)
|
||||
var msg = make([]byte, 512)
|
||||
var n int
|
||||
n, _ = ws2.Read(msg)
|
||||
fmt.Printf("Received: %s.\n", msg[:n])
|
||||
})
|
||||
|
||||
// gorilla websocket Dialer.Dial bad
|
||||
http.HandleFunc("/ex6", func(w http.ResponseWriter, r *http.Request) {
|
||||
untrustedInput := r.Referer()
|
||||
|
||||
dialer := gorilla.Dialer{}
|
||||
dialer.Dial(untrustedInput, r.Header) //SSRF
|
||||
})
|
||||
|
||||
// gorilla websocket Dialer.Dial good
|
||||
http.HandleFunc("/ex7", func(w http.ResponseWriter, r *http.Request) {
|
||||
untrustedInput := r.Referer()
|
||||
|
||||
if untrustedInput == "localhost" {
|
||||
dialer := gorilla.Dialer{}
|
||||
dialer.Dial(untrustedInput, r.Header) //OK
|
||||
}
|
||||
})
|
||||
|
||||
// gorilla websocket Dialer.DialContext bad
|
||||
http.HandleFunc("/ex8", func(w http.ResponseWriter, r *http.Request) {
|
||||
untrustedInput := r.Referer()
|
||||
|
||||
dialer := gorilla.Dialer{}
|
||||
dialer.DialContext(context.TODO(), untrustedInput, r.Header) //SSRF
|
||||
})
|
||||
|
||||
// gorilla websocket Dialer.DialContext good
|
||||
http.HandleFunc("/ex9", func(w http.ResponseWriter, r *http.Request) {
|
||||
untrustedInput := r.Referer()
|
||||
|
||||
if untrustedInput == "localhost" {
|
||||
dialer := gorilla.Dialer{}
|
||||
dialer.DialContext(context.TODO(), untrustedInput, r.Header) //OK
|
||||
}
|
||||
})
|
||||
|
||||
log.Println(http.ListenAndServe(":80", nil))
|
||||
|
||||
}
|
||||
15
ql/test/experimental/CWE-918/go.mod
Normal file
15
ql/test/experimental/CWE-918/go.mod
Normal file
@@ -0,0 +1,15 @@
|
||||
module github.com/mercadolibre/fury_opensource-codeql/go/test/SSRF
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-chi/chi v4.1.2+incompatible
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/stretchr/testify v1.6.0 // indirect
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
)
|
||||
100
ql/test/experimental/CWE-918/new-tests.go
Normal file
100
ql/test/experimental/CWE-918/new-tests.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-playground/validator"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func HandlerGin(c *gin.Context) {
|
||||
var body struct {
|
||||
integer int
|
||||
float float32
|
||||
boolean bool
|
||||
word string
|
||||
safe string `binding:"alphanum"`
|
||||
}
|
||||
|
||||
err := c.ShouldBindJSON(&body)
|
||||
|
||||
http.Get(fmt.Sprintf("http://example.com/%d", body.integer)) // OK
|
||||
http.Get(fmt.Sprintf("http://example.com/%v", body.float)) // OK
|
||||
http.Get(fmt.Sprintf("http://example.com/%v", body.boolean)) // OK
|
||||
http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // SSRF
|
||||
http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // SSRF
|
||||
|
||||
if err == nil {
|
||||
http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // SSRF
|
||||
http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // OK
|
||||
}
|
||||
|
||||
taintedParam := c.Param("id")
|
||||
|
||||
validate := validator.New()
|
||||
err = validate.Var(taintedParam, "alpha")
|
||||
if err == nil {
|
||||
http.Get("http://example.com/" + taintedParam) // OK
|
||||
}
|
||||
|
||||
http.Get("http://example.com/" + taintedParam) //SSRF
|
||||
|
||||
taintedQuery := c.Query("id")
|
||||
http.Get("http://example.com/" + taintedQuery) //SSRF
|
||||
}
|
||||
|
||||
func HandlerHttp(req *http.Request) {
|
||||
//HTTP
|
||||
var body struct {
|
||||
integer int
|
||||
float float32
|
||||
boolean bool
|
||||
word string
|
||||
safe string `validate:"alphanum"`
|
||||
}
|
||||
reqBody, _ := ioutil.ReadAll(req.Body)
|
||||
json.Unmarshal(reqBody, &body)
|
||||
|
||||
http.Get(fmt.Sprintf("http://example.com/%d", body.integer)) // OK
|
||||
http.Get(fmt.Sprintf("http://example.com/%v", body.float)) // OK
|
||||
http.Get(fmt.Sprintf("http://example.com/%v", body.boolean)) // OK
|
||||
http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // SSRF
|
||||
http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // SSRF
|
||||
|
||||
validate := validator.New()
|
||||
err := validate.Struct(body)
|
||||
if err == nil {
|
||||
http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // SSRF
|
||||
http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // OK
|
||||
}
|
||||
|
||||
taintedQuery := req.URL.Query().Get("param1")
|
||||
http.Get("http://example.com/" + taintedQuery) // SSRF
|
||||
|
||||
taintedParam := strings.TrimPrefix(req.URL.Path, "/example-path/")
|
||||
http.Get("http://example.com/" + taintedParam) // SSRF
|
||||
}
|
||||
|
||||
func HandlerMux(r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
taintedParam := vars["id"]
|
||||
http.Get("http://example.com/" + taintedParam) // SSRF
|
||||
|
||||
numericID, _ := strconv.Atoi(taintedParam)
|
||||
http.Get(fmt.Sprintf("http://example.com/%d", numericID)) // OK
|
||||
}
|
||||
|
||||
func HandlerChi(r *http.Request) {
|
||||
taintedParam := chi.URLParam(r, "articleID")
|
||||
http.Get("http://example.com/" + taintedParam) // SSRF
|
||||
|
||||
b, _ := strconv.ParseBool(taintedParam)
|
||||
http.Get(fmt.Sprintf("http://example.com/%t", b)) // OK
|
||||
}
|
||||
436
ql/test/experimental/CWE-918/vendor/github.com/gin-gonic/gin/stub.go
generated
vendored
Normal file
436
ql/test/experimental/CWE-918/vendor/github.com/gin-gonic/gin/stub.go
generated
vendored
Normal file
@@ -0,0 +1,436 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/gin-gonic/gin, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/gin-gonic/gin (exports: Context; functions: )
|
||||
|
||||
// Package gin is a stub of github.com/gin-gonic/gin, generated by depstubber.
|
||||
package gin
|
||||
|
||||
import (
|
||||
bufio "bufio"
|
||||
io "io"
|
||||
multipart "mime/multipart"
|
||||
net "net"
|
||||
http "net/http"
|
||||
time "time"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
Request *http.Request
|
||||
Writer ResponseWriter
|
||||
Params Params
|
||||
Keys map[string]interface{}
|
||||
Errors interface{}
|
||||
Accepted []string
|
||||
}
|
||||
|
||||
func (_ *Context) Abort() {}
|
||||
|
||||
func (_ *Context) AbortWithError(_ int, _ error) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) AbortWithStatus(_ int) {}
|
||||
|
||||
func (_ *Context) AbortWithStatusJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) AsciiJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Bind(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindHeader(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindJSON(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindQuery(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindUri(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindXML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindYAML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ClientIP() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) ContentType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Cookie(_ string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ *Context) Copy() *Context {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Data(_ int, _ string, _ []byte) {}
|
||||
|
||||
func (_ *Context) DataFromReader(_ int, _ int64, _ string, _ io.Reader, _ map[string]string) {}
|
||||
|
||||
func (_ *Context) Deadline() (time.Time, bool) {
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
func (_ *Context) DefaultPostForm(_ string, _ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) DefaultQuery(_ string, _ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Done() <-chan struct{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Err() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Error(_ error) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) File(_ string) {}
|
||||
|
||||
func (_ *Context) FileAttachment(_ string, _ string) {}
|
||||
|
||||
func (_ *Context) FileFromFS(_ string, _ http.FileSystem) {}
|
||||
|
||||
func (_ *Context) FormFile(_ string) (*multipart.FileHeader, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Context) FullPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Get(_ string) (interface{}, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetBool(_ string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) GetDuration(_ string) time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetFloat64(_ string) float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetHeader(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) GetInt(_ string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetInt64(_ string) int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetPostForm(_ string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (_ *Context) GetPostFormArray(_ string) ([]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetPostFormMap(_ string) (map[string]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetQuery(_ string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (_ *Context) GetQueryArray(_ string) ([]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetQueryMap(_ string) (map[string]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetRawData() ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetString(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringMap(_ string) map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringMapString(_ string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringMapStringSlice(_ string) map[string][]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringSlice(_ string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetTime(_ string) time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (_ *Context) HTML(_ int, _ string, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Handler() HandlerFunc {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) HandlerName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) HandlerNames() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Header(_ string, _ string) {}
|
||||
|
||||
func (_ *Context) IndentedJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) IsAborted() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) IsWebsocket() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) JSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) JSONP(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) MultipartForm() (*multipart.Form, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Context) MustBindWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) MustGet(_ string) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Negotiate(_ int, _ Negotiate) {}
|
||||
|
||||
func (_ *Context) NegotiateFormat(_ ...string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Next() {}
|
||||
|
||||
func (_ *Context) Param(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) PostForm(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) PostFormArray(_ string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) PostFormMap(_ string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ProtoBuf(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) PureJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Query(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) QueryArray(_ string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) QueryMap(_ string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Redirect(_ int, _ string) {}
|
||||
|
||||
func (_ *Context) Render(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) SSEvent(_ string, _ interface{}) {}
|
||||
|
||||
func (_ *Context) SaveUploadedFile(_ *multipart.FileHeader, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) SecureJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Set(_ string, _ interface{}) {}
|
||||
|
||||
func (_ *Context) SetAccepted(_ ...string) {}
|
||||
|
||||
func (_ *Context) SetCookie(_ string, _ string, _ int, _ string, _ string, _ bool, _ bool) {}
|
||||
|
||||
func (_ *Context) SetSameSite(_ http.SameSite) {}
|
||||
|
||||
func (_ *Context) ShouldBind(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindBodyWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindHeader(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindJSON(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindQuery(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindUri(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindXML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindYAML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Status(_ int) {}
|
||||
|
||||
func (_ *Context) Stream(_ func(io.Writer) bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) String(_ int, _ string, _ ...interface{}) {}
|
||||
|
||||
func (_ *Context) Value(_ interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) XML(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) YAML(_ int, _ interface{}) {}
|
||||
|
||||
type Error struct {
|
||||
Err error
|
||||
Type ErrorType
|
||||
Meta interface{}
|
||||
}
|
||||
|
||||
func (_ Error) Error() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Error) IsType(_ ErrorType) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Error) JSON() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Error) MarshalJSON() ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Error) SetMeta(_ interface{}) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Error) SetType(_ ErrorType) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ErrorType uint64
|
||||
|
||||
type HandlerFunc func(*Context)
|
||||
|
||||
type Negotiate struct {
|
||||
Offered []string
|
||||
HTMLName string
|
||||
HTMLData interface{}
|
||||
JSONData interface{}
|
||||
XMLData interface{}
|
||||
YAMLData interface{}
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
type Param struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
type Params []Param
|
||||
|
||||
func (_ Params) ByName(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ Params) Get(_ string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
type ResponseWriter interface {
|
||||
CloseNotify() <-chan bool
|
||||
Flush()
|
||||
Header() http.Header
|
||||
Hijack() (net.Conn, *bufio.ReadWriter, error)
|
||||
Pusher() http.Pusher
|
||||
Size() int
|
||||
Status() int
|
||||
Write(_ []byte) (int, error)
|
||||
WriteHeader(_ int)
|
||||
WriteHeaderNow()
|
||||
WriteString(_ string) (int, error)
|
||||
Written() bool
|
||||
}
|
||||
16
ql/test/experimental/CWE-918/vendor/github.com/go-chi/chi/stub.go
generated
vendored
Normal file
16
ql/test/experimental/CWE-918/vendor/github.com/go-chi/chi/stub.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/go-chi/chi, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/go-chi/chi (exports: ; functions: URLParam)
|
||||
|
||||
// Package chi is a stub of github.com/go-chi/chi, generated by depstubber.
|
||||
package chi
|
||||
|
||||
import (
|
||||
http "net/http"
|
||||
)
|
||||
|
||||
func URLParam(_ *http.Request, _ string) string {
|
||||
return ""
|
||||
}
|
||||
160
ql/test/experimental/CWE-918/vendor/github.com/go-playground/validator/stub.go
generated
vendored
Normal file
160
ql/test/experimental/CWE-918/vendor/github.com/go-playground/validator/stub.go
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/go-playground/validator, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/go-playground/validator (exports: Validate; functions: New)
|
||||
|
||||
// Package validator is a stub of github.com/go-playground/validator, generated by depstubber.
|
||||
package validator
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
type CustomTypeFunc func(reflect.Value) interface{}
|
||||
|
||||
type FieldError interface {
|
||||
ActualTag() string
|
||||
Field() string
|
||||
Kind() reflect.Kind
|
||||
Namespace() string
|
||||
Param() string
|
||||
StructField() string
|
||||
StructNamespace() string
|
||||
Tag() string
|
||||
Translate(_ interface{}) string
|
||||
Type() reflect.Type
|
||||
Value() interface{}
|
||||
}
|
||||
|
||||
type FieldLevel interface {
|
||||
ExtractType(_ reflect.Value) (reflect.Value, reflect.Kind, bool)
|
||||
Field() reflect.Value
|
||||
FieldName() string
|
||||
GetStructFieldOK() (reflect.Value, reflect.Kind, bool)
|
||||
GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool)
|
||||
GetStructFieldOKAdvanced(_ reflect.Value, _ string) (reflect.Value, reflect.Kind, bool)
|
||||
GetStructFieldOKAdvanced2(_ reflect.Value, _ string) (reflect.Value, reflect.Kind, bool, bool)
|
||||
GetTag() string
|
||||
Param() string
|
||||
Parent() reflect.Value
|
||||
StructFieldName() string
|
||||
Top() reflect.Value
|
||||
}
|
||||
|
||||
type FilterFunc func([]byte) bool
|
||||
|
||||
type Func func(FieldLevel) bool
|
||||
|
||||
type FuncCtx func(context.Context, FieldLevel) bool
|
||||
|
||||
func New() *Validate {
|
||||
return nil
|
||||
}
|
||||
|
||||
type RegisterTranslationsFunc func(interface{}) error
|
||||
|
||||
type StructLevel interface {
|
||||
Current() reflect.Value
|
||||
ExtractType(_ reflect.Value) (reflect.Value, reflect.Kind, bool)
|
||||
Parent() reflect.Value
|
||||
ReportError(_ interface{}, _ string, _ string, _ string, _ string)
|
||||
ReportValidationErrors(_ string, _ string, _ ValidationErrors)
|
||||
Top() reflect.Value
|
||||
Validator() *Validate
|
||||
}
|
||||
|
||||
type StructLevelFunc func(StructLevel)
|
||||
|
||||
type StructLevelFuncCtx func(context.Context, StructLevel)
|
||||
|
||||
type TagNameFunc func(reflect.StructField) string
|
||||
|
||||
type TranslationFunc func(interface{}, FieldError) string
|
||||
|
||||
type Validate struct{}
|
||||
|
||||
func (_ *Validate) RegisterAlias(_ string, _ string) {}
|
||||
|
||||
func (_ *Validate) RegisterCustomTypeFunc(_ CustomTypeFunc, _ ...interface{}) {}
|
||||
|
||||
func (_ *Validate) RegisterStructValidation(_ StructLevelFunc, _ ...interface{}) {}
|
||||
|
||||
func (_ *Validate) RegisterStructValidationCtx(_ StructLevelFuncCtx, _ ...interface{}) {}
|
||||
|
||||
func (_ *Validate) RegisterTagNameFunc(_ TagNameFunc) {}
|
||||
|
||||
func (_ *Validate) RegisterTranslation(_ string, _ interface{}, _ RegisterTranslationsFunc, _ TranslationFunc) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) RegisterValidation(_ string, _ Func, _ ...bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) RegisterValidationCtx(_ string, _ FuncCtx, _ ...bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) SetTagName(_ string) {}
|
||||
|
||||
func (_ *Validate) Struct(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) StructCtx(_ context.Context, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) StructExcept(_ interface{}, _ ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) StructExceptCtx(_ context.Context, _ interface{}, _ ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) StructFiltered(_ interface{}, _ FilterFunc) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) StructFilteredCtx(_ context.Context, _ interface{}, _ FilterFunc) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) StructPartial(_ interface{}, _ ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) StructPartialCtx(_ context.Context, _ interface{}, _ ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) Var(_ interface{}, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) VarCtx(_ context.Context, _ interface{}, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) VarWithValue(_ interface{}, _ interface{}, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validate) VarWithValueCtx(_ context.Context, _ interface{}, _ interface{}, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ValidationErrors []FieldError
|
||||
|
||||
func (_ ValidationErrors) Error() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ ValidationErrors) Translate(_ interface{}) ValidationErrorsTranslations {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ValidationErrorsTranslations map[string]string
|
||||
252
ql/test/experimental/CWE-918/vendor/github.com/gorilla/mux/stub.go
generated
vendored
Normal file
252
ql/test/experimental/CWE-918/vendor/github.com/gorilla/mux/stub.go
generated
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/gorilla/mux, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/gorilla/mux (exports: ; functions: Vars,NewRouter)
|
||||
|
||||
// Package mux is a stub of github.com/gorilla/mux, generated by depstubber.
|
||||
package mux
|
||||
|
||||
import (
|
||||
http "net/http"
|
||||
url "net/url"
|
||||
)
|
||||
|
||||
type BuildVarsFunc func(map[string]string) map[string]string
|
||||
|
||||
type MatcherFunc func(*http.Request, *RouteMatch) bool
|
||||
|
||||
func (_ MatcherFunc) Match(_ *http.Request, _ *RouteMatch) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type MiddlewareFunc func(http.Handler) http.Handler
|
||||
|
||||
func (_ MiddlewareFunc) Middleware(_ http.Handler) http.Handler {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewRouter() *Router {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Route struct{}
|
||||
|
||||
func (_ *Route) BuildOnly() *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) BuildVarsFunc(_ BuildVarsFunc) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) GetError() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) GetHandler() http.Handler {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) GetHostTemplate() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ *Route) GetMethods() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Route) GetName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Route) GetPathRegexp() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ *Route) GetPathTemplate() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ *Route) GetQueriesRegexp() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Route) GetQueriesTemplates() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Route) Handler(_ http.Handler) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) HandlerFunc(_ func(http.ResponseWriter, *http.Request)) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) Headers(_ ...string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) HeadersRegexp(_ ...string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) Host(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) Match(_ *http.Request, _ *RouteMatch) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Route) MatcherFunc(_ MatcherFunc) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) Methods(_ ...string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) Name(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) Path(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) PathPrefix(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) Queries(_ ...string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) Schemes(_ ...string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) SkipClean() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Route) Subrouter() *Router {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Route) URL(_ ...string) (*url.URL, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Route) URLHost(_ ...string) (*url.URL, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Route) URLPath(_ ...string) (*url.URL, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type RouteMatch struct {
|
||||
Route *Route
|
||||
Handler http.Handler
|
||||
Vars map[string]string
|
||||
MatchErr error
|
||||
}
|
||||
|
||||
type Router struct {
|
||||
NotFoundHandler http.Handler
|
||||
MethodNotAllowedHandler http.Handler
|
||||
KeepContext bool
|
||||
}
|
||||
|
||||
func (_ *Router) BuildVarsFunc(_ BuildVarsFunc) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Get(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) GetRoute(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Handle(_ string, _ http.Handler) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) HandleFunc(_ string, _ func(http.ResponseWriter, *http.Request)) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Headers(_ ...string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Host(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Match(_ *http.Request, _ *RouteMatch) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Router) MatcherFunc(_ MatcherFunc) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Methods(_ ...string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Name(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) NewRoute() *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Path(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) PathPrefix(_ string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Queries(_ ...string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Schemes(_ ...string) *Route {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {}
|
||||
|
||||
func (_ *Router) SkipClean(_ bool) *Router {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) StrictSlash(_ bool) *Router {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Use(_ ...MiddlewareFunc) {}
|
||||
|
||||
func (_ *Router) UseEncodedPath() *Router {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Router) Walk(_ WalkFunc) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Vars(_ *http.Request) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
type WalkFunc func(*Route, *Router, []*Route) error
|
||||
135
ql/test/experimental/CWE-918/vendor/github.com/gorilla/websocket/stub.go
generated
vendored
Normal file
135
ql/test/experimental/CWE-918/vendor/github.com/gorilla/websocket/stub.go
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/gorilla/websocket, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/gorilla/websocket (exports: Dialer; functions: )
|
||||
|
||||
// Package websocket is a stub of github.com/gorilla/websocket, generated by depstubber.
|
||||
package websocket
|
||||
|
||||
import (
|
||||
context "context"
|
||||
tls "crypto/tls"
|
||||
io "io"
|
||||
net "net"
|
||||
http "net/http"
|
||||
url "net/url"
|
||||
time "time"
|
||||
)
|
||||
|
||||
type BufferPool interface {
|
||||
Get() interface{}
|
||||
Put(_ interface{})
|
||||
}
|
||||
|
||||
type Conn struct{}
|
||||
|
||||
func (_ *Conn) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) CloseHandler() func(int, string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) EnableWriteCompression(_ bool) {}
|
||||
|
||||
func (_ *Conn) LocalAddr() net.Addr {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) NextReader() (int, io.Reader, error) {
|
||||
return 0, nil, nil
|
||||
}
|
||||
|
||||
func (_ *Conn) NextWriter(_ int) (io.WriteCloser, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Conn) PingHandler() func(string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) PongHandler() func(string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) ReadJSON(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) ReadMessage() (int, []byte, error) {
|
||||
return 0, nil, nil
|
||||
}
|
||||
|
||||
func (_ *Conn) RemoteAddr() net.Addr {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) SetCloseHandler(_ func(int, string) error) {}
|
||||
|
||||
func (_ *Conn) SetCompressionLevel(_ int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) SetPingHandler(_ func(string) error) {}
|
||||
|
||||
func (_ *Conn) SetPongHandler(_ func(string) error) {}
|
||||
|
||||
func (_ *Conn) SetReadDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) SetReadLimit(_ int64) {}
|
||||
|
||||
func (_ *Conn) SetWriteDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) Subprotocol() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Conn) UnderlyingConn() net.Conn {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) WriteControl(_ int, _ []byte, _ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) WriteJSON(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) WriteMessage(_ int, _ []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) WritePreparedMessage(_ *PreparedMessage) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Dialer struct {
|
||||
NetDial func(string, string) (net.Conn, error)
|
||||
NetDialContext func(context.Context, string, string) (net.Conn, error)
|
||||
Proxy func(*http.Request) (*url.URL, error)
|
||||
TLSClientConfig *tls.Config
|
||||
HandshakeTimeout time.Duration
|
||||
ReadBufferSize int
|
||||
WriteBufferSize int
|
||||
WriteBufferPool BufferPool
|
||||
Subprotocols []string
|
||||
EnableCompression bool
|
||||
Jar http.CookieJar
|
||||
}
|
||||
|
||||
func (_ *Dialer) Dial(_ string, _ http.Header) (*Conn, *http.Response, error) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
func (_ *Dialer) DialContext(_ context.Context, _ string, _ http.Header) (*Conn, *http.Response, error) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
type PreparedMessage struct{}
|
||||
120
ql/test/experimental/CWE-918/vendor/golang.org/x/net/websocket/stub.go
generated
vendored
Normal file
120
ql/test/experimental/CWE-918/vendor/golang.org/x/net/websocket/stub.go
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for golang.org/x/net/websocket, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: golang.org/x/net/websocket (exports: ; functions: Dial,NewConfig,DialConfig)
|
||||
|
||||
// Package websocket is a stub of golang.org/x/net/websocket, generated by depstubber.
|
||||
package websocket
|
||||
|
||||
import (
|
||||
tls "crypto/tls"
|
||||
io "io"
|
||||
net "net"
|
||||
http "net/http"
|
||||
url "net/url"
|
||||
time "time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Location *url.URL
|
||||
Origin *url.URL
|
||||
Protocol []string
|
||||
Version int
|
||||
TlsConfig *tls.Config
|
||||
Header http.Header
|
||||
Dialer *net.Dialer
|
||||
}
|
||||
|
||||
type Conn struct {
|
||||
PayloadType byte
|
||||
MaxPayloadBytes int
|
||||
}
|
||||
|
||||
func (_ Conn) HandleFrame(_ interface{}) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ Conn) HeaderReader() io.Reader {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ Conn) Len() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ Conn) NewFrameReader() (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ Conn) NewFrameWriter(_ byte) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ Conn) TrailerReader() io.Reader {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ Conn) WriteClose(_ int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) Config() *Config {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) IsClientConn() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Conn) IsServerConn() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Conn) LocalAddr() net.Addr {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) Read(_ []byte) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (_ *Conn) RemoteAddr() net.Addr {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) Request() *http.Request {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) SetDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) SetReadDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) SetWriteDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Conn) Write(_ []byte) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func Dial(_ string, _ string, _ string) (*Conn, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func DialConfig(_ *Config) (*Conn, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func NewConfig(_ string, _ string) (*Config, error) {
|
||||
return nil, nil
|
||||
}
|
||||
10
ql/test/experimental/CWE-918/vendor/modules.txt
vendored
Normal file
10
ql/test/experimental/CWE-918/vendor/modules.txt
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# github.com/gorilla/websocket v1.4.2
|
||||
# golang.org/x/net v0.0.0-20200421231249-e086a090c8fd
|
||||
# github.com/gin-gonic/gin v1.6.3
|
||||
# github.com/go-chi/chi v4.1.2+incompatible
|
||||
# github.com/gorilla/mux v1.8.0
|
||||
# github.com/kr/text v0.2.0
|
||||
# github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e
|
||||
# github.com/stretchr/testify v1.6.0
|
||||
# golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
|
||||
# gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f
|
||||
Reference in New Issue
Block a user