diff --git a/python/ql/lib/semmle/python/security/dataflow/CodeInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/CodeInjectionCustomizations.qll index 5878245ed10..5a7e5882e44 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CodeInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CodeInjectionCustomizations.qll @@ -60,4 +60,11 @@ module CodeInjection { /** DEPRECATED: Use ConstCompareAsSanitizerGuard instead. */ deprecated class StringConstCompareAsSanitizerGuard = ConstCompareAsSanitizerGuard; + + /** + * A sanitizer defined via models-as-data with kind "code-injection". + */ + class SanitizerFromModel extends Sanitizer { + SanitizerFromModel() { ModelOutput::barrierNode(this, "code-injection") } + } } diff --git a/python/ql/lib/semmle/python/security/dataflow/CommandInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/CommandInjectionCustomizations.qll index 0bfd6494a1c..facb422e728 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CommandInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CommandInjectionCustomizations.qll @@ -95,4 +95,11 @@ module CommandInjection { /** DEPRECATED: Use ConstCompareAsSanitizerGuard instead. */ deprecated class StringConstCompareAsSanitizerGuard = ConstCompareAsSanitizerGuard; + + /** + * A sanitizer defined via models-as-data with kind "command-injection". + */ + class SanitizerFromModel extends Sanitizer { + SanitizerFromModel() { ModelOutput::barrierNode(this, "command-injection") } + } } diff --git a/python/ql/lib/semmle/python/security/dataflow/LogInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/LogInjectionCustomizations.qll index 59e52f0ab0a..98c767df289 100644 --- a/python/ql/lib/semmle/python/security/dataflow/LogInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/LogInjectionCustomizations.qll @@ -106,4 +106,11 @@ module LogInjection { this.getArg(0).asExpr().(StringLiteral).getText() in ["\r\n", "\n"] } } + + /** + * A sanitizer defined via models-as-data with kind "log-injection". + */ + class SanitizerFromModel extends Sanitizer { + SanitizerFromModel() { ModelOutput::barrierNode(this, "log-injection") } + } } diff --git a/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll index e2399d49c0b..269026b591b 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll @@ -98,4 +98,11 @@ module PathInjection { /** DEPRECATED: Use ConstCompareAsSanitizerGuard instead. */ deprecated class StringConstCompareAsSanitizerGuard = ConstCompareAsSanitizerGuard; + + /** + * A sanitizer defined via models-as-data with kind "path-injection". + */ + class SanitizerFromModel extends Sanitizer { + SanitizerFromModel() { ModelOutput::barrierNode(this, "path-injection") } + } } diff --git a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll index 58e5adc8660..0ef2234a577 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll @@ -84,4 +84,11 @@ module ReflectedXss { /** DEPRECATED: Use ConstCompareAsSanitizerGuard instead. */ deprecated class StringConstCompareAsSanitizerGuard = ConstCompareAsSanitizerGuard; + + /** + * A sanitizer defined via models-as-data with kind "html-injection" or "js-injection". + */ + class SanitizerFromModel extends Sanitizer { + SanitizerFromModel() { ModelOutput::barrierNode(this, ["html-injection", "js-injection"]) } + } } diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll index 4118732e8da..ee6f17b03d2 100644 --- a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll @@ -69,4 +69,11 @@ module SqlInjection { private class DataAsSqlSink extends Sink { DataAsSqlSink() { ModelOutput::sinkNode(this, "sql-injection") } } + + /** + * A sanitizer defined via models-as-data with kind "sql-injection". + */ + class SanitizerFromModel extends Sanitizer { + SanitizerFromModel() { ModelOutput::barrierNode(this, "sql-injection") } + } } diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationCustomizations.qll index 074677ee1dc..17450bb82d9 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationCustomizations.qll @@ -65,4 +65,11 @@ module UnsafeDeserialization { /** DEPRECATED: Use ConstCompareAsSanitizerGuard instead. */ deprecated class StringConstCompareAsSanitizerGuard = ConstCompareAsSanitizerGuard; + + /** + * A sanitizer defined via models-as-data with kind "unsafe-deserialization". + */ + class SanitizerFromModel extends Sanitizer { + SanitizerFromModel() { ModelOutput::barrierNode(this, "unsafe-deserialization") } + } } diff --git a/python/ql/src/Security/CWE-798/HardcodedCredentials.ql b/python/ql/src/Security/CWE-798/HardcodedCredentials.ql index 97b1f2fba1c..1e7b4452a9a 100644 --- a/python/ql/src/Security/CWE-798/HardcodedCredentials.ql +++ b/python/ql/src/Security/CWE-798/HardcodedCredentials.ql @@ -105,6 +105,15 @@ class CredentialSink extends DataFlow::Node { } } +class CredentialSanitizer extends DataFlow::Node { + CredentialSanitizer() { + exists(string s | s.matches("credentials-%") | + // Whatever the string, this will sanitize flow to all credential sinks. + ModelOutput::barrierNode(this, s) + ) + } +} + /** * Gets a regular expression for matching names of locations (variables, parameters, keys) that * indicate the value being held is a credential. @@ -120,6 +129,8 @@ private module HardcodedCredentialsConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink } + predicate isBarrier(DataFlow::Node node) { node instanceof CredentialSanitizer } + predicate observeDiffInformedIncrementalMode() { any() } }