diff --git a/go/ql/lib/semmle/go/frameworks/K8sIoApimachineryPkgRuntime.qll b/go/ql/lib/semmle/go/frameworks/K8sIoApimachineryPkgRuntime.qll index 5f1a45945e7d..5c7481e58087 100644 --- a/go/ql/lib/semmle/go/frameworks/K8sIoApimachineryPkgRuntime.qll +++ b/go/ql/lib/semmle/go/frameworks/K8sIoApimachineryPkgRuntime.qll @@ -50,7 +50,7 @@ module K8sIoApimachineryPkgRuntime { } } - private class DecoderDecode extends Method, UnmarshalingFunction::Range { + private class DecoderDecode extends UnmarshalingFunction::Range, Method { DecoderDecode() { this.implements(packagePath(), "Decoder", "Decode") or this.hasQualifiedName(packagePath(), "WithoutVersionDecoder", "Decode") @@ -95,7 +95,7 @@ module K8sIoApimachineryPkgRuntime { } } - private class ParameterCodecDecodeParameters extends Method, UnmarshalingFunction::Range { + private class ParameterCodecDecodeParameters extends UnmarshalingFunction::Range, Method { ParameterCodecDecodeParameters() { this.implements(packagePath(), "ParameterCodec", "DecodeParameters") } @@ -110,7 +110,7 @@ module K8sIoApimachineryPkgRuntime { } } - private class ParameterCodecEncodeParameters extends Method, MarshalingFunction::Range { + private class ParameterCodecEncodeParameters extends MarshalingFunction::Range, Method { ParameterCodecEncodeParameters() { this.implements(packagePath(), "ParameterCodec", "EncodeParameters") } @@ -125,7 +125,7 @@ module K8sIoApimachineryPkgRuntime { } } - private class ProtobufMarshallerMarshalTo extends Method, MarshalingFunction::Range { + private class ProtobufMarshallerMarshalTo extends MarshalingFunction::Range, Method { ProtobufMarshallerMarshalTo() { this.implements(packagePath(), "ProtobufMarshaller", "MarshalTo") or this.implements(packagePath(), "ProtobufReverseMarshaller", "MarshalToSizedBuffer") @@ -138,7 +138,7 @@ module K8sIoApimachineryPkgRuntime { override string getFormat() { result = "protobuf" } } - private class RawExtensionMarshal extends Method, MarshalingFunction::Range { + private class RawExtensionMarshal extends MarshalingFunction::Range, Method { RawExtensionMarshal() { this.hasQualifiedName(packagePath(), "RawExtension", "Marshal") } override DataFlow::FunctionInput getAnInput() { result.isReceiver() } @@ -148,7 +148,7 @@ module K8sIoApimachineryPkgRuntime { override string getFormat() { result = "protobuf" } } - private class RawExtensionUnmarshal extends Method, UnmarshalingFunction::Range { + private class RawExtensionUnmarshal extends UnmarshalingFunction::Range, Method { RawExtensionUnmarshal() { this.hasQualifiedName(packagePath(), "RawExtension", "Unmarshal") } override DataFlow::FunctionInput getAnInput() { result.isReceiver() } @@ -158,7 +158,7 @@ module K8sIoApimachineryPkgRuntime { override string getFormat() { result = "protobuf" } } - private class UnknownMarshal extends Method, MarshalingFunction::Range { + private class UnknownMarshal extends MarshalingFunction::Range, Method { string methodName; UnknownMarshal() { @@ -177,7 +177,7 @@ module K8sIoApimachineryPkgRuntime { override string getFormat() { result = "protobuf" } } - private class UnknownUnmarshal extends Method, UnmarshalingFunction::Range { + private class UnknownUnmarshal extends UnmarshalingFunction::Range, Method { UnknownUnmarshal() { this.hasQualifiedName(packagePath(), "Unknown", "Unmarshal") } override DataFlow::FunctionInput getAnInput() { result.isReceiver() } diff --git a/go/ql/lib/semmle/go/frameworks/Revel.qll b/go/ql/lib/semmle/go/frameworks/Revel.qll index 547c7c6bdac8..a1eff5e736e7 100644 --- a/go/ql/lib/semmle/go/frameworks/Revel.qll +++ b/go/ql/lib/semmle/go/frameworks/Revel.qll @@ -140,7 +140,7 @@ module Revel { /** * A render of a template. */ - abstract class TemplateRender extends DataFlow::Node, TemplateInstantiation::Range { + abstract class TemplateRender extends TemplateInstantiation::Range { /** Gets the name of the file that is rendered. */ abstract File getRenderedFile(); diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll index e798d116352f..c6adc5c57406 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll @@ -46,7 +46,7 @@ module NetHttp { } } - private class MapWrite extends Http::HeaderWrite::Range, DataFlow::Node { + private class MapWrite extends Http::HeaderWrite::Range { DataFlow::Node index; DataFlow::Node rhs; diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll index 525eb73d5b96..4d86c581e07a 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll @@ -61,7 +61,7 @@ module Regexp { } } - private class DefaultRegexpMatchFunction extends RegexpMatchFunction::Range, Function { + private class DefaultRegexpMatchFunction extends RegexpMatchFunction::Range { int patArg; int strArg; diff --git a/go/ql/lib/semmle/go/security/CleartextLoggingCustomizations.qll b/go/ql/lib/semmle/go/security/CleartextLoggingCustomizations.qll index 4abc9021268e..05fb88977ac2 100644 --- a/go/ql/lib/semmle/go/security/CleartextLoggingCustomizations.qll +++ b/go/ql/lib/semmle/go/security/CleartextLoggingCustomizations.qll @@ -120,7 +120,7 @@ module CleartextLogging { * * This is a source since `log.Print(obj)` will often show the fields of `obj`. */ - private class StructPasswordFieldSource extends DataFlow::Node, Source { + private class StructPasswordFieldSource extends Source { string name; StructPasswordFieldSource() { @@ -137,7 +137,7 @@ module CleartextLogging { } /** An access to a variable or property that might contain a password. */ - private class ReadPasswordSource extends DataFlow::Node, Source { + private class ReadPasswordSource extends Source { string name; ReadPasswordSource() { @@ -162,7 +162,7 @@ module CleartextLogging { } /** A call that might return a password. */ - private class CallPasswordSource extends DataFlow::CallNode, Source { + private class CallPasswordSource extends Source, DataFlow::CallNode { string name; CallPasswordSource() { diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll index 248276ba3965..60c3414f44ce 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -61,7 +61,7 @@ module OpenUrlRedirect { /** * An HTTP redirect, considered as a sink for `Configuration`. */ - class RedirectSink extends Sink, DataFlow::Node { + class RedirectSink extends Sink { RedirectSink() { this = any(Http::Redirect redir).getUrl() } } @@ -69,7 +69,7 @@ module OpenUrlRedirect { * A definition of the HTTP "Location" header, considered as a sink for * `Configuration`. */ - class LocationHeaderSink extends Sink, DataFlow::Node { + class LocationHeaderSink extends Sink { LocationHeaderSink() { exists(Http::HeaderWrite hw | hw.getHeaderName() = "location" | this = hw.getValue()) } @@ -95,20 +95,20 @@ module OpenUrlRedirect { * A call to a function called `isLocalUrl`, `isValidRedirect`, or similar, which is * considered a barrier guard for sanitizing untrusted URLs. */ - class RedirectCheckBarrierGuardAsBarrierGuard extends RedirectCheckBarrier, Barrier { } + class RedirectCheckBarrierGuardAsBarrierGuard extends Barrier instanceof RedirectCheckBarrier { } /** * 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 RegexpCheckBarrier, Barrier { } + class RegexpCheckAsBarrierGuard extends Barrier instanceof RegexpCheckBarrier { } /** * A check against a constant value or the `Hostname` function, * considered a barrier guard for url flow. */ - class UrlCheckAsBarrierGuard extends UrlCheckBarrier, Barrier { } + class UrlCheckAsBarrierGuard extends Barrier instanceof UrlCheckBarrier { } } /** A sink for an open redirect, considered as a sink for safe URL flow. */ diff --git a/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll b/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll index 82f9df4b5064..abd19e9819a8 100644 --- a/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll +++ b/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll @@ -98,14 +98,15 @@ module RequestForgery { * A call to a function called `isLocalUrl`, `isValidRedirect`, or similar, which is * considered a barrier guard. */ - class RedirectCheckBarrierGuardAsBarrierGuard extends RedirectCheckBarrier, Sanitizer { } + class RedirectCheckBarrierGuardAsBarrierGuard extends Sanitizer instanceof RedirectCheckBarrier { + } /** * 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 RegexpCheckBarrier, Sanitizer { } + class RegexpCheckAsBarrierGuard extends Sanitizer instanceof RegexpCheckBarrier { } /** * An equality check comparing a data-flow node against a constant string, considered as @@ -114,7 +115,7 @@ module RequestForgery { * Additionally, a check comparing `url.Hostname()` against a constant string is also * considered a barrier guard for `url`. */ - class UrlCheckAsBarrierGuard extends UrlCheckBarrier, Sanitizer { } + class UrlCheckAsBarrierGuard extends Sanitizer instanceof UrlCheckBarrier { } /** * A simple-typed node, considered a sanitizer for request forgery. diff --git a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlinkCustomizations.qll b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlinkCustomizations.qll index 3fe375833319..1128cc85a002 100644 --- a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlinkCustomizations.qll +++ b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlinkCustomizations.qll @@ -126,7 +126,7 @@ module UnsafeUnzipSymlink { * An argument to a call to `os.Symlink` within a loop that extracts a zip or tar archive, * taken as a sink for unsafe unzipping of symlinks. */ - class OsSymlink extends DataFlow::Node, SymlinkSink { + class OsSymlink extends SymlinkSink { OsSymlink() { exists(DataFlow::CallNode n | n.asExpr() = getASymlinkCall() | this = n.getArgument([0, 1]) and @@ -139,7 +139,7 @@ module UnsafeUnzipSymlink { * An argument to `path/filepath.EvalSymlinks` or `os.Readlink`, taken as a sink for detecting target * paths that are likely safe to extract to. */ - class StdlibSymlinkResolvers extends DataFlow::Node, EvalSymlinksSink { + class StdlibSymlinkResolvers extends EvalSymlinksSink { StdlibSymlinkResolvers() { exists(DataFlow::CallNode n | n.getTarget().hasQualifiedName("path/filepath", "EvalSymlinks") diff --git a/go/ql/lib/semmle/go/security/Xss.qll b/go/ql/lib/semmle/go/security/Xss.qll index f11dc12bf763..a7e2f9a2244b 100644 --- a/go/ql/lib/semmle/go/security/Xss.qll +++ b/go/ql/lib/semmle/go/security/Xss.qll @@ -135,14 +135,14 @@ module SharedXss { * A `Template` from `html/template` will HTML-escape data automatically * and therefore acts as a sanitizer for XSS vulnerabilities. */ - class HtmlTemplateSanitizer extends Sanitizer, DataFlow::Node { + class HtmlTemplateSanitizer extends Sanitizer { HtmlTemplateSanitizer() { exists(Method m, DataFlow::CallNode call | m = call.getCall().getTarget() | m.hasQualifiedName("html/template", "Template", "ExecuteTemplate") and - call.getArgument(2) = this + this = call.getArgument(2) or m.hasQualifiedName("html/template", "Template", "Execute") and - call.getArgument(1) = this + this = call.getArgument(1) ) } } diff --git a/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll b/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll index 980c601582e8..29b107c1c1bb 100644 --- a/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll +++ b/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll @@ -30,7 +30,7 @@ module ZipSlip { /** * A tar file header, as a source for zip slip. */ - class TarHeaderSource extends Source, DataFlow::Node { + class TarHeaderSource extends Source { TarHeaderSource() { this = any(DataFlow::MethodCallNode mcn | diff --git a/go/ql/src/Security/CWE-209/StackTraceExposure.ql b/go/ql/src/Security/CWE-209/StackTraceExposure.ql index 408e12b3c15e..45d58f442c32 100644 --- a/go/ql/src/Security/CWE-209/StackTraceExposure.ql +++ b/go/ql/src/Security/CWE-209/StackTraceExposure.ql @@ -53,7 +53,7 @@ module StackTraceExposureConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof Http::ResponseBody } predicate isBarrier(DataFlow::Node node) { - // Sanitise everything controlled by an is-debug-mode check. + // Sanitize everything controlled by an is-debug-mode check. // Imprecision: I don't try to guess which arm of a branch is intended // to mean debug mode, and which is production mode. exists(ControlFlow::ConditionGuardNode cgn | diff --git a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql index edbb41782b8c..cc2a2e697188 100644 --- a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql +++ b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql @@ -140,9 +140,7 @@ predicate privateUrlFlowsToAuthCodeUrlCall(DataFlow::CallNode call) { module FlowToPrintConfig implements DataFlow::ConfigSig { additional predicate isSinkCall(DataFlow::Node sink, DataFlow::CallNode call) { - exists(LoggerCall logCall | call = logCall | - sink = logCall.getAValueFormattedMessageComponent() - ) + sink = call.(LoggerCall).getAValueFormattedMessageComponent() } predicate isSource(DataFlow::Node source) { source = any(AuthCodeUrl m).getACall().getResult() } diff --git a/go/ql/src/experimental/CWE-287/ImproperLdapAuthCustomizations.qll b/go/ql/src/experimental/CWE-287/ImproperLdapAuthCustomizations.qll index 0a2739eabc79..fceae1398d79 100644 --- a/go/ql/src/experimental/CWE-287/ImproperLdapAuthCustomizations.qll +++ b/go/ql/src/experimental/CWE-287/ImproperLdapAuthCustomizations.qll @@ -29,7 +29,7 @@ module ImproperLdapAuth { * * This is overapproximate: we do not attempt to reason about the correctness of the regexp. */ - class RegexpCheckAsBarrierGuard extends RegexpCheckBarrier, LdapSanitizer { } + class RegexpCheckAsBarrierGuard extends LdapSanitizer instanceof RegexpCheckBarrier { } /** * An empty string. diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index 998ce83ba74c..436b657883eb 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -113,7 +113,7 @@ module ServerSideRequestForgery { * * This is overapproximate: we do not attempt to reason about the correctness of the regexp. */ - class RegexpCheckAsBarrierGuard extends RegexpCheckBarrier, Sanitizer { } + class RegexpCheckAsBarrierGuard extends Sanitizer instanceof RegexpCheckBarrier { } private predicate equalityAsSanitizerGuard(DataFlow::Node g, Expr e, boolean outcome) { exists(DataFlow::Node url, DataFlow::EqualityTestNode eq | @@ -156,5 +156,5 @@ module ServerSideRequestForgery { * 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 Sanitizer, ValidatorVarCheckBarrier { } + class ValidatorAsSanitizer extends Sanitizer instanceof ValidatorVarCheckBarrier { } } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.expected index 591d990be47c..30a38580f789 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.expected @@ -1,3 +1,38 @@ +#select +| test.go:154:14:154:21 | password | test.go:153:17:153:24 | definition of password | test.go:154:14:154:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:155:17:155:24 | password | test.go:153:17:153:24 | definition of password | test.go:155:17:155:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:156:14:156:21 | password | test.go:153:17:153:24 | definition of password | test.go:156:14:156:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:157:18:157:25 | password | test.go:153:17:153:24 | definition of password | test.go:157:18:157:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:158:14:158:21 | password | test.go:153:17:153:24 | definition of password | test.go:158:14:158:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:159:13:159:20 | password | test.go:153:17:153:24 | definition of password | test.go:159:13:159:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:160:22:160:29 | password | test.go:153:17:153:24 | definition of password | test.go:160:22:160:29 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:161:15:161:22 | password | test.go:153:17:153:24 | definition of password | test.go:161:15:161:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:162:14:162:21 | password | test.go:153:17:153:24 | definition of password | test.go:162:14:162:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:163:13:163:20 | password | test.go:153:17:153:24 | definition of password | test.go:163:13:163:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:164:16:164:23 | password | test.go:153:17:153:24 | definition of password | test.go:164:16:164:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:165:13:165:20 | password | test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:166:16:166:23 | password | test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:167:13:167:20 | password | test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:168:17:168:24 | password | test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:169:13:169:20 | password | test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:170:12:170:19 | password | test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:171:21:171:28 | password | test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:172:14:172:21 | password | test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:173:13:173:20 | password | test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:174:12:174:19 | password | test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:175:15:175:22 | password | test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:176:15:176:22 | password | test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:177:18:177:25 | password | test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:178:15:178:22 | password | test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:179:19:179:26 | password | test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:180:15:180:22 | password | test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:181:14:181:21 | password | test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:182:23:182:30 | password | test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:183:16:183:23 | password | test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:184:15:184:22 | password | test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:185:14:185:21 | password | test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:186:17:186:24 | password | test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:187:16:187:23 | password | test.go:153:17:153:24 | definition of password | test.go:187:16:187:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | edges | test.go:153:17:153:24 | definition of password | test.go:154:14:154:21 | password | provenance | | | test.go:153:17:153:24 | definition of password | test.go:155:17:155:24 | password | provenance | | @@ -10,29 +45,52 @@ edges | test.go:153:17:153:24 | definition of password | test.go:162:14:162:21 | password | provenance | | | test.go:153:17:153:24 | definition of password | test.go:163:13:163:20 | password | provenance | | | test.go:153:17:153:24 | definition of password | test.go:164:16:164:23 | password | provenance | | -| test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | provenance | Sink:MaD:380 | -| test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | provenance | Sink:MaD:381 | -| test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | provenance | Sink:MaD:382 | -| test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | provenance | Sink:MaD:383 | -| test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | provenance | Sink:MaD:384 | -| test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | provenance | Sink:MaD:385 | -| test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | provenance | Sink:MaD:386 | -| test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | provenance | Sink:MaD:387 | -| test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | provenance | Sink:MaD:388 | -| test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | provenance | Sink:MaD:389 | -| test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | provenance | Sink:MaD:390 | -| test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | provenance | Sink:MaD:391 | -| test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | provenance | Sink:MaD:392 | -| test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | provenance | Sink:MaD:393 | -| test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | provenance | Sink:MaD:394 | -| test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | provenance | Sink:MaD:395 | -| test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | provenance | Sink:MaD:396 | -| test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | provenance | Sink:MaD:397 | -| test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | provenance | Sink:MaD:398 | -| test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | provenance | Sink:MaD:399 | -| test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | provenance | Sink:MaD:400 | -| test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | provenance | Sink:MaD:401 | +| test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | provenance | Sink:MaD:1 | +| test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | provenance | Sink:MaD:2 | +| test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | provenance | Sink:MaD:3 | +| test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | provenance | Sink:MaD:4 | +| test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | provenance | Sink:MaD:5 | +| test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | provenance | Sink:MaD:6 | +| test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | provenance | Sink:MaD:7 | +| test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | provenance | Sink:MaD:8 | +| test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | provenance | Sink:MaD:9 | +| test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | provenance | Sink:MaD:10 | +| test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | provenance | Sink:MaD:11 | +| test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | provenance | Sink:MaD:12 | +| test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | provenance | Sink:MaD:13 | +| test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | provenance | Sink:MaD:14 | +| test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | provenance | Sink:MaD:15 | +| test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | provenance | Sink:MaD:16 | +| test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | provenance | Sink:MaD:17 | +| test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | provenance | Sink:MaD:18 | +| test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | provenance | Sink:MaD:19 | +| test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | provenance | Sink:MaD:20 | +| test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | provenance | Sink:MaD:21 | +| test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | provenance | Sink:MaD:22 | | test.go:153:17:153:24 | definition of password | test.go:187:16:187:23 | password | provenance | | +models +| 1 | Sink: group:beego-logs; ; false; Alert; ; ; Argument[0..1]; log-injection; manual | +| 2 | Sink: group:beego-logs; ; false; Critical; ; ; Argument[0..1]; log-injection; manual | +| 3 | Sink: group:beego-logs; ; false; Debug; ; ; Argument[0..1]; log-injection; manual | +| 4 | Sink: group:beego-logs; ; false; Emergency; ; ; Argument[0..1]; log-injection; manual | +| 5 | Sink: group:beego-logs; ; false; Error; ; ; Argument[0..1]; log-injection; manual | +| 6 | Sink: group:beego-logs; ; false; Info; ; ; Argument[0..1]; log-injection; manual | +| 7 | Sink: group:beego-logs; ; false; Informational; ; ; Argument[0..1]; log-injection; manual | +| 8 | Sink: group:beego-logs; ; false; Notice; ; ; Argument[0..1]; log-injection; manual | +| 9 | Sink: group:beego-logs; ; false; Trace; ; ; Argument[0..1]; log-injection; manual | +| 10 | Sink: group:beego-logs; ; false; Warn; ; ; Argument[0..1]; log-injection; manual | +| 11 | Sink: group:beego-logs; ; false; Warning; ; ; Argument[0..1]; log-injection; manual | +| 12 | Sink: group:beego-logs; BeeLogger; true; Alert; ; ; Argument[0..1]; log-injection; manual | +| 13 | Sink: group:beego-logs; BeeLogger; true; Critical; ; ; Argument[0..1]; log-injection; manual | +| 14 | Sink: group:beego-logs; BeeLogger; true; Debug; ; ; Argument[0..1]; log-injection; manual | +| 15 | Sink: group:beego-logs; BeeLogger; true; Emergency; ; ; Argument[0..1]; log-injection; manual | +| 16 | Sink: group:beego-logs; BeeLogger; true; Error; ; ; Argument[0..1]; log-injection; manual | +| 17 | Sink: group:beego-logs; BeeLogger; true; Info; ; ; Argument[0..1]; log-injection; manual | +| 18 | Sink: group:beego-logs; BeeLogger; true; Informational; ; ; Argument[0..1]; log-injection; manual | +| 19 | Sink: group:beego-logs; BeeLogger; true; Notice; ; ; Argument[0..1]; log-injection; manual | +| 20 | Sink: group:beego-logs; BeeLogger; true; Trace; ; ; Argument[0..1]; log-injection; manual | +| 21 | Sink: group:beego-logs; BeeLogger; true; Warn; ; ; Argument[0..1]; log-injection; manual | +| 22 | Sink: group:beego-logs; BeeLogger; true; Warning; ; ; Argument[0..1]; log-injection; manual | nodes | test.go:153:17:153:24 | definition of password | semmle.label | definition of password | | test.go:154:14:154:21 | password | semmle.label | password | @@ -70,38 +128,3 @@ nodes | test.go:186:17:186:24 | password | semmle.label | password | | test.go:187:16:187:23 | password | semmle.label | password | subpaths -#select -| test.go:154:14:154:21 | password | test.go:153:17:153:24 | definition of password | test.go:154:14:154:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:155:17:155:24 | password | test.go:153:17:153:24 | definition of password | test.go:155:17:155:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:156:14:156:21 | password | test.go:153:17:153:24 | definition of password | test.go:156:14:156:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:157:18:157:25 | password | test.go:153:17:153:24 | definition of password | test.go:157:18:157:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:158:14:158:21 | password | test.go:153:17:153:24 | definition of password | test.go:158:14:158:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:159:13:159:20 | password | test.go:153:17:153:24 | definition of password | test.go:159:13:159:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:160:22:160:29 | password | test.go:153:17:153:24 | definition of password | test.go:160:22:160:29 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:161:15:161:22 | password | test.go:153:17:153:24 | definition of password | test.go:161:15:161:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:162:14:162:21 | password | test.go:153:17:153:24 | definition of password | test.go:162:14:162:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:163:13:163:20 | password | test.go:153:17:153:24 | definition of password | test.go:163:13:163:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:164:16:164:23 | password | test.go:153:17:153:24 | definition of password | test.go:164:16:164:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:165:13:165:20 | password | test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:166:16:166:23 | password | test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:167:13:167:20 | password | test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:168:17:168:24 | password | test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:169:13:169:20 | password | test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:170:12:170:19 | password | test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:171:21:171:28 | password | test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:172:14:172:21 | password | test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:173:13:173:20 | password | test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:174:12:174:19 | password | test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:175:15:175:22 | password | test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:176:15:176:22 | password | test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:177:18:177:25 | password | test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:178:15:178:22 | password | test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:179:19:179:26 | password | test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:180:15:180:22 | password | test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:181:14:181:21 | password | test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:182:23:182:30 | password | test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:183:16:183:23 | password | test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:184:15:184:22 | password | test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:185:14:185:21 | password | test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:186:17:186:24 | password | test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | -| test.go:187:16:187:23 | password | test.go:153:17:153:24 | definition of password | test.go:187:16:187:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.qlref index 21eebbd09beb..693299c33a21 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.qlref @@ -1 +1,4 @@ -Security/CWE-312/CleartextLogging.ql +query: Security/CWE-312/CleartextLogging.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.expected index c624f05d450e..4dca9d050d71 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.expected @@ -1,3 +1,6 @@ +#select +| test.go:253:13:253:34 | call to GetString | test.go:253:13:253:34 | call to GetString | test.go:253:13:253:34 | call to GetString | This path to an untrusted URL redirection depends on a $@. | test.go:253:13:253:34 | call to GetString | user-provided value | +| test.go:254:20:254:41 | call to GetString | test.go:254:20:254:41 | call to GetString | test.go:254:20:254:41 | call to GetString | This path to an untrusted URL redirection depends on a $@. | test.go:254:20:254:41 | call to GetString | user-provided value | edges nodes | test.go:253:13:253:34 | call to GetString | semmle.label | call to GetString | @@ -5,6 +8,3 @@ nodes | test.go:317:13:317:27 | call to URI | semmle.label | call to URI | | test.go:318:20:318:34 | call to URL | semmle.label | call to URL | subpaths -#select -| test.go:253:13:253:34 | call to GetString | test.go:253:13:253:34 | call to GetString | test.go:253:13:253:34 | call to GetString | This path to an untrusted URL redirection depends on a $@. | test.go:253:13:253:34 | call to GetString | user-provided value | -| test.go:254:20:254:41 | call to GetString | test.go:254:20:254:41 | call to GetString | test.go:254:20:254:41 | call to GetString | This path to an untrusted URL redirection depends on a $@. | test.go:254:20:254:41 | call to GetString | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.qlref index 0f1a74778256..13add930f517 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.qlref @@ -1 +1,4 @@ -Security/CWE-601/OpenUrlRedirect.ql +query: Security/CWE-601/OpenUrlRedirect.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.qlref index 754513d72bb3..e6b791f39fca 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.qlref @@ -1,2 +1,4 @@ query: Security/CWE-079/ReflectedXss.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.qlref index 78ce25b1921f..6eb2e94892f2 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.qlref @@ -1,2 +1,4 @@ query: Security/CWE-022/TaintedPath.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/test.go b/go/ql/test/library-tests/semmle/go/frameworks/Beego/test.go index d702f4a54450..38cb06691f83 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/test.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/test.go @@ -31,75 +31,75 @@ type bindMe struct { // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromBind(input *context.BeegoInput, sink http.ResponseWriter) { var bound bindMe - input.Bind(bound, "someKey") - sink.Write([]byte(bound.a[0])) - sink.Write([]byte(bound.b)) - sink.Write([]byte(bound.c.z)) + input.Bind(bound, "someKey") // $ Source[go/reflected-xss] + sink.Write([]byte(bound.a[0])) // $ Alert[go/reflected-xss] + sink.Write([]byte(bound.b)) // $ Alert[go/reflected-xss] + sink.Write([]byte(bound.c.z)) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromCookie(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.Cookie("someKey"))) + sink.Write([]byte(input.Cookie("someKey"))) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromData(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.Data()["someKey"].(string))) + sink.Write([]byte(input.Data()["someKey"].(string))) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromGetData(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.GetData("someKey").(string))) + sink.Write([]byte(input.GetData("someKey").(string))) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromHeader(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.Header("someKey"))) + sink.Write([]byte(input.Header("someKey"))) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromParam(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.Param("someKey"))) + sink.Write([]byte(input.Param("someKey"))) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromParams(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.Params()["someKey"])) + sink.Write([]byte(input.Params()["someKey"])) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromQuery(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.Query("someKey"))) + sink.Write([]byte(input.Query("someKey"))) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromRefer(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.Refer())) + sink.Write([]byte(input.Refer())) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromReferer(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.Referer())) + sink.Write([]byte(input.Referer())) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromURI(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.URI())) + sink.Write([]byte(input.URI())) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromURL(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.URL())) + sink.Write([]byte(input.URL())) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data to an `http.ResponseWriter` func xssFromUserAgent(input *context.BeegoInput, sink http.ResponseWriter) { - sink.Write([]byte(input.UserAgent())) + sink.Write([]byte(input.UserAgent())) // $ Alert[go/reflected-xss] } // BAD: with no obvious ContentType call we assume this could be text/html. func echoToBodyNoContentType(input *context.BeegoInput, output *context.BeegoOutput) { - output.Body(input.Data()["someKey"].([]byte)) + output.Body(input.Data()["someKey"].([]byte)) // $ Alert[go/reflected-xss] } // OK: JSON can't (by itself) cause XSS @@ -111,7 +111,7 @@ func echoToBodyContentTypeJson(input *context.BeegoInput, output *context.BeegoO // BAD: echoing untrusted data with an HTML content type func echoToBodyContentTypeHtml(input *context.BeegoInput, output *context.BeegoOutput) { output.ContentType("text/html") - output.Body(input.Data()["someKey"].([]byte)) + output.Body(input.Data()["someKey"].([]byte)) // $ Alert[go/reflected-xss] } // OK: JSON can't (by itself) cause XSS @@ -123,7 +123,7 @@ func echoToBodyContentTypeJsonUsingHeader(input *context.BeegoInput, output *con // BAD: echoing untrusted data with an HTML content type func echoToBodyContentTypeHtmlUsingHeader(input *context.BeegoInput, output *context.BeegoOutput) { output.Header("content-type", "text/html") - output.Body(input.Data()["someKey"].([]byte)) + output.Body(input.Data()["someKey"].([]byte)) // $ Alert[go/reflected-xss] } // OK: JSON and other non-HTML formats can't (by themselves) cause XSS @@ -140,7 +140,7 @@ func echoToFixedContentTypeRoutines(input *context.BeegoInput, output *context.B func echoToBodyContentTypeHtmlUsingHandler() { beego.Post("", func(context *context.Context) { context.Output.Header("content-type", "text/html") - context.Output.Body(context.Input.Data()["someKey"].([]byte)) + context.Output.Body(context.Input.Data()["someKey"].([]byte)) // $ Alert[go/reflected-xss] }) } @@ -150,41 +150,41 @@ func echoToBodySanitized(input *context.BeegoInput, output *context.BeegoOutput) } // BAD: logging something named "password". -func loggerTest(password string, logger *logs.BeeLogger) { - beego.Alert(password) - beego.Critical(password) - beego.Debug(password) - beego.Emergency(password) - beego.Error(password) - beego.Info(password) - beego.Informational(password) - beego.Notice(password) - beego.Trace(password) - beego.Warn(password) - beego.Warning(password) - logs.Alert(password) - logs.Critical(password) - logs.Debug(password) - logs.Emergency(password) - logs.Error(password) - logs.Info(password) - logs.Informational(password) - logs.Notice(password) - logs.Trace(password) - logs.Warn(password) - logs.Warning(password) - logger.Alert(password) - logger.Critical(password) - logger.Debug(password) - logger.Emergency(password) - logger.Error(password) - logger.Info(password) - logger.Informational(password) - logger.Notice(password) - logger.Trace(password) - logger.Warn(password) - logger.Warning(password) - utils.Display(password) +func loggerTest(password string, logger *logs.BeeLogger) { // $ Source[go/clear-text-logging] + beego.Alert(password) // $ Alert[go/clear-text-logging] + beego.Critical(password) // $ Alert[go/clear-text-logging] + beego.Debug(password) // $ Alert[go/clear-text-logging] + beego.Emergency(password) // $ Alert[go/clear-text-logging] + beego.Error(password) // $ Alert[go/clear-text-logging] + beego.Info(password) // $ Alert[go/clear-text-logging] + beego.Informational(password) // $ Alert[go/clear-text-logging] + beego.Notice(password) // $ Alert[go/clear-text-logging] + beego.Trace(password) // $ Alert[go/clear-text-logging] + beego.Warn(password) // $ Alert[go/clear-text-logging] + beego.Warning(password) // $ Alert[go/clear-text-logging] + logs.Alert(password) // $ Alert[go/clear-text-logging] + logs.Critical(password) // $ Alert[go/clear-text-logging] + logs.Debug(password) // $ Alert[go/clear-text-logging] + logs.Emergency(password) // $ Alert[go/clear-text-logging] + logs.Error(password) // $ Alert[go/clear-text-logging] + logs.Info(password) // $ Alert[go/clear-text-logging] + logs.Informational(password) // $ Alert[go/clear-text-logging] + logs.Notice(password) // $ Alert[go/clear-text-logging] + logs.Trace(password) // $ Alert[go/clear-text-logging] + logs.Warn(password) // $ Alert[go/clear-text-logging] + logs.Warning(password) // $ Alert[go/clear-text-logging] + logger.Alert(password) // $ Alert[go/clear-text-logging] + logger.Critical(password) // $ Alert[go/clear-text-logging] + logger.Debug(password) // $ Alert[go/clear-text-logging] + logger.Emergency(password) // $ Alert[go/clear-text-logging] + logger.Error(password) // $ Alert[go/clear-text-logging] + logger.Info(password) // $ Alert[go/clear-text-logging] + logger.Informational(password) // $ Alert[go/clear-text-logging] + logger.Notice(password) // $ Alert[go/clear-text-logging] + logger.Trace(password) // $ Alert[go/clear-text-logging] + logger.Warn(password) // $ Alert[go/clear-text-logging] + logger.Warning(password) // $ Alert[go/clear-text-logging] + utils.Display(password) // $ Alert[go/clear-text-logging] } type myStruct struct { @@ -196,83 +196,83 @@ func sanitizersTest(ctx *context.Context) { input := ctx.Input output := ctx.Output - untrusted := input.Data()["someKey"] - output.Body([]byte(beego.HTML2str(untrusted.(string)))) - output.Body([]byte(beego.Htmlunquote(untrusted.(string)))) + untrusted := input.Data()["someKey"] // $ Source[go/reflected-xss] + output.Body([]byte(beego.HTML2str(untrusted.(string)))) // $ Alert[go/reflected-xss] + output.Body([]byte(beego.Htmlunquote(untrusted.(string)))) // $ Alert[go/reflected-xss] mapVal, _ := beego.MapGet(untrusted.(map[string][]byte), "somekey") - output.Body(mapVal.([]byte)) - output.Body([]byte(beego.Str2html(untrusted.(string)))) - output.Body([]byte(beego.Substr(untrusted.(string), 1, 2))) + output.Body(mapVal.([]byte)) // $ Alert[go/reflected-xss] + output.Body([]byte(beego.Str2html(untrusted.(string)))) // $ Alert[go/reflected-xss] + output.Body([]byte(beego.Substr(untrusted.(string), 1, 2))) // $ Alert[go/reflected-xss] var s myStruct - beego.ParseForm(ctx.Request.Form, s) - output.Body([]byte(s.field)) + beego.ParseForm(ctx.Request.Form, s) // $ Source[go/reflected-xss] + output.Body([]byte(s.field)) // $ Alert[go/reflected-xss] } // BAD: using user-provided data as paths in file-system operations func fsOpsTest(ctx *context.Context, c *beego.Controller, fs beego.FileSystem) { input := ctx.Input - untrusted := input.Data()["someKey"].(string) - beego.Walk(nil, untrusted, func(path string, info os.FileInfo, err error) error { return nil }) - fs.Open(untrusted) - c.SaveToFile("someReceviedFile", untrusted) + untrusted := input.Data()["someKey"].(string) // $ Source[go/path-injection] + beego.Walk(nil, untrusted, func(path string, info os.FileInfo, err error) error { return nil }) // $ Alert[go/path-injection] + fs.Open(untrusted) // $ Alert[go/path-injection] + c.SaveToFile("someReceviedFile", untrusted) // $ Alert[go/path-injection] } // BAD: echoing untrusted data, using various Controller sources func controllerSourceTest(c *beego.Controller, output *context.BeegoOutput) { - f, fh, _ := c.GetFile("somename") - output.Body([]byte(fh.Filename)) + f, fh, _ := c.GetFile("somename") // $ Source[go/reflected-xss] + output.Body([]byte(fh.Filename)) // $ Alert[go/reflected-xss] content, _ := ioutil.ReadAll(f) - output.Body(content) + output.Body(content) // $ Alert[go/reflected-xss] - files, _ := c.GetFiles("someothername") - output.Body([]byte(files[0].Filename)) + files, _ := c.GetFiles("someothername") // $ Source[go/reflected-xss] + output.Body([]byte(files[0].Filename)) // $ Alert[go/reflected-xss] - s := c.GetString("somekey") - output.Body([]byte(s)) + s := c.GetString("somekey") // $ Source[go/reflected-xss] + output.Body([]byte(s)) // $ Alert[go/reflected-xss] - ss := c.GetStrings("someotherkey") - output.Body([]byte(ss[0])) + ss := c.GetStrings("someotherkey") // $ Source[go/reflected-xss] + output.Body([]byte(ss[0])) // $ Alert[go/reflected-xss] - val := c.Input()["thirdkey"] - output.Body([]byte(val[0])) + val := c.Input()["thirdkey"] // $ Source[go/reflected-xss] + output.Body([]byte(val[0])) // $ Alert[go/reflected-xss] var str myStruct - c.ParseForm(str) - output.Body([]byte(str.field)) + c.ParseForm(str) // $ Source[go/reflected-xss] + output.Body([]byte(str.field)) // $ Alert[go/reflected-xss] } func controllerSinkTest(c *beego.Controller) { - untrusted := c.GetString("somekey") - c.SetData(untrusted) // GOOD: SetData always uses a non-html content-type, so no XSS risk + untrusted := c.GetString("somekey") // $ Source[go/reflected-xss] + c.SetData(untrusted) // GOOD: SetData always uses a non-html content-type, so no XSS risk - c.CustomAbort(500, untrusted) // BAD: CustomAbort doesn't set a content-type, so there is an XSS risk + c.CustomAbort(500, untrusted) // $ Alert[go/reflected-xss] // BAD: CustomAbort doesn't set a content-type, so there is an XSS risk } func redirectTest(c *beego.Controller, ctx *context.Context) { - c.Redirect(c.GetString("somekey"), 304) // BAD: User-controlled redirect - ctx.Redirect(304, c.GetString("somekey")) // BAD: User-controlled redirect + c.Redirect(c.GetString("somekey"), 304) // $ Alert[go/unvalidated-url-redirection] + ctx.Redirect(304, c.GetString("somekey")) // $ Alert[go/unvalidated-url-redirection] } // BAD: echoing untrusted data, using Context source func contextSourceTest(c *context.Context) { - c.Output.Body([]byte(c.GetCookie("somekey"))) + c.Output.Body([]byte(c.GetCookie("somekey"))) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data, using Context sinks func contextSinkTest(c *context.Context) { - c.WriteString(c.GetCookie("somekey")) - c.Abort(500, c.GetCookie("someOtherKey")) + c.WriteString(c.GetCookie("somekey")) // $ Alert[go/reflected-xss] + c.Abort(500, c.GetCookie("someOtherKey")) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data, using context.WriteBody as a propagator func contextWriteBodyTest(c *context.Context) { - context.WriteBody("some/encoding", c.ResponseWriter, []byte(c.GetCookie("someKey"))) + context.WriteBody("some/encoding", c.ResponseWriter, []byte(c.GetCookie("someKey"))) // $ Alert[go/reflected-xss] } // BAD unless otherwise noted: echoing untrusted data, using various utils methods as propagators func testUtilsPropagators(c *beego.Controller) { - files, _ := c.GetFiles("someothername") + files, _ := c.GetFiles("someothername") // $ Source[go/reflected-xss] genericFiles := make([]interface{}, len(files), len(files)) for i := range files { genericFiles[i] = files[i] @@ -280,36 +280,36 @@ func testUtilsPropagators(c *beego.Controller) { untainted := make([]interface{}, 1, 1) - c.CustomAbort(500, utils.GetDisplayString(files[0].Filename)) - c.CustomAbort(500, utils.SliceChunk(genericFiles, 1)[0][0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SliceDiff(genericFiles, untainted)[0].(*multipart.FileHeader).Filename) + c.CustomAbort(500, utils.GetDisplayString(files[0].Filename)) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SliceChunk(genericFiles, 1)[0][0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SliceDiff(genericFiles, untainted)[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] // GOOD: the tainted values are subtracted, so taint is not propagated c.CustomAbort(500, utils.SliceDiff(untainted, genericFiles)[0].(*multipart.FileHeader).Filename) c.CustomAbort( 500, utils.SliceFilter( genericFiles, - func([]interface{}) bool { return true })[0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SliceIntersect(genericFiles, untainted)[0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SliceIntersect(untainted, genericFiles)[0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SliceMerge(genericFiles, untainted)[0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SliceMerge(untainted, genericFiles)[0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SlicePad(untainted, 10, genericFiles[0])[0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SlicePad(genericFiles, 10, untainted[0])[0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SliceRand(genericFiles).(*multipart.FileHeader).Filename) + func([]interface{}) bool { return true })[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SliceIntersect(genericFiles, untainted)[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SliceIntersect(untainted, genericFiles)[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SliceMerge(genericFiles, untainted)[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SliceMerge(untainted, genericFiles)[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SlicePad(untainted, 10, genericFiles[0])[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SlicePad(genericFiles, 10, untainted[0])[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SliceRand(genericFiles).(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] // Note this is misnamed -- it's a map operation, not a reduce - c.CustomAbort(500, utils.SliceReduce(genericFiles, func(x interface{}) interface{} { return x })[0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SliceShuffle(genericFiles)[0].(*multipart.FileHeader).Filename) - c.CustomAbort(500, utils.SliceUnique(genericFiles)[0].(*multipart.FileHeader).Filename) + c.CustomAbort(500, utils.SliceReduce(genericFiles, func(x interface{}) interface{} { return x })[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SliceShuffle(genericFiles)[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] + c.CustomAbort(500, utils.SliceUnique(genericFiles)[0].(*multipart.FileHeader).Filename) // $ Alert[go/reflected-xss] } // BAD: echoing untrusted data, using BeeMap as an intermediary func testBeeMap(c *beego.Controller) { bMap := utils.NewBeeMap() - untrusted := c.GetString("someKey") + untrusted := c.GetString("someKey") // $ Source[go/reflected-xss] bMap.Set("someKey", untrusted) - c.CustomAbort(500, bMap.Get("someKey").(string)) - c.CustomAbort(500, bMap.Items()["someKey"].(string)) + c.CustomAbort(500, bMap.Get("someKey").(string)) // $ Alert[go/reflected-xss] + c.CustomAbort(500, bMap.Items()["someKey"].(string)) // $ Alert[go/reflected-xss] } // GOOD: using the input URL for a redirect operation @@ -321,25 +321,25 @@ func testSafeRedirects(c *beego.Controller, ctx *context.Context) { // BAD: using RequestBody data as path in a file-system operation func requestBodySourceTest(ctx *context.Context, c *beego.Controller) { var dat map[string]interface{} - json.Unmarshal(ctx.Input.RequestBody, &dat) + json.Unmarshal(ctx.Input.RequestBody, &dat) // $ Source[go/path-injection] untrusted := dat["filepath"].(string) - c.SaveToFile("someReceviedFile", untrusted) + c.SaveToFile("someReceviedFile", untrusted) // $ Alert[go/path-injection] } // BAD: using user-provided data as paths in file-system operations func fsOpsTest2(ctx *context.Context, c *beego.Controller, fs beego.FileSystem) { input := ctx.Input - untrusted := input.Data()["someKey"].(string) + untrusted := input.Data()["someKey"].(string) // $ Source[go/path-injection] beegoOutput := context.BeegoOutput{} - beegoOutput.Download(untrusted, "license.txt") + beegoOutput.Download(untrusted, "license.txt") // $ Alert[go/path-injection] } // BAD: using user-provided data as paths in file-system operations func fsOpsV2Test(ctx *Beegov2Context.Context, c *beegov2.Controller) { input := ctx.Input - untrusted := input.Data()["someKey"].(string) + untrusted := input.Data()["someKey"].(string) // $ Source[go/path-injection] buffer := make([]byte, 10) - _ = c.SaveToFileWithBuffer("filenameExistsInForm", untrusted, buffer) + _ = c.SaveToFileWithBuffer("filenameExistsInForm", untrusted, buffer) // $ Alert[go/path-injection] beegoOutput := Beegov2Context.BeegoOutput{} - beegoOutput.Download(untrusted, "license.txt") + beegoOutput.Download(untrusted, "license.txt") // $ Alert[go/path-injection] } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.ql b/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.ql index b0247c0e533a..147f3bbb2116 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.ql @@ -1,5 +1,4 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation import semmle.go.security.CommandInjection import codeql.dataflow.test.ProvenancePathGraph @@ -9,7 +8,7 @@ class UntrustedFunction extends Function { UntrustedFunction() { this.getName() = ["getUntrustedString", "getUntrustedBytes"] } } -class RemoteSource extends DataFlow::Node, RemoteFlowSource::Range { +class RemoteSource extends RemoteFlowSource::Range { RemoteSource() { this = any(UntrustedFunction f).getACall().getResult() } } diff --git a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index 0e1265b5c1e6..b95abaa47c50 100644 --- a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -6,8 +6,8 @@ | contenttype.go:79:11:79:14 | data | contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:73:10:73:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | | contenttype.go:91:4:91:7 | data | contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:88:10:88:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | | contenttype.go:114:50:114:53 | data | contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:113:10:113:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | -| reflectedxsstest.go:33:10:33:57 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:33:10:33:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | -| reflectedxsstest.go:34:10:34:62 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:10:34:62 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | +| reflectedxsstest.go:33:10:33:57 | type conversion | reflectedxsstest.go:30:2:30:44 | ... := ...[0] | reflectedxsstest.go:33:10:33:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:30:2:30:44 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | +| reflectedxsstest.go:34:10:34:62 | type conversion | reflectedxsstest.go:30:2:30:44 | ... := ...[1] | reflectedxsstest.go:34:10:34:62 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:30:2:30:44 | ... := ...[1] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | | reflectedxsstest.go:44:10:44:55 | type conversion | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:44:10:44:55 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | | reflectedxsstest.go:45:10:45:18 | byteSlice | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:45:10:45:18 | byteSlice | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | | reflectedxsstest.go:54:11:54:21 | type conversion | reflectedxsstest.go:51:14:51:18 | selection of URL | reflectedxsstest.go:54:11:54:21 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:51:14:51:18 | selection of URL | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | @@ -30,10 +30,11 @@ edges | contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data | provenance | Src:MaD:8 | | contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data | provenance | Src:MaD:8 | | contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | provenance | Src:MaD:8 | -| reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:32:30:32:33 | file | provenance | Src:MaD:7 | -| reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:46:34:60 | selection of Filename | provenance | Src:MaD:7 | -| reflectedxsstest.go:32:2:32:34 | ... := ...[0] | reflectedxsstest.go:33:49:33:55 | content | provenance | | -| reflectedxsstest.go:32:30:32:33 | file | reflectedxsstest.go:32:2:32:34 | ... := ...[0] | provenance | MaD:13 | +| reflectedxsstest.go:30:2:30:44 | ... := ...[0] | reflectedxsstest.go:31:30:31:33 | file | provenance | Src:MaD:7 | +| reflectedxsstest.go:30:2:30:44 | ... := ...[1] | reflectedxsstest.go:34:46:34:60 | selection of Filename | provenance | Src:MaD:7 | +| reflectedxsstest.go:31:2:31:34 | ... := ...[0] | reflectedxsstest.go:32:48:32:54 | content | provenance | | +| reflectedxsstest.go:31:30:31:33 | file | reflectedxsstest.go:31:2:31:34 | ... := ...[0] | provenance | MaD:13 | +| reflectedxsstest.go:32:48:32:54 | content | reflectedxsstest.go:33:49:33:55 | content | provenance | | | reflectedxsstest.go:33:17:33:56 | []type{args} [array] | reflectedxsstest.go:33:17:33:56 | call to Sprintf | provenance | MaD:12 | | reflectedxsstest.go:33:17:33:56 | call to Sprintf | reflectedxsstest.go:33:10:33:57 | type conversion | provenance | | | reflectedxsstest.go:33:49:33:55 | content | reflectedxsstest.go:33:17:33:56 | []type{args} [array] | provenance | | @@ -106,10 +107,11 @@ nodes | contenttype.go:91:4:91:7 | data | semmle.label | data | | contenttype.go:113:10:113:28 | call to FormValue | semmle.label | call to FormValue | | contenttype.go:114:50:114:53 | data | semmle.label | data | -| reflectedxsstest.go:31:2:31:44 | ... := ...[0] | semmle.label | ... := ...[0] | -| reflectedxsstest.go:31:2:31:44 | ... := ...[1] | semmle.label | ... := ...[1] | -| reflectedxsstest.go:32:2:32:34 | ... := ...[0] | semmle.label | ... := ...[0] | -| reflectedxsstest.go:32:30:32:33 | file | semmle.label | file | +| reflectedxsstest.go:30:2:30:44 | ... := ...[0] | semmle.label | ... := ...[0] | +| reflectedxsstest.go:30:2:30:44 | ... := ...[1] | semmle.label | ... := ...[1] | +| reflectedxsstest.go:31:2:31:34 | ... := ...[0] | semmle.label | ... := ...[0] | +| reflectedxsstest.go:31:30:31:33 | file | semmle.label | file | +| reflectedxsstest.go:32:48:32:54 | content | semmle.label | content | | reflectedxsstest.go:33:10:33:57 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:33:17:33:56 | []type{args} [array] | semmle.label | []type{args} [array] | | reflectedxsstest.go:33:17:33:56 | call to Sprintf | semmle.label | call to Sprintf | diff --git a/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go b/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go index b3ddc79535b4..ce708a2c7d78 100644 --- a/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go +++ b/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go @@ -25,11 +25,11 @@ func ServeJsonDirect(w http.ResponseWriter, r http.Request) { func ErrTest(w http.ResponseWriter, r http.Request) { cookie, err := r.Cookie("somecookie") - w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // GOOD: Cookie's value is not user-controlled in reflected xss. - w.Write([]byte(fmt.Sprintf("Cookie check error: %v", err))) // GOOD: Cookie's err return is harmless - http.Error(w, fmt.Sprintf("Cookie result: %v", cookie), 500) // Good: only plain text is written. - file, header, err := r.FormFile("someFile") // $ Source[go/reflected-xss] + w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // GOOD: Cookie's value is not user-controlled in reflected xss. + w.Write([]byte(fmt.Sprintf("Cookie check error: %v", err))) // GOOD: Cookie's err return is harmless + file, header, err := r.FormFile("someFile") // $ Source[go/reflected-xss] content, err2 := io.ReadAll(file) + http.Error(w, fmt.Sprintf("File content: %v", content), 500) // Good: only plain text is written. w.Write([]byte(fmt.Sprintf("File content: %v", content))) // $ Alert[go/reflected-xss] // BAD: file content is user-controlled w.Write([]byte(fmt.Sprintf("File name: %v", header.Filename))) // $ Alert[go/reflected-xss] // BAD: file header is user-controlled w.Write([]byte(fmt.Sprintf("FormFile error: %v", err))) // GOOD: FormFile's err return is harmless