diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll index 08a86092afbb..57dfcd29117f 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll @@ -35,6 +35,11 @@ private class DefaultIntentRedirectionSink extends IntentRedirectionSink { DefaultIntentRedirectionSink() { sinkNode(this, "intent-redirection") } } +/** External sanitizers for Intent redirection vulnerabilities. */ +private class ExternalIntentRedirectionSanitizer extends IntentRedirectionSanitizer { + ExternalIntentRedirectionSanitizer() { barrierNode(this, "intent-redirection") } +} + /** * A default sanitizer for `Intent` nodes dominated by calls to `ComponentName.getPackageName` * and `ComponentName.getClassName`. These are used to check whether the origin or destination diff --git a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll index b6b9d02e289d..273c5360b815 100644 --- a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll @@ -37,6 +37,10 @@ private class DefaultCommandInjectionSink extends CommandInjectionSink { DefaultCommandInjectionSink() { sinkNode(this, "command-injection") } } +private class ExternalCommandInjectionSanitizer extends CommandInjectionSanitizer { + ExternalCommandInjectionSanitizer() { barrierNode(this, "command-injection") } +} + private class DefaultCommandInjectionSanitizer extends CommandInjectionSanitizer { DefaultCommandInjectionSanitizer() { this instanceof SimpleTypeSanitizer diff --git a/java/ql/lib/semmle/code/java/security/FragmentInjection.qll b/java/ql/lib/semmle/code/java/security/FragmentInjection.qll index 8cd5e32a5ecd..7e6170ff9283 100644 --- a/java/ql/lib/semmle/code/java/security/FragmentInjection.qll +++ b/java/ql/lib/semmle/code/java/security/FragmentInjection.qll @@ -49,6 +49,13 @@ private class DefaultFragmentInjectionSink extends FragmentInjectionSink { DefaultFragmentInjectionSink() { sinkNode(this, "fragment-injection") } } +/** A barrier for Fragment injection vulnerabilities. */ +abstract class FragmentInjectionSanitizer extends DataFlow::Node { } + +private class ExternalFragmentInjectionSanitizer extends FragmentInjectionSanitizer { + ExternalFragmentInjectionSanitizer() { barrierNode(this, "fragment-injection") } +} + private class DefaultFragmentInjectionAdditionalTaintStep extends FragmentInjectionAdditionalTaintStep { override predicate step(DataFlow::Node n1, DataFlow::Node n2) { diff --git a/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll index 40636ffd8c25..1cb9f711b6fa 100644 --- a/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll @@ -14,6 +14,8 @@ module FragmentInjectionTaintConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof FragmentInjectionSink } + predicate isBarrier(DataFlow::Node node) { node instanceof FragmentInjectionSanitizer } + predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { any(FragmentInjectionAdditionalTaintStep c).step(n1, n2) } diff --git a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll index 45d664897775..d9a5db7b12d3 100644 --- a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll +++ b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll @@ -26,6 +26,13 @@ private class DefaultGroovyInjectionSink extends GroovyInjectionSink { DefaultGroovyInjectionSink() { sinkNode(this, "groovy-injection") } } +/** A data flow sanitizer for Groovy expression injection vulnerabilities. */ +abstract class GroovyInjectionSanitizer extends DataFlow::ExprNode { } + +private class ExternalGroovyInjectionSanitizer extends GroovyInjectionSanitizer { + ExternalGroovyInjectionSanitizer() { barrierNode(this, "groovy-injection") } +} + /** A set of additional taint steps to consider when taint tracking Groovy related data flows. */ private class DefaultGroovyInjectionAdditionalTaintStep extends GroovyInjectionAdditionalTaintStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { diff --git a/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll index b497873b9bb1..af4645b15917 100644 --- a/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll @@ -14,6 +14,8 @@ module GroovyInjectionConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof GroovyInjectionSink } + predicate isBarrier(DataFlow::Node node) { node instanceof GroovyInjectionSanitizer } + predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { any(GroovyInjectionAdditionalTaintStep c).step(fromNode, toNode) } diff --git a/java/ql/lib/semmle/code/java/security/HttpsUrls.qll b/java/ql/lib/semmle/code/java/security/HttpsUrls.qll index 071f95b49902..10e4553f9ae8 100644 --- a/java/ql/lib/semmle/code/java/security/HttpsUrls.qll +++ b/java/ql/lib/semmle/code/java/security/HttpsUrls.qll @@ -8,6 +8,7 @@ private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.frameworks.ApacheHttp private import semmle.code.java.frameworks.Networking +private import semmle.code.java.security.Sanitizers /** * String of HTTP URLs not in private domains. @@ -36,6 +37,17 @@ private class DefaultUrlOpenSink extends UrlOpenSink { DefaultUrlOpenSink() { sinkNode(this, "request-forgery") } } +/** + * A sanitizer to URL opening. + */ +abstract class UrlOpenSanitizer extends DataFlow::Node { } + +private class SimpleTypeUrlOpenSanitizer extends UrlOpenSanitizer instanceof SimpleTypeSanitizer { } + +private class ExternalUrlOpenSanitizer extends UrlOpenSanitizer { + ExternalUrlOpenSanitizer() { barrierNode(this, "request-forgery") } +} + /** * A unit class for adding additional taint steps. * diff --git a/java/ql/lib/semmle/code/java/security/HttpsUrlsQuery.qll b/java/ql/lib/semmle/code/java/security/HttpsUrlsQuery.qll index 1e67e3ca59a7..5f4e8489a713 100644 --- a/java/ql/lib/semmle/code/java/security/HttpsUrlsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/HttpsUrlsQuery.qll @@ -4,7 +4,6 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.frameworks.Networking import semmle.code.java.security.HttpsUrls -private import semmle.code.java.security.Sanitizers /** * A taint tracking configuration for HTTP connections. @@ -18,7 +17,7 @@ module HttpStringToUrlOpenMethodFlowConfig implements DataFlow::ConfigSig { any(HttpUrlsAdditionalTaintStep c).step(node1, node2) } - predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer } + predicate isBarrier(DataFlow::Node node) { node instanceof UrlOpenSanitizer } predicate observeDiffInformedIncrementalMode() { any() } } diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 94951c10c532..e3ca87b4825e 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -33,6 +33,9 @@ abstract class ImplicitPendingIntentSource extends ApiSourceNode { } /** A sink that sends an implicit and mutable `PendingIntent` to a third party. */ abstract class ImplicitPendingIntentSink extends DataFlow::Node { } +/** A sanitizer for sending an implicit and mutable `PendingIntent` to a third party. */ +abstract class ImplicitPendingIntentSanitizer extends DataFlow::Node { } + /** * A unit class for adding additional taint steps. * @@ -76,6 +79,15 @@ private class SendPendingIntent extends ImplicitPendingIntentSink { } } +private class ExplicitPendingIntentSanitizer extends ImplicitPendingIntentSanitizer instanceof ExplicitIntentSanitizer +{ } + +private class ExternalIntentRedirectionSanitizer extends ExplicitIntentSanitizer { + ExternalIntentRedirectionSanitizer() { + barrierNode(this, ["intent-redirection", "pending-intents"]) + } +} + private class MutablePendingIntentFlowStep extends ImplicitPendingIntentAdditionalTaintStep { override predicate mutablePendingIntentCreation(DataFlow::Node node1, DataFlow::Node node2) { exists(PendingIntentCreation pic, Argument flagArg | diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll index f66309c97bec..0bb96b706aaa 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll @@ -23,7 +23,9 @@ module ImplicitPendingIntentStartConfig implements DataFlow::StateConfigSig { sink instanceof ImplicitPendingIntentSink and state instanceof MutablePendingIntent } - predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof ExplicitIntentSanitizer } + predicate isBarrier(DataFlow::Node sanitizer) { + sanitizer instanceof ImplicitPendingIntentSanitizer + } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { any(ImplicitPendingIntentAdditionalTaintStep c).step(node1, node2) diff --git a/java/ql/lib/semmle/code/java/security/InformationLeak.qll b/java/ql/lib/semmle/code/java/security/InformationLeak.qll index ba7a7a52a707..64e979d4036a 100644 --- a/java/ql/lib/semmle/code/java/security/InformationLeak.qll +++ b/java/ql/lib/semmle/code/java/security/InformationLeak.qll @@ -17,3 +17,10 @@ private class DefaultInformationLeakSink extends InformationLeakSink { this instanceof XssSink } } + +/** A sanitizer for information leak. */ +abstract class InformationLeakSanitizer extends DataFlow::Node { } + +private class ExternalInformationLeakSanitizer extends InformationLeakSanitizer { + ExternalInformationLeakSanitizer() { barrierNode(this, "information-leak") } +} diff --git a/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll index e1c840ce2642..04876b5d8bb1 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll @@ -50,6 +50,8 @@ module BeanValidationConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof BeanValidationSink } + predicate isBarrier(DataFlow::Node node) { node instanceof BeanValidationSanitizer } + predicate observeDiffInformedIncrementalMode() { any() } } @@ -60,6 +62,15 @@ module BeanValidationFlow = TaintTracking::Global; * A bean validation sink, such as method `buildConstraintViolationWithTemplate` * declared on a subtype of `javax.validation.ConstraintValidatorContext`. */ -private class BeanValidationSink extends DataFlow::Node { - BeanValidationSink() { sinkNode(this, "bean-validation") } +abstract class BeanValidationSink extends DataFlow::Node { } + +private class ExternalBeanValidationSink extends BeanValidationSink { + ExternalBeanValidationSink() { sinkNode(this, "bean-validation") } +} + +/** A bean validation sanitizer. */ +abstract class BeanValidationSanitizer extends DataFlow::Node { } + +private class ExternalBeanValidationSanitizer extends BeanValidationSanitizer { + ExternalBeanValidationSanitizer() { barrierNode(this, "bean-validation") } } diff --git a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll index 4ad1dd3ba310..c11ebf1ae59f 100644 --- a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll @@ -16,6 +16,16 @@ private class DefaultJexlEvaluationSink extends JexlEvaluationSink { DefaultJexlEvaluationSink() { sinkNode(this, "jexl-injection") } } +/** + * A sink for Expresssion Language injection vulnerabilities via Jexl, + * that is, method calls that run evaluation of a JEXL expression. + */ +abstract class JexlEvaluationSanitizer extends DataFlow::ExprNode { } + +private class ExternalJexlEvaluationSanitizer extends JexlEvaluationSanitizer { + ExternalJexlEvaluationSanitizer() { barrierNode(this, "jexl-injection") } +} + /** * A unit class for adding additional taint steps. * @@ -48,6 +58,8 @@ module JexlInjectionConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink } + predicate isBarrier(DataFlow::Node node) { node instanceof JexlEvaluationSanitizer } + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { any(JexlInjectionAdditionalTaintStep c).step(node1, node2) } diff --git a/java/ql/lib/semmle/code/java/security/JndiInjection.qll b/java/ql/lib/semmle/code/java/security/JndiInjection.qll index 0e61a53c0ab0..cb41c2cf2063 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjection.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjection.qll @@ -34,6 +34,10 @@ private class DefaultJndiInjectionSink extends JndiInjectionSink { DefaultJndiInjectionSink() { sinkNode(this, "jndi-injection") } } +private class ExternalJndiInjectionSanitizer extends JndiInjectionSanitizer { + ExternalJndiInjectionSanitizer() { barrierNode(this, "jndi-injection") } +} + /** * A method that does a JNDI lookup when it receives a specific argument set to `true`. */ diff --git a/java/ql/lib/semmle/code/java/security/LdapInjection.qll b/java/ql/lib/semmle/code/java/security/LdapInjection.qll index ff92d40cf556..ad1cdbe49db2 100644 --- a/java/ql/lib/semmle/code/java/security/LdapInjection.qll +++ b/java/ql/lib/semmle/code/java/security/LdapInjection.qll @@ -38,6 +38,10 @@ private class DefaultLdapInjectionSink extends LdapInjectionSink { /** A sanitizer that clears the taint on (boxed) primitive types. */ private class DefaultLdapSanitizer extends LdapInjectionSanitizer instanceof SimpleTypeSanitizer { } +private class ExternalLdapInjectionSanitizer extends LdapInjectionSanitizer { + ExternalLdapInjectionSanitizer() { barrierNode(this, "ldap-injection") } +} + /** * Holds if `n1` to `n2` is a dataflow step that converts between `String` and `LdapName`, * i.e. `new LdapName(tainted)`. diff --git a/java/ql/lib/semmle/code/java/security/LogInjection.qll b/java/ql/lib/semmle/code/java/security/LogInjection.qll index da5a1dc73a0c..fdde5471e6d9 100644 --- a/java/ql/lib/semmle/code/java/security/LogInjection.qll +++ b/java/ql/lib/semmle/code/java/security/LogInjection.qll @@ -36,6 +36,10 @@ private class DefaultLogInjectionSink extends LogInjectionSink { private class DefaultLogInjectionSanitizer extends LogInjectionSanitizer instanceof SimpleTypeSanitizer { } +private class ExternalLogInjectionSanitizer extends LogInjectionSanitizer { + ExternalLogInjectionSanitizer() { barrierNode(this, "log-injection") } +} + private class LineBreaksLogInjectionSanitizer extends LogInjectionSanitizer { LineBreaksLogInjectionSanitizer() { logInjectionSanitizer(this.asExpr()) diff --git a/java/ql/lib/semmle/code/java/security/MvelInjection.qll b/java/ql/lib/semmle/code/java/security/MvelInjection.qll index dc804d4a1854..e6af37f9e4bb 100644 --- a/java/ql/lib/semmle/code/java/security/MvelInjection.qll +++ b/java/ql/lib/semmle/code/java/security/MvelInjection.qll @@ -37,6 +37,10 @@ private class DefaultMvelInjectionSanitizer extends MvelInjectionSanitizer { } } +private class ExternalMvelInjectionSanitizer extends MvelInjectionSanitizer { + ExternalMvelInjectionSanitizer() { barrierNode(this, "mvel-injection") } +} + /** A set of additional taint steps to consider when taint tracking MVEL related data flows. */ private class DefaultMvelInjectionAdditionalTaintStep extends MvelInjectionAdditionalTaintStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { diff --git a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll index e3f93b39ece1..c703916fa78d 100644 --- a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll +++ b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll @@ -7,6 +7,7 @@ private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.frameworks.MyBatis +private import semmle.code.java.security.Sanitizers /** * A data flow sink for unvalidated user input that is used in OGNL EL evaluation. @@ -15,6 +16,8 @@ private import semmle.code.java.frameworks.MyBatis */ abstract class OgnlInjectionSink extends ApiSinkNode { } +abstract class OgnlInjectionSanitizer extends DataFlow::Node { } + /** * A unit class for adding additional taint steps. * @@ -32,6 +35,13 @@ private class DefaultOgnlInjectionSink extends OgnlInjectionSink { DefaultOgnlInjectionSink() { sinkNode(this, "ognl-injection") } } +private class SimpleTypeOgnlInjectionSanitizer extends OgnlInjectionSanitizer instanceof SimpleTypeSanitizer +{ } + +private class ExternalOgnlInjectionSanitizer extends OgnlInjectionSanitizer { + ExternalOgnlInjectionSanitizer() { barrierNode(this, "ognl-injection") } +} + /** The class `org.apache.commons.ognl.Ognl` or `ognl.Ognl`. */ private class TypeOgnl extends Class { TypeOgnl() { this.hasQualifiedName(["org.apache.commons.ognl", "ognl"], "Ognl") } diff --git a/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll index d9bfad412599..9c1d24ed4ace 100644 --- a/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll @@ -3,7 +3,6 @@ import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.OgnlInjection -private import semmle.code.java.security.Sanitizers /** * A taint-tracking configuration for unvalidated user input that is used in OGNL EL evaluation. @@ -13,7 +12,7 @@ module OgnlInjectionFlowConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof OgnlInjectionSink } - predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer } + predicate isBarrier(DataFlow::Node node) { node instanceof OgnlInjectionSanitizer } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { any(OgnlInjectionAdditionalTaintStep c).step(node1, node2) diff --git a/java/ql/lib/semmle/code/java/security/QueryInjection.qll b/java/ql/lib/semmle/code/java/security/QueryInjection.qll index 583a41ce9335..509d7d9cebea 100644 --- a/java/ql/lib/semmle/code/java/security/QueryInjection.qll +++ b/java/ql/lib/semmle/code/java/security/QueryInjection.qll @@ -8,10 +8,14 @@ import semmle.code.java.frameworks.javaee.Persistence private import semmle.code.java.frameworks.MyBatis private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.security.Sanitizers /** A sink for database query language injection vulnerabilities. */ abstract class QueryInjectionSink extends ApiSinkNode { } +/** A sanitizer for query injection vulnerabilities. */ +abstract class QueryInjectionSanitizer extends DataFlow::Node { } + /** * A unit class for adding additional taint steps. * @@ -60,6 +64,13 @@ private class MongoDbInjectionSink extends QueryInjectionSink { } } +private class SimpleTypeQueryInjectionSanitizer extends QueryInjectionSanitizer instanceof SimpleTypeSanitizer +{ } + +private class ExternalQueryInjectionSanitizer extends QueryInjectionSanitizer { + ExternalQueryInjectionSanitizer() { barrierNode(this, "sql-injection") } +} + private class MongoJsonStep extends AdditionalQueryInjectionTaintStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { exists(MethodCall ma | diff --git a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll index 1238793ffd70..877b4d607d80 100644 --- a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll +++ b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll @@ -8,6 +8,7 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.frameworks.Servlets import semmle.code.java.frameworks.JaxWS private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.security.Sanitizers /** A sink that is vulnerable to an HTTP header splitting attack. */ abstract class HeaderSplittingSink extends DataFlow::Node { } @@ -16,6 +17,32 @@ private class DefaultHeaderSplittingSink extends HeaderSplittingSink { DefaultHeaderSplittingSink() { sinkNode(this, "response-splitting") } } +/** A sanitizer for an HTTP header splitting attack. */ +abstract class HeaderSplittingSanitizer extends DataFlow::Node { } + +private class SimpleTypeHeaderSplittingSanitizer extends HeaderSplittingSanitizer instanceof SimpleTypeSanitizer +{ } + +private class ExternalHeaderSplittingSanitizer extends HeaderSplittingSanitizer { + ExternalHeaderSplittingSanitizer() { barrierNode(this, "response-splitting") } +} + +private class NewlineRemovalHeaderSplittingSanitizer extends HeaderSplittingSanitizer { + NewlineRemovalHeaderSplittingSanitizer() { + exists(MethodCall ma, string methodName, CompileTimeConstantExpr target | + this.asExpr() = ma and + ma.getMethod().hasQualifiedName("java.lang", "String", methodName) and + target = ma.getArgument(0) and + ( + methodName = "replace" and target.getIntValue() = [10, 13] // 10 == "\n", 13 == "\r" + or + methodName = "replaceAll" and + target.getStringValue().regexpMatch(".*([\n\r]|\\[\\^[^\\]\r\n]*\\]).*") + ) + ) + } +} + /** A source that introduces data considered safe to use by a header splitting source. */ abstract class SafeHeaderSplittingSource extends DataFlow::Node instanceof RemoteFlowSource { } diff --git a/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll b/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll index 9bd96a51a68d..327796cf831f 100644 --- a/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll @@ -2,7 +2,6 @@ import java private import semmle.code.java.dataflow.FlowSources -private import semmle.code.java.security.Sanitizers import semmle.code.java.security.ResponseSplitting /** @@ -16,21 +15,7 @@ module ResponseSplittingConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink } - predicate isBarrier(DataFlow::Node node) { - node instanceof SimpleTypeSanitizer - or - exists(MethodCall ma, string methodName, CompileTimeConstantExpr target | - node.asExpr() = ma and - ma.getMethod().hasQualifiedName("java.lang", "String", methodName) and - target = ma.getArgument(0) and - ( - methodName = "replace" and target.getIntValue() = [10, 13] // 10 == "\n", 13 == "\r" - or - methodName = "replaceAll" and - target.getStringValue().regexpMatch(".*([\n\r]|\\[\\^[^\\]\r\n]*\\]).*") - ) - ) - } + predicate isBarrier(DataFlow::Node node) { node instanceof HeaderSplittingSanitizer } predicate observeDiffInformedIncrementalMode() { any() } } diff --git a/java/ql/lib/semmle/code/java/security/SensitiveDataExposureThroughErrorMessageQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveDataExposureThroughErrorMessageQuery.qll index 8644ef415b3e..df141ddc55c1 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveDataExposureThroughErrorMessageQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveDataExposureThroughErrorMessageQuery.qll @@ -21,6 +21,8 @@ private module GetMessageFlowSourceToHttpResponseSinkFlowConfig implements DataF predicate isSource(DataFlow::Node src) { src instanceof GetMessageFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof InformationLeakSink } + + predicate isBarrier(DataFlow::Node node) { node instanceof InformationLeakSanitizer } } private module GetMessageFlowSourceToHttpResponseSinkFlow = diff --git a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll index 7058b844cbdb..3e256cda12de 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll @@ -120,6 +120,10 @@ private class DefaultSensitiveLoggerBarrier extends SensitiveLoggerBarrier { } } +private class ExternalSensitiveLoggerBarrier extends SensitiveLoggerBarrier { + ExternalSensitiveLoggerBarrier() { barrierNode(this, "log-injection") } +} + /** A data-flow configuration for identifying potentially-sensitive data flowing to a log output. */ module SensitiveLoggerConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof SensitiveLoggerSource } diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index ea58c08e07ce..57ae83e503d5 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -14,6 +14,8 @@ private module NotificationTrackingConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sinkNode(sink, "notification") } + predicate isBarrier(DataFlow::Node node) { barrierNode(node, "notification") } + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { isSink(node) and exists(c) } diff --git a/java/ql/lib/semmle/code/java/security/SqlConcatenatedQuery.qll b/java/ql/lib/semmle/code/java/security/SqlConcatenatedQuery.qll index 7cfea41a8d77..0fe876d6686e 100644 --- a/java/ql/lib/semmle/code/java/security/SqlConcatenatedQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SqlConcatenatedQuery.qll @@ -4,7 +4,6 @@ import java private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.SqlConcatenatedLib private import semmle.code.java.security.SqlInjectionQuery -private import semmle.code.java.security.Sanitizers private class UncontrolledStringBuilderSource extends DataFlow::ExprNode { UncontrolledStringBuilderSource() { @@ -23,7 +22,7 @@ module UncontrolledStringBuilderSourceFlowConfig implements DataFlow::ConfigSig predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink } - predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer } + predicate isBarrier(DataFlow::Node node) { node instanceof QueryInjectionSanitizer } predicate observeDiffInformedIncrementalMode() { any() } diff --git a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll index 67f0f1220433..d2bf1eb10488 100644 --- a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll @@ -8,7 +8,6 @@ import java import semmle.code.java.dataflow.FlowSources -private import semmle.code.java.security.Sanitizers import semmle.code.java.security.QueryInjection /** @@ -19,7 +18,7 @@ module QueryInjectionFlowConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink } - predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer } + predicate isBarrier(DataFlow::Node node) { node instanceof QueryInjectionSanitizer } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { any(AdditionalQueryInjectionTaintStep s).step(node1, node2) diff --git a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll index 0eb069a06c20..b6034107e103 100644 --- a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll @@ -70,6 +70,8 @@ private module StackTraceStringToHttpResponseSinkFlowConfig implements DataFlow: predicate isSource(DataFlow::Node src) { stackTraceExpr(_, src.asExpr()) } predicate isSink(DataFlow::Node sink) { sink instanceof InformationLeakSink } + + predicate isBarrier(DataFlow::Node node) { node instanceof InformationLeakSanitizer } } private module StackTraceStringToHttpResponseSinkFlow = diff --git a/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll b/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll index a03775990541..35c2ce89aa49 100644 --- a/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll +++ b/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll @@ -128,6 +128,8 @@ module StaticInitializationVectorConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof EncryptionInitializationSink } + predicate isBarrier(DataFlow::Node node) { barrierNode(node, "encryption-iv") } + predicate observeDiffInformedIncrementalMode() { any() } } diff --git a/java/ql/lib/semmle/code/java/security/TaintedEnvironmentVariableQuery.qll b/java/ql/lib/semmle/code/java/security/TaintedEnvironmentVariableQuery.qll index 2bc9dba92f01..2fd6080ffa41 100644 --- a/java/ql/lib/semmle/code/java/security/TaintedEnvironmentVariableQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TaintedEnvironmentVariableQuery.qll @@ -22,6 +22,10 @@ private module ProcessBuilderEnvironmentFlow = DataFlow::Global