mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Merge pull request #12246 from owen-mc/go/fix/misc
Fix miscellaneous errors highlighted by QL-for-QL
This commit is contained in:
@@ -12,12 +12,12 @@ import semmle.go.PrintAst
|
||||
import ideContextual
|
||||
|
||||
/**
|
||||
* The source file to generate an AST from.
|
||||
* Gets the source file to generate an AST from.
|
||||
*/
|
||||
external string selectedSourceFile();
|
||||
|
||||
/**
|
||||
* Hook to customize the functions printed by this query.
|
||||
* A hook to customize the functions printed by this query.
|
||||
*/
|
||||
class Cfg extends PrintAstConfiguration {
|
||||
override predicate shouldPrintFunction(FuncDecl func) { shouldPrintFile(func.getFile()) }
|
||||
|
||||
@@ -115,7 +115,7 @@ module FileSystemAccess {
|
||||
/** A function that escapes meta-characters to prevent injection attacks. */
|
||||
class EscapeFunction extends Function instanceof EscapeFunction::Range {
|
||||
/**
|
||||
* The context that this function escapes for.
|
||||
* Gets the context that this function escapes for.
|
||||
*
|
||||
* Currently, this can be "js", "html", or "url".
|
||||
*/
|
||||
@@ -132,7 +132,7 @@ module EscapeFunction {
|
||||
*/
|
||||
abstract class Range extends Function {
|
||||
/**
|
||||
* The context that this function escapes for.
|
||||
* Gets the context that this function escapes for.
|
||||
*
|
||||
* Currently, this can be `js', `html', or `url'.
|
||||
*/
|
||||
|
||||
@@ -181,7 +181,7 @@ class Folder extends Container, @folder {
|
||||
override string getURL() { result = "folder://" + this.getAbsolutePath() }
|
||||
}
|
||||
|
||||
/** Any file, including files that have not been extracted but are referred to as locations for errors. */
|
||||
/** A file, including files that have not been extracted but are referred to as locations for errors. */
|
||||
class ExtractedOrExternalFile extends Container, @file, Documentable, ExprParent, GoModExprParent,
|
||||
DeclParent, ScopeNode
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ import go
|
||||
import PrintAst
|
||||
|
||||
/**
|
||||
* Hook to customize the functions printed by this query.
|
||||
* A hook to customize the functions printed by this query.
|
||||
*/
|
||||
class Cfg extends PrintAstConfiguration {
|
||||
override predicate shouldPrintFunction(FuncDecl func) { any() }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import go
|
||||
|
||||
/**
|
||||
* Hook to customize the files and functions printed by this module.
|
||||
* A hook to customize the files and functions printed by this module.
|
||||
*
|
||||
* For an AstNode to be printed, it always requires `shouldPrintFile(f)` to hold
|
||||
* for its containing file `f`, and additionally requires `shouldPrintFunction(fun)`
|
||||
|
||||
@@ -602,7 +602,7 @@ private newtype TCallable =
|
||||
TFuncLitCallable(FuncLit l)
|
||||
|
||||
/**
|
||||
* This is either a `Function` or a `FuncLit`, because of limitations of both
|
||||
* A `Function` or a `FuncLit`. We do it this way because of limitations of both
|
||||
* `Function` and `FuncDef`:
|
||||
* - `Function` is an entity, and therefore does not include function literals, and
|
||||
* - `FuncDef` is an AST node, and so is not extracted for functions from external libraries.
|
||||
|
||||
@@ -581,7 +581,7 @@ module StringOps {
|
||||
}
|
||||
|
||||
/**
|
||||
* One of the operands in a string concatenation.
|
||||
* An operand in a string concatenation.
|
||||
*
|
||||
* See `ConcatenationElement` for more information.
|
||||
*/
|
||||
|
||||
@@ -172,7 +172,7 @@ class InvalidType extends @invalidtype, Type {
|
||||
/** A basic type. */
|
||||
class BasicType extends @basictype, Type { }
|
||||
|
||||
/** Either the normal or literal boolean type */
|
||||
/** The normal boolean type or the literal boolean type */
|
||||
class BoolType extends @booltype, BasicType { }
|
||||
|
||||
/** The `bool` type of a non-literal expression */
|
||||
@@ -317,7 +317,7 @@ class Complex128Type extends @complex128type, ComplexType {
|
||||
override string getName() { result = "complex128" }
|
||||
}
|
||||
|
||||
/** Either the normal or literal string type */
|
||||
/** The normal string type or the literal string type */
|
||||
class StringType extends @stringtype, BasicType { }
|
||||
|
||||
/** The `string` type of a non-literal expression */
|
||||
|
||||
@@ -1305,10 +1305,10 @@ module CFG {
|
||||
exists(Completion inner | lastNode(this.getBody(), last, inner) and not inner.isNormal() |
|
||||
if inner = Break(this.getLabel())
|
||||
then cmpl = Done()
|
||||
else
|
||||
if inner = Continue(this.getLabel())
|
||||
then none()
|
||||
else cmpl = inner
|
||||
else (
|
||||
not inner = Continue(this.getLabel()) and
|
||||
cmpl = inner
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ private newtype TSsaWithFields =
|
||||
TStep(SsaWithFields base, Field f) { exists(accessPathAux(base, f)) }
|
||||
|
||||
/**
|
||||
* Gets a representation of `nd` as an ssa-with-fields value if there is one.
|
||||
* Gets a representation of `insn` as an ssa-with-fields value if there is one.
|
||||
*/
|
||||
private TSsaWithFields accessPath(IR::Instruction insn) {
|
||||
exists(SsaVariable v | insn = v.getAUse() | result = TRoot(v))
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import go
|
||||
|
||||
/**
|
||||
* A call to a regexp match function, considered as a barrier guard for sanitizing untrusted URLs.
|
||||
* Holds if `resultNode` comes from 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.
|
||||
*
|
||||
|
||||
@@ -61,9 +61,8 @@ module Private {
|
||||
/** A data flow node that represents the output of a call. */
|
||||
class OutNode extends Node {
|
||||
DataFlow::CallNode call;
|
||||
int i;
|
||||
|
||||
OutNode() { this = call.getResult(i) }
|
||||
OutNode() { this = call.getResult(_) }
|
||||
|
||||
/** Gets the underlying call. */
|
||||
DataFlowCall getCall() { result = call.asExpr() }
|
||||
@@ -753,13 +752,14 @@ module Public {
|
||||
* of the function.
|
||||
*/
|
||||
class ResultNode extends InstructionNode {
|
||||
FuncDef fd;
|
||||
int i;
|
||||
|
||||
ResultNode() {
|
||||
exists(IR::ReturnInstruction ret | ret.getRoot() = fd | insn = ret.getResult(i))
|
||||
or
|
||||
insn.(IR::ReadResultInstruction).reads(fd.getResultVar(i))
|
||||
exists(FuncDef fd |
|
||||
exists(IR::ReturnInstruction ret | ret.getRoot() = fd | insn = ret.getResult(i))
|
||||
or
|
||||
insn.(IR::ReadResultInstruction).reads(fd.getResultVar(i))
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the index of this result among all results of the function. */
|
||||
@@ -1112,12 +1112,12 @@ module Public {
|
||||
*/
|
||||
class RangeElementNode extends Node {
|
||||
DataFlow::Node base;
|
||||
IR::ExtractTupleElementInstruction extract;
|
||||
|
||||
RangeElementNode() {
|
||||
this.asInstruction() = extract and
|
||||
extract.extractsElement(_, 1) and
|
||||
extract.getBase().(IR::GetNextEntryInstruction).getDomain() = base.asInstruction()
|
||||
exists(IR::ExtractTupleElementInstruction extract | extract = this.asInstruction() |
|
||||
extract.extractsElement(_, 1) and
|
||||
extract.getBase().(IR::GetNextEntryInstruction).getDomain() = base.asInstruction()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the data-flow node representing the base from which the element is read. */
|
||||
|
||||
@@ -28,9 +28,7 @@ abstract class Dependency extends Locatable {
|
||||
*/
|
||||
abstract predicate relevantForFile(File file);
|
||||
|
||||
/**
|
||||
* An import of this dependency.
|
||||
*/
|
||||
/** Gets an import of this dependency. */
|
||||
ImportSpec getAnImport() {
|
||||
result.getPath().regexpMatch("\\Q" + this.getDepPath() + "\\E(/.*)?") and
|
||||
this.relevantForFile(result.getFile())
|
||||
@@ -86,7 +84,7 @@ class GoModDependency extends Dependency, GoModRequireLine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this require line originally states dependency `path` had version `ver`.
|
||||
* Holds if this require line originally states dependency `path` had version `v`.
|
||||
*
|
||||
* The actual info of this dependency can change based on `replace` directives in the same go.mod
|
||||
* file, which replace a dependency with another one.
|
||||
|
||||
@@ -51,13 +51,9 @@ module Beego {
|
||||
*/
|
||||
private class BeegoInputSource extends UntrustedFlowSource::Range {
|
||||
string methodName;
|
||||
FunctionOutput output;
|
||||
|
||||
BeegoInputSource() {
|
||||
exists(DataFlow::MethodCallNode c | this = output.getExitNode(c) |
|
||||
c.getTarget().hasQualifiedName(contextPackagePath(), "BeegoInput", methodName)
|
||||
) and
|
||||
(
|
||||
exists(FunctionOutput output |
|
||||
methodName = "Bind" and
|
||||
output.isParameter(0)
|
||||
or
|
||||
@@ -66,6 +62,10 @@ module Beego {
|
||||
"URI", "URL", "UserAgent"
|
||||
] and
|
||||
output.isResult(0)
|
||||
|
|
||||
exists(DataFlow::MethodCallNode c | this = output.getExitNode(c) |
|
||||
c.getTarget().hasQualifiedName(contextPackagePath(), "BeegoInput", methodName)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -81,16 +81,8 @@ module Beego {
|
||||
* `beego.Controller` sources of untrusted data.
|
||||
*/
|
||||
private class BeegoControllerSource extends UntrustedFlowSource::Range {
|
||||
string methodName;
|
||||
FunctionOutput output;
|
||||
|
||||
BeegoControllerSource() {
|
||||
exists(DataFlow::MethodCallNode c |
|
||||
c.getTarget().hasQualifiedName(packagePath(), "Controller", methodName)
|
||||
|
|
||||
this = output.getExitNode(c)
|
||||
) and
|
||||
(
|
||||
exists(string methodName, FunctionOutput output |
|
||||
methodName = "ParseForm" and
|
||||
output.isParameter(0)
|
||||
or
|
||||
@@ -99,6 +91,12 @@ module Beego {
|
||||
or
|
||||
methodName = "GetFile" and
|
||||
output.isResult(1)
|
||||
|
|
||||
exists(DataFlow::MethodCallNode c |
|
||||
c.getTarget().hasQualifiedName(packagePath(), "Controller", methodName)
|
||||
|
|
||||
this = output.getExitNode(c)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -225,10 +223,8 @@ module Beego {
|
||||
}
|
||||
|
||||
private class ContextResponseBody extends Http::ResponseBody::Range {
|
||||
string name;
|
||||
|
||||
ContextResponseBody() {
|
||||
exists(Method m | m.hasQualifiedName(contextPackagePath(), "Context", name) |
|
||||
exists(Method m, string name | m.hasQualifiedName(contextPackagePath(), "Context", name) |
|
||||
name = "Abort" and this = m.getACall().getArgument(1)
|
||||
or
|
||||
name = "WriteString" and this = m.getACall().getArgument(0)
|
||||
@@ -326,16 +322,17 @@ module Beego {
|
||||
}
|
||||
|
||||
private class RedirectMethods extends Http::Redirect::Range, DataFlow::CallNode {
|
||||
string package;
|
||||
string className;
|
||||
|
||||
RedirectMethods() {
|
||||
(
|
||||
package = packagePath() and className = "Controller"
|
||||
or
|
||||
package = contextPackagePath() and className = "Context"
|
||||
) and
|
||||
this = any(Method m | m.hasQualifiedName(package, className, "Redirect")).getACall()
|
||||
exists(string package |
|
||||
(
|
||||
package = packagePath() and className = "Controller"
|
||||
or
|
||||
package = contextPackagePath() and className = "Context"
|
||||
) and
|
||||
this = any(Method m | m.hasQualifiedName(package, className, "Redirect")).getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getUrl() {
|
||||
|
||||
@@ -43,17 +43,15 @@ private module Echo {
|
||||
* Models of `Context.Get/Set`. `Context` behaves like a map, with corresponding taint propagation.
|
||||
*/
|
||||
private class ContextMapModels extends TaintTracking::FunctionModel, Method {
|
||||
string methodName;
|
||||
FunctionInput input;
|
||||
FunctionOutput output;
|
||||
|
||||
ContextMapModels() {
|
||||
(
|
||||
exists(string methodName | this.hasQualifiedName(packagePath(), "Context", methodName) |
|
||||
methodName = "Get" and input.isReceiver() and output.isResult()
|
||||
or
|
||||
methodName = "Set" and input.isParameter(1) and output.isReceiver()
|
||||
) and
|
||||
this.hasQualifiedName(packagePath(), "Context", methodName)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
|
||||
|
||||
@@ -10,20 +10,20 @@ module K8sIoApiCoreV1 {
|
||||
string packagePath() { result = package("k8s.io/api", "core/v1") }
|
||||
|
||||
private class SecretDeepCopy extends TaintTracking::FunctionModel, Method {
|
||||
string methodName;
|
||||
FunctionOutput output;
|
||||
|
||||
SecretDeepCopy() {
|
||||
(
|
||||
exists(string methodName |
|
||||
methodName in ["DeepCopy", "DeepCopyObject"] and output.isResult()
|
||||
or
|
||||
methodName = "DeepCopyInto" and output.isParameter(0)
|
||||
) and
|
||||
this.hasQualifiedName(packagePath(), ["Secret", "SecretList"], methodName)
|
||||
|
|
||||
this.hasQualifiedName(packagePath(), ["Secret", "SecretList"], methodName)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
|
||||
inp.isReceiver() and outp = outp
|
||||
inp.isReceiver() and outp = output
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -201,11 +201,9 @@ module Revel {
|
||||
private class RevelHeaderMethods extends TaintTracking::FunctionModel {
|
||||
FunctionInput input;
|
||||
FunctionOutput output;
|
||||
string name;
|
||||
|
||||
RevelHeaderMethods() {
|
||||
this.(Method).hasQualifiedName(packagePath(), "RevelHeader", name) and
|
||||
(
|
||||
exists(string name | this.(Method).hasQualifiedName(packagePath(), "RevelHeader", name) |
|
||||
name = ["Add", "Set"] and input.isParameter([0, 1]) and output.isReceiver()
|
||||
or
|
||||
name = ["Get", "GetAll"] and input.isReceiver() and output.isResult()
|
||||
|
||||
@@ -57,13 +57,12 @@ module NetHttp {
|
||||
}
|
||||
|
||||
private class MapWrite extends Http::HeaderWrite::Range, DataFlow::Node {
|
||||
Write write;
|
||||
DataFlow::Node index;
|
||||
DataFlow::Node rhs;
|
||||
|
||||
MapWrite() {
|
||||
this.getType().hasQualifiedName("net/http", "Header") and
|
||||
write.writesElement(this, index, rhs)
|
||||
any(Write write).writesElement(this, index, rhs)
|
||||
}
|
||||
|
||||
override DataFlow::Node getName() { result = index }
|
||||
|
||||
@@ -71,7 +71,7 @@ module InsecureFeatureFlag {
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags suggesting an optional feature, perhaps deliberately insecure.
|
||||
* A flag suggesting an optional feature, perhaps deliberately insecure.
|
||||
*/
|
||||
class SecurityFeatureFlag extends FlagKind {
|
||||
SecurityFeatureFlag() { this = "securityFeature" }
|
||||
|
||||
@@ -19,7 +19,7 @@ module SafeUrlFlow {
|
||||
/** An outgoing sanitizer edge for safe URL flow. */
|
||||
abstract class SanitizerEdge extends DataFlow::Node { }
|
||||
|
||||
/** Standard library safe URL sources. */
|
||||
/** A standard library safe URL source. */
|
||||
class StdlibSource extends Source, DataFlow::FieldReadNode {
|
||||
StdlibSource() { this.getField().hasQualifiedName("net/http", "Request", ["Host", "URL"]) }
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ module UnsafeUnzipSymlink {
|
||||
import UnsafeUnzipSymlinkCustomizations::UnsafeUnzipSymlink
|
||||
|
||||
/**
|
||||
* Taint-flow configuration tracking archive header fields flowing to a `path/filepath.EvalSymlinks` call.
|
||||
* A taint-flow configuration tracking archive header fields flowing to a `path/filepath.EvalSymlinks` call.
|
||||
*/
|
||||
class EvalSymlinksConfiguration extends TaintTracking2::Configuration {
|
||||
EvalSymlinksConfiguration() { this = "Archive header field symlinks resolved" }
|
||||
@@ -41,7 +41,7 @@ module UnsafeUnzipSymlink {
|
||||
}
|
||||
|
||||
/**
|
||||
* Taint-flow configuration tracking archive header fields flowing to an `os.Symlink` call,
|
||||
* A taint-flow configuration tracking archive header fields flowing to an `os.Symlink` call,
|
||||
* which never flow to a `path/filepath.EvalSymlinks` call.
|
||||
*/
|
||||
class SymlinkConfiguration extends TaintTracking::Configuration {
|
||||
|
||||
@@ -61,7 +61,7 @@ module ZipSlip {
|
||||
}
|
||||
|
||||
/**
|
||||
* Excludes zipped file data from consideration for zip slip.
|
||||
* A zipped file, excluded from for zip slip.
|
||||
*/
|
||||
class ZipFileOpen extends Sanitizer {
|
||||
ZipFileOpen() {
|
||||
|
||||
@@ -16,7 +16,8 @@ import go
|
||||
string packagePath() { result = package("github.com/pkg/errors", "") }
|
||||
|
||||
/**
|
||||
* An equality test which guarantees that an expression is always `nil`.
|
||||
* Holds if `g` is an equality test which guarantees that the expression `e` is
|
||||
* either `nil` or not `nil`, depending on `outcome`.
|
||||
*/
|
||||
predicate nilTestGuard(DataFlow::Node g, Expr e, boolean outcome) {
|
||||
exists(DataFlow::EqualityTestNode eq, DataFlow::Node otherNode |
|
||||
|
||||
@@ -19,7 +19,7 @@ class HashableNode extends AstNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* An opaque integer describing the type of this AST node.
|
||||
* Gets an opaque integer describing the type of this AST node.
|
||||
*/
|
||||
int getKind() {
|
||||
exists(int baseKind |
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import go
|
||||
|
||||
/**
|
||||
* Holds if `src` is a pattern for a collection of alternatives where
|
||||
* Holds if `re` is a pattern for a collection of alternatives where
|
||||
* only the first or last alternative is anchored, indicating a
|
||||
* precedence mistake explained by `msg`.
|
||||
*
|
||||
@@ -46,7 +46,7 @@ predicate isInterestingSemiAnchoredRegexpString(string re, string msg) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `src` is an unanchored pattern for a URL, indicating a
|
||||
* Holds if `re` is an unanchored pattern for a URL, indicating a
|
||||
* mistake explained by `msg`.
|
||||
*/
|
||||
bindingset[re]
|
||||
|
||||
@@ -38,7 +38,7 @@ predicate becomesPartOf(DataFlow::Node part, DataFlow::Node whole) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags suggesting a deliberately insecure certificate setup.
|
||||
* A flag suggesting a deliberately insecure certificate setup.
|
||||
*/
|
||||
class InsecureCertificateFlag extends FlagKind {
|
||||
InsecureCertificateFlag() { this = "insecureCertificate" }
|
||||
|
||||
@@ -14,7 +14,8 @@ import go
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
* RSA key length data flow tracking configuration.
|
||||
* A data flow tracking configuration for tracking flow from RSA key length to
|
||||
* calls to RSA key generation functions.
|
||||
*/
|
||||
class RsaKeyTrackingConfiguration extends DataFlow::Configuration {
|
||||
RsaKeyTrackingConfiguration() { this = "RsaKeyTrackingConfiguration" }
|
||||
|
||||
@@ -52,7 +52,8 @@ int getASecureTlsVersion() {
|
||||
int getATlsVersion() { result = getASecureTlsVersion() or isInsecureTlsVersion(result, _, _) }
|
||||
|
||||
/**
|
||||
* Flow of TLS versions into a `tls.Config` struct, to the `MinVersion` and `MaxVersion` fields.
|
||||
* A taint-tracking configuration for tracking flow from TLS versions to the
|
||||
* `tls.Config.MinVersion` and `tls.Config.MaxVersion` fields.
|
||||
*/
|
||||
class TlsVersionFlowConfig extends TaintTracking::Configuration {
|
||||
TlsVersionFlowConfig() { this = "TlsVersionFlowConfig" }
|
||||
@@ -152,8 +153,8 @@ predicate isInsecureTlsVersionFlow(
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow of unsecure TLS cipher suites into a `tls.Config` struct,
|
||||
* to the `CipherSuites` field.
|
||||
* A taint-tracking configuration for tracking flow from insecure TLS cipher
|
||||
* suites into a `tls.Config` struct, to the `CipherSuites` field.
|
||||
*/
|
||||
class TlsInsecureCipherSuitesFlowConfig extends TaintTracking::Configuration {
|
||||
TlsInsecureCipherSuitesFlowConfig() { this = "TlsInsecureCipherSuitesFlowConfig" }
|
||||
@@ -229,7 +230,7 @@ predicate isInsecureTlsCipherFlow(DataFlow::PathNode source, DataFlow::PathNode
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags suggesting support for an old or legacy TLS version.
|
||||
* A flag suggesting support for an old or legacy TLS version.
|
||||
*
|
||||
* We accept 'intermediate' because it appears to be common for TLS users
|
||||
* to define three profiles: modern, intermediate, legacy/old, perhaps based
|
||||
|
||||
@@ -24,5 +24,5 @@ where
|
||||
// this excludes flow from safe parts of request URLs, for example the full URL when the
|
||||
// doing a redirect from `http://<path>` to `https://<path>`
|
||||
not scfg.hasFlow(_, sink.getNode())
|
||||
select sink.getNode(), source, sink, "Untrusted URL redirection depends on a $@.", source.getNode(),
|
||||
"user-provided value"
|
||||
select sink.getNode(), source, sink, "This path to an untrusted URL redirection depends on a $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
|
||||
@@ -65,7 +65,8 @@ private class SetCookieSink extends DataFlow::Node {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks sensitive name to `net/http.SetCookie`.
|
||||
* A taint-tracking configuration for tracking flow from sensitive names to
|
||||
* `net/http.SetCookie`.
|
||||
*/
|
||||
class NameToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration {
|
||||
NameToNetHttpCookieTrackingConfiguration() { this = "NameToNetHttpCookieTrackingConfiguration" }
|
||||
@@ -84,7 +85,8 @@ class NameToNetHttpCookieTrackingConfiguration extends TaintTracking::Configurat
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks `bool` assigned to `HttpOnly` that flows into `net/http.SetCookie`.
|
||||
* A taint-tracking configuration for tracking flow from `bool` assigned to
|
||||
* `HttpOnly` that flows into `net/http.SetCookie`.
|
||||
*/
|
||||
class BoolToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration {
|
||||
BoolToNetHttpCookieTrackingConfiguration() { this = "BoolToNetHttpCookieTrackingConfiguration" }
|
||||
@@ -105,7 +107,8 @@ class BoolToNetHttpCookieTrackingConfiguration extends TaintTracking::Configurat
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks `HttpOnly` set to `false` to `gin-gonic/gin.Context.SetCookie`.
|
||||
* A taint-tracking configuration for tracking flow from `HttpOnly` set to
|
||||
* `false` to `gin-gonic/gin.Context.SetCookie`.
|
||||
*/
|
||||
class BoolToGinSetCookieTrackingConfiguration extends DataFlow::Configuration {
|
||||
BoolToGinSetCookieTrackingConfiguration() { this = "BoolToGinSetCookieTrackingConfiguration" }
|
||||
@@ -125,7 +128,8 @@ class BoolToGinSetCookieTrackingConfiguration extends DataFlow::Configuration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks sensitive name to `gin-gonic/gin.Context.SetCookie`.
|
||||
* A taint-tracking configuration for tracking flow from sensitive names to
|
||||
* `gin-gonic/gin.Context.SetCookie`.
|
||||
*/
|
||||
private class NameToGinSetCookieTrackingConfiguration extends DataFlow2::Configuration {
|
||||
NameToGinSetCookieTrackingConfiguration() { this = "NameToGinSetCookieTrackingConfiguration" }
|
||||
@@ -164,7 +168,8 @@ private class GorillaStoreSaveSink extends DataFlow::Node {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks from gorilla cookie store creation to `gorilla/sessions.Session.Save`.
|
||||
* A taint-tracking configuration for tracking flow from gorilla cookie store
|
||||
* creation to `gorilla/sessions.Session.Save`.
|
||||
*/
|
||||
class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuration {
|
||||
GorillaCookieStoreSaveTrackingConfiguration() {
|
||||
@@ -194,7 +199,8 @@ class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuratio
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks session options to `gorilla/sessions.Session.Save`.
|
||||
* A taint-tracking configuration for tracking flow from session options to
|
||||
* `gorilla/sessions.Session.Save`.
|
||||
*/
|
||||
class GorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration {
|
||||
GorillaSessionOptionsTrackingConfiguration() {
|
||||
@@ -219,7 +225,8 @@ class GorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configur
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks `bool` assigned to `HttpOnly` that flows into `gorilla/sessions.Session.Save`.
|
||||
* A taint-tracking configuration for tracking flow from a `bool` assigned to
|
||||
* `HttpOnly` to `gorilla/sessions.Session.Save`.
|
||||
*/
|
||||
class BoolToGorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration {
|
||||
BoolToGorillaSessionOptionsTrackingConfiguration() {
|
||||
|
||||
@@ -161,7 +161,7 @@ abstract class CryptographicOperation extends DataFlow::Node {
|
||||
}
|
||||
|
||||
/**
|
||||
* Models cryptographic operations of the `crypto/md5` package.
|
||||
* A cryptographic operation from the `crypto/md5` package.
|
||||
*/
|
||||
class Md5 extends CryptographicOperation, DataFlow::CallNode {
|
||||
Md5() { this.getTarget().hasQualifiedName("crypto/md5", ["New", "Sum"]) }
|
||||
@@ -174,7 +174,7 @@ class Md5 extends CryptographicOperation, DataFlow::CallNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Models cryptographic operations of the `crypto/sha1` package.
|
||||
* A cryptographic operation from the `crypto/sha1` package.
|
||||
*/
|
||||
class Sha1 extends CryptographicOperation, DataFlow::CallNode {
|
||||
Sha1() { this.getTarget().hasQualifiedName("crypto/sha1", ["New", "Sum"]) }
|
||||
@@ -187,7 +187,7 @@ class Sha1 extends CryptographicOperation, DataFlow::CallNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Models cryptographic operations of the `crypto/des` package.
|
||||
* A cryptographic operation from the `crypto/des` package.
|
||||
*/
|
||||
class Des extends CryptographicOperation, DataFlow::CallNode {
|
||||
Des() { this.getTarget().hasQualifiedName("crypto/des", ["NewCipher", "NewTripleDESCipher"]) }
|
||||
@@ -200,10 +200,10 @@ class Des extends CryptographicOperation, DataFlow::CallNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Models cryptographic operations of the `crypto/rc4` package.
|
||||
* A cryptographic operation from the `crypto/rc4` package.
|
||||
*/
|
||||
class Rc4 extends CryptographicOperation, DataFlow::CallNode {
|
||||
Rc4() { this.getTarget().hasQualifiedName("crypto/rc4", ["NewCipher"]) }
|
||||
Rc4() { this.getTarget().hasQualifiedName("crypto/rc4", "NewCipher") }
|
||||
|
||||
override Expr getInput() { result = this.getArgument(0).asExpr() }
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ predicate flowsFromUntrustedToConversion(
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the names of the types that will not be escaped when passed to
|
||||
* A name of a type that will not be escaped when passed to
|
||||
* a `html/template` template.
|
||||
*/
|
||||
class PassthroughTypeName extends string {
|
||||
|
||||
@@ -132,7 +132,7 @@ module ServerSideRequestForgery {
|
||||
}
|
||||
|
||||
/**
|
||||
* If the tainted variable is a boolean or has numeric type is not possible to exploit a SSRF
|
||||
* A value which has boolean or numeric type, considered as a sanitizer for SSRF.
|
||||
*/
|
||||
class NumSanitizer extends Sanitizer {
|
||||
NumSanitizer() {
|
||||
@@ -142,8 +142,8 @@ module ServerSideRequestForgery {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* A body received from a request, where certain tags on our struct's fields have been used to hint
|
||||
* to 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 { }
|
||||
|
||||
@@ -166,7 +166,7 @@ class FlowsFromUntrusted extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the provided `dst` is also destination of a `UntrustedFlowSource`.
|
||||
* Holds if the provided `allowOriginHW` is also destination of a `UntrustedFlowSource`.
|
||||
*/
|
||||
predicate flowsToGuardedByCheckOnUntrusted(AllowOriginHeaderWrite allowOriginHW) {
|
||||
exists(FlowsFromUntrusted cfg, DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn |
|
||||
|
||||
@@ -175,18 +175,14 @@ private module CleverGo {
|
||||
* Models HTTP redirects.
|
||||
*/
|
||||
private class HttpRedirect extends Http::Redirect::Range, DataFlow::CallNode {
|
||||
string package;
|
||||
DataFlow::Node urlNode;
|
||||
|
||||
HttpRedirect() {
|
||||
// HTTP redirect models for package: clevergo.tech/clevergo@v0.5.2
|
||||
package = packagePath() and
|
||||
// Receiver type: Context
|
||||
(
|
||||
// signature: func (*Context) Redirect(code int, url string) error
|
||||
this = any(Method m | m.hasQualifiedName(package, "Context", "Redirect")).getACall() and
|
||||
urlNode = this.getArgument(1)
|
||||
)
|
||||
// signature: func (*Context) Redirect(code int, url string) error
|
||||
this = any(Method m | m.hasQualifiedName(packagePath(), "Context", "Redirect")).getACall() and
|
||||
urlNode = this.getArgument(1)
|
||||
}
|
||||
|
||||
override DataFlow::Node getUrl() { result = urlNode }
|
||||
|
||||
@@ -130,18 +130,14 @@ private module Fiber {
|
||||
* Models HTTP redirects.
|
||||
*/
|
||||
private class Redirect extends Http::Redirect::Range, DataFlow::CallNode {
|
||||
string package;
|
||||
DataFlow::Node urlNode;
|
||||
|
||||
Redirect() {
|
||||
// HTTP redirect models for package: github.com/gofiber/fiber@v1.14.6
|
||||
package = fiberPackagePath() and
|
||||
// Receiver type: Ctx
|
||||
(
|
||||
// signature: func (*Ctx) Redirect(location string, status ...int)
|
||||
this = any(Method m | m.hasQualifiedName(package, "Ctx", "Redirect")).getACall() and
|
||||
urlNode = this.getArgument(0)
|
||||
)
|
||||
// signature: func (*Ctx) Redirect(location string, status ...int)
|
||||
this = any(Method m | m.hasQualifiedName(fiberPackagePath(), "Ctx", "Redirect")).getACall() and
|
||||
urlNode = this.getArgument(0)
|
||||
}
|
||||
|
||||
override DataFlow::Node getUrl() { result = urlNode }
|
||||
|
||||
@@ -44,7 +44,7 @@ class Diagnostic extends @diagnostic {
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps `Compilation`, removing the `.exe` suffixes from compilation descriptions
|
||||
* A wrapper around a `Compilation`, removing the `.exe` suffixes from compilation descriptions
|
||||
* such that this test produces the same results on Windows and non-Windows platforms.
|
||||
*/
|
||||
class PlatformNeutralCompilation extends Compilation {
|
||||
|
||||
@@ -2,17 +2,18 @@ import go
|
||||
|
||||
from string path
|
||||
where
|
||||
(
|
||||
path = "github.com/nonexistent/v2/test" or // OK
|
||||
path = "github.com/nonexistent/test" or // OK
|
||||
path = "github.com/nonexistent//v//test" or // NOT OK
|
||||
path = "github.com/nonexistent//v/test" or // NOT OK
|
||||
path = "github.com/nonexistent/v//test" or // NOT OK
|
||||
path = "github.com/nonexistent/v/asd/v2/test" or // NOT OK
|
||||
path = "github.com/nonexistent/v/test" or // NOT OK
|
||||
path = "github.com/nonexistent//v2//test" or // NOT OK
|
||||
path = "github.com/nonexistent//v2/test" or // NOT OK
|
||||
path = "github.com/nonexistent/v2//test" // NOT OK
|
||||
) and
|
||||
path =
|
||||
[
|
||||
"github.com/nonexistent/v2/test", // OK
|
||||
"github.com/nonexistent/test", // OK
|
||||
"github.com/nonexistent//v//test", // NOT OK
|
||||
"github.com/nonexistent//v/test", // NOT OK
|
||||
"github.com/nonexistent/v//test", // NOT OK
|
||||
"github.com/nonexistent/v/asd/v2/test", // NOT OK
|
||||
"github.com/nonexistent/v/test", // NOT OK
|
||||
"github.com/nonexistent//v2//test", // NOT OK
|
||||
"github.com/nonexistent//v2/test", // NOT OK
|
||||
"github.com/nonexistent/v2//test" // NOT OK
|
||||
] and
|
||||
path = package("github.com/nonexistent", "test")
|
||||
select path
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import go
|
||||
|
||||
from Type t
|
||||
where t.getPackage().getName().regexpMatch("main|pkg1|pkg2")
|
||||
where t.getPackage().getName() = ["main", "pkg1", "pkg2"]
|
||||
select t.pp(), strictcount(t.getMethod(_))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import go
|
||||
|
||||
from Type t, string m
|
||||
where t.getPackage().getName().regexpMatch("main|pkg1|pkg2")
|
||||
where t.getPackage().getName() = ["main", "pkg1", "pkg2"]
|
||||
select t.pp(), m, t.getMethod(m)
|
||||
|
||||
@@ -8,5 +8,5 @@ nodes
|
||||
| test.go:312:20:312:34 | call to URL | semmle.label | call to URL |
|
||||
subpaths
|
||||
#select
|
||||
| test.go:247:13:247:34 | call to GetString | test.go:247:13:247:34 | call to GetString | test.go:247:13:247:34 | call to GetString | Untrusted URL redirection depends on a $@. | test.go:247:13:247:34 | call to GetString | user-provided value |
|
||||
| test.go:248:20:248:41 | call to GetString | test.go:248:20:248:41 | call to GetString | test.go:248:20:248:41 | call to GetString | Untrusted URL redirection depends on a $@. | test.go:248:20:248:41 | call to GetString | user-provided value |
|
||||
| test.go:247:13:247:34 | call to GetString | test.go:247:13:247:34 | call to GetString | test.go:247:13:247:34 | call to GetString | This path to an untrusted URL redirection depends on a $@. | test.go:247:13:247:34 | call to GetString | user-provided value |
|
||||
| test.go:248:20:248:41 | call to GetString | test.go:248:20:248:41 | call to GetString | test.go:248:20:248:41 | call to GetString | This path to an untrusted URL redirection depends on a $@. | test.go:248:20:248:41 | call to GetString | user-provided value |
|
||||
|
||||
@@ -14,5 +14,5 @@ nodes
|
||||
| test.go:191:21:191:32 | call to String | semmle.label | call to String |
|
||||
subpaths
|
||||
#select
|
||||
| test.go:171:20:171:24 | param | test.go:170:11:170:32 | call to Param | test.go:171:20:171:24 | param | Untrusted URL redirection depends on a $@. | test.go:170:11:170:32 | call to Param | user-provided value |
|
||||
| test.go:180:20:180:28 | ...+... | test.go:176:11:176:32 | call to Param | test.go:180:20:180:28 | ...+... | Untrusted URL redirection depends on a $@. | test.go:176:11:176:32 | call to Param | user-provided value |
|
||||
| test.go:171:20:171:24 | param | test.go:170:11:170:32 | call to Param | test.go:171:20:171:24 | param | This path to an untrusted URL redirection depends on a $@. | test.go:170:11:170:32 | call to Param | user-provided value |
|
||||
| test.go:180:20:180:28 | ...+... | test.go:176:11:176:32 | call to Param | test.go:180:20:180:28 | ...+... | This path to an untrusted URL redirection depends on a $@. | test.go:176:11:176:32 | call to Param | user-provided value |
|
||||
|
||||
@@ -5,4 +5,4 @@ nodes
|
||||
| EndToEnd.go:94:20:94:49 | call to Get | semmle.label | call to Get |
|
||||
subpaths
|
||||
#select
|
||||
| EndToEnd.go:94:20:94:49 | call to Get | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | Untrusted URL redirection depends on a $@. | EndToEnd.go:94:20:94:27 | selection of Params | user-provided value |
|
||||
| EndToEnd.go:94:20:94:49 | call to Get | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | This path to an untrusted URL redirection depends on a $@. | EndToEnd.go:94:20:94:27 | selection of Params | user-provided value |
|
||||
|
||||
@@ -8,10 +8,9 @@ class SqlTest extends InlineExpectationsTest {
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "query" and
|
||||
exists(SQL::Query q, SQL::QueryString qs, int qsLine | qs = q.getAQueryString() |
|
||||
exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() |
|
||||
q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
|
||||
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
|
||||
qs.hasLocationInfo(_, qsLine, _, _, _) and
|
||||
element = q.toString() and
|
||||
value = qs.toString()
|
||||
)
|
||||
|
||||
@@ -112,14 +112,14 @@ nodes
|
||||
| stdlib.go:194:23:194:42 | call to EscapedPath | semmle.label | call to EscapedPath |
|
||||
subpaths
|
||||
#select
|
||||
| OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | Untrusted URL redirection depends on a $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value |
|
||||
| stdlib.go:15:30:15:35 | target | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:15:30:15:35 | target | Untrusted URL redirection depends on a $@. | stdlib.go:13:13:13:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:24:30:24:35 | target | stdlib.go:22:13:22:18 | selection of Form | stdlib.go:24:30:24:35 | target | Untrusted URL redirection depends on a $@. | stdlib.go:22:13:22:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:35:30:35:39 | ...+... | stdlib.go:31:13:31:18 | selection of Form | stdlib.go:35:30:35:39 | ...+... | Untrusted URL redirection depends on a $@. | stdlib.go:31:13:31:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:46:23:46:28 | target | stdlib.go:44:13:44:18 | selection of Form | stdlib.go:46:23:46:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:44:13:44:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:67:23:67:40 | ...+... | stdlib.go:64:13:64:18 | selection of Form | stdlib.go:67:23:67:40 | ...+... | Untrusted URL redirection depends on a $@. | stdlib.go:64:13:64:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:92:23:92:28 | target | stdlib.go:89:13:89:18 | selection of Form | stdlib.go:92:23:92:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:89:13:89:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:152:23:152:28 | target | stdlib.go:146:13:146:18 | selection of Form | stdlib.go:152:23:152:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:146:13:146:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:184:23:184:28 | target | stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:182:13:182:33 | call to FormValue | user-provided value |
|
||||
| stdlib.go:192:23:192:33 | selection of Path | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:192:23:192:33 | selection of Path | Untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value |
|
||||
| stdlib.go:194:23:194:42 | call to EscapedPath | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:194:23:194:42 | call to EscapedPath | Untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value |
|
||||
| OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | This path to an untrusted URL redirection depends on a $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value |
|
||||
| stdlib.go:15:30:15:35 | target | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:15:30:15:35 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:13:13:13:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:24:30:24:35 | target | stdlib.go:22:13:22:18 | selection of Form | stdlib.go:24:30:24:35 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:22:13:22:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:35:30:35:39 | ...+... | stdlib.go:31:13:31:18 | selection of Form | stdlib.go:35:30:35:39 | ...+... | This path to an untrusted URL redirection depends on a $@. | stdlib.go:31:13:31:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:46:23:46:28 | target | stdlib.go:44:13:44:18 | selection of Form | stdlib.go:46:23:46:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:44:13:44:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:67:23:67:40 | ...+... | stdlib.go:64:13:64:18 | selection of Form | stdlib.go:67:23:67:40 | ...+... | This path to an untrusted URL redirection depends on a $@. | stdlib.go:64:13:64:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:92:23:92:28 | target | stdlib.go:89:13:89:18 | selection of Form | stdlib.go:92:23:92:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:89:13:89:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:152:23:152:28 | target | stdlib.go:146:13:146:18 | selection of Form | stdlib.go:152:23:152:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:146:13:146:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:184:23:184:28 | target | stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:182:13:182:33 | call to FormValue | user-provided value |
|
||||
| stdlib.go:192:23:192:33 | selection of Path | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:192:23:192:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value |
|
||||
| stdlib.go:194:23:194:42 | call to EscapedPath | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:194:23:194:42 | call to EscapedPath | This path to an untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value |
|
||||
|
||||
Reference in New Issue
Block a user