Merge remote-tracking branch 'origin/main' into dbartol/mergeback-3.10

This commit is contained in:
Dave Bartolomeo
2023-07-06 10:00:46 -04:00
1654 changed files with 47750 additions and 21714 deletions

View File

@@ -33,9 +33,6 @@ class SafeExternalApi extends Unit {
DataFlowPrivate::DataFlowCallable getSafeCallable() { none() }
}
/** DEPRECATED: Alias for SafeExternalApi */
deprecated class SafeExternalAPI = SafeExternalApi;
/** The default set of "safe" external APIs. */
private class DefaultSafeExternalApi extends SafeExternalApi {
override DataFlow::CallCfgNode getSafeCall() {
@@ -170,9 +167,6 @@ class ExternalApiDataNode extends DataFlow::Node {
}
}
/** DEPRECATED: Alias for ExternalApiDataNode */
deprecated class ExternalAPIDataNode = ExternalApiDataNode;
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */
class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration {
UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" }
@@ -182,9 +176,6 @@ class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
}
/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */
deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig;
/** A node representing untrusted data being passed to an external API. */
class UntrustedExternalApiDataNode extends ExternalApiDataNode {
UntrustedExternalApiDataNode() { any(UntrustedDataToExternalApiConfig c).hasFlow(_, this) }
@@ -195,9 +186,6 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode {
}
}
/** DEPRECATED: Alias for UntrustedExternalApiDataNode */
deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode;
/** An external API which is used with untrusted data. */
private newtype TExternalApi =
MkExternalApi(string repr, DataFlowPrivate::ArgumentPosition apos) {
@@ -230,6 +218,3 @@ class ExternalApiUsedWithUntrustedData extends MkExternalApi {
/** Gets a textual representation of this element. */
string toString() { result = repr + " [" + apos + "]" }
}
/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */
deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData;

View File

@@ -13,13 +13,10 @@
*/
import python
import semmle.python.security.Paths
import semmle.python.dataflow.TaintTracking
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.filters.Tests
class HardcodedValue extends TaintKind {
HardcodedValue() { this = "hard coded value" }
}
import DataFlow::PathGraph
bindingset[char, fraction]
predicate fewer_characters_than(StrConst str, string char, float fraction) {
@@ -78,31 +75,27 @@ predicate maybeCredential(ControlFlowNode f) {
)
}
class HardcodedValueSource extends TaintSource {
HardcodedValueSource() { maybeCredential(this) }
override predicate isSourceOf(TaintKind kind) { kind instanceof HardcodedValue }
class HardcodedValueSource extends DataFlow::Node {
HardcodedValueSource() { maybeCredential(this.asCfgNode()) }
}
class CredentialSink extends TaintSink {
class CredentialSink extends DataFlow::Node {
CredentialSink() {
exists(string name |
name.regexpMatch(getACredentialRegex()) and
not name.matches("%file")
|
any(FunctionValue func).getNamedArgumentForCall(_, name) = this
any(FunctionValue func).getNamedArgumentForCall(_, name) = this.asCfgNode()
or
exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this)
exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this.asCfgNode())
or
exists(CompareNode cmp, NameNode n | n.getId() = name |
cmp.operands(this, any(Eq eq), n)
cmp.operands(this.asCfgNode(), any(Eq eq), n)
or
cmp.operands(n, any(Eq eq), this)
cmp.operands(n, any(Eq eq), this.asCfgNode())
)
)
}
override predicate sinks(TaintKind kind) { kind instanceof HardcodedValue }
}
/**
@@ -118,16 +111,14 @@ private string getACredentialRegex() {
class HardcodedCredentialsConfiguration extends TaintTracking::Configuration {
HardcodedCredentialsConfiguration() { this = "Hardcoded credentials configuration" }
override predicate isSource(TaintTracking::Source source) {
source instanceof HardcodedValueSource
}
override predicate isSource(DataFlow::Node source) { source instanceof HardcodedValueSource }
override predicate isSink(TaintTracking::Sink sink) { sink instanceof CredentialSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink }
}
from HardcodedCredentialsConfiguration config, TaintedPathSource src, TaintedPathSink sink
from HardcodedCredentialsConfiguration config, DataFlow::PathNode src, DataFlow::PathNode sink
where
config.hasFlowPath(src, sink) and
not any(TestScope test).contains(src.getAstNode())
select src.getSource(), src, sink, "This hardcoded value is $@.", sink.getNode(),
not any(TestScope test).contains(src.getNode().asCfgNode().getNode())
select src.getNode(), src, sink, "This hardcoded value is $@.", sink.getNode(),
"used as credentials"

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* The query "Arbitrary file write during archive extraction ("Zip Slip")" (`py/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")."

View File

@@ -4,16 +4,15 @@
<qhelp>
<overview>
<p>Extracting files from a malicious zip archive without validating that the destination file path
is within the destination directory can cause files outside the destination directory to be
overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in
archive paths.</p>
<p>Extracting files from a malicious zip file, or similar type of archive,
is at risk of directory traversal attacks if filenames from the archive are
not properly validated.</p>
<p>Zip archives contain archive entries representing each file in the archive. These entries
include a file path for the entry, but these file paths are not restricted and may contain
unexpected special elements such as the directory traversal element (<code>..</code>). If these
file paths are used to determine an output file to write the contents of the archive item to, then
the file may be written to an unexpected location. This can result in sensitive information being
file paths are used to create a filesystem path, then a file operation may happen in an
unexpected location. This can result in sensitive information being
revealed or deleted, or an attacker being able to influence behavior by modifying unexpected
files.</p>

View File

@@ -1,8 +1,8 @@
/**
* @name Arbitrary file write during archive extraction ("Zip Slip")
* @description Extracting files from a malicious archive without validating that the
* destination file path is within the destination directory can cause files outside
* the destination directory to be overwritten.
* @name Arbitrary file access during archive extraction ("Zip Slip")
* @description Extracting files from a malicious ZIP file, or similar type of archive, without
* validating that the destination file path is within the destination directory
* can allow an attacker to unexpectedly gain access to resources.
* @kind path-problem
* @id py/zipslip
* @problem.severity error

View File

@@ -5,7 +5,7 @@
* @problem.severity error
* @security-severity 9.3
* @precision high
* @id py/command-injection
* @id py/paramiko-command-injection
* @tags security
* experimental
* external/cwe/cwe-074

View File

@@ -90,9 +90,6 @@ module LdapQuery {
}
}
/** DEPRECATED: Alias for LdapQuery */
deprecated module LDAPQuery = LdapQuery;
/**
* A data-flow node that collect methods executing a LDAP query.
*
@@ -106,9 +103,6 @@ class LdapQuery extends DataFlow::Node instanceof LdapQuery::Range {
DataFlow::Node getQuery() { result = super.getQuery() }
}
/** DEPRECATED: Alias for LdapQuery */
deprecated class LDAPQuery = LdapQuery;
/** Provides classes for modeling LDAP components escape-related APIs. */
module LdapEscape {
/**
@@ -125,9 +119,6 @@ module LdapEscape {
}
}
/** DEPRECATED: Alias for LdapEscape */
deprecated module LDAPEscape = LdapEscape;
/**
* A data-flow node that collects functions escaping LDAP components.
*
@@ -141,9 +132,6 @@ class LdapEscape extends DataFlow::Node instanceof LdapEscape::Range {
DataFlow::Node getAnInput() { result = super.getAnInput() }
}
/** DEPRECATED: Alias for LdapEscape */
deprecated class LDAPEscape = LdapEscape;
/** Provides classes for modeling LDAP bind-related APIs. */
module LdapBind {
/**
@@ -173,9 +161,6 @@ module LdapBind {
}
}
/** DEPRECATED: Alias for LdapBind */
deprecated module LDAPBind = LdapBind;
/**
* A data-flow node that collects methods binding a LDAP connection.
*
@@ -202,9 +187,6 @@ class LdapBind extends DataFlow::Node instanceof LdapBind::Range {
deprecated predicate useSSL() { this.useSsl() }
}
/** DEPRECATED: Alias for LdapBind */
deprecated class LDAPBind = LdapBind;
/** Provides classes for modeling SQL sanitization libraries. */
module SqlEscape {
/**
@@ -221,9 +203,6 @@ module SqlEscape {
}
}
/** DEPRECATED: Alias for SqlEscape */
deprecated module SQLEscape = SqlEscape;
/**
* A data-flow node that collects functions escaping SQL statements.
*
@@ -237,9 +216,6 @@ class SqlEscape extends DataFlow::Node instanceof SqlEscape::Range {
DataFlow::Node getAnInput() { result = super.getAnInput() }
}
/** DEPRECATED: Alias for SqlEscape */
deprecated class SQLEscape = SqlEscape;
/** Provides a class for modeling NoSql execution APIs. */
module NoSqlQuery {
/**
@@ -254,9 +230,6 @@ module NoSqlQuery {
}
}
/** DEPRECATED: Alias for NoSqlQuery */
deprecated module NoSQLQuery = NoSqlQuery;
/**
* A data-flow node that executes NoSQL queries.
*
@@ -268,9 +241,6 @@ class NoSqlQuery extends DataFlow::Node instanceof NoSqlQuery::Range {
DataFlow::Node getQuery() { result = super.getQuery() }
}
/** DEPRECATED: Alias for NoSqlQuery */
deprecated class NoSQLQuery = NoSqlQuery;
/** Provides classes for modeling NoSql sanitization-related APIs. */
module NoSqlSanitizer {
/**
@@ -285,9 +255,6 @@ module NoSqlSanitizer {
}
}
/** DEPRECATED: Alias for NoSqlSanitizer */
deprecated module NoSQLSanitizer = NoSqlSanitizer;
/**
* A data-flow node that collects functions sanitizing NoSQL queries.
*
@@ -299,9 +266,6 @@ class NoSqlSanitizer extends DataFlow::Node instanceof NoSqlSanitizer::Range {
DataFlow::Node getAnInput() { result = super.getAnInput() }
}
/** DEPRECATED: Alias for NoSqlSanitizer */
deprecated class NoSQLSanitizer = NoSqlSanitizer;
/** Provides classes for modeling HTTP Header APIs. */
module HeaderDeclaration {
/**
@@ -450,9 +414,6 @@ module JwtEncoding {
}
}
/** DEPRECATED: Alias for JwtEncoding */
deprecated module JWTEncoding = JwtEncoding;
/**
* A data-flow node that collects methods encoding a JWT token.
*
@@ -481,9 +442,6 @@ class JwtEncoding extends DataFlow::Node instanceof JwtEncoding::Range {
string getAlgorithmString() { result = super.getAlgorithmString() }
}
/** DEPRECATED: Alias for JwtEncoding */
deprecated class JWTEncoding = JwtEncoding;
/** Provides classes for modeling JWT decoding-related APIs. */
module JwtDecoding {
/**
@@ -525,9 +483,6 @@ module JwtDecoding {
}
}
/** DEPRECATED: Alias for JwtDecoding */
deprecated module JWTDecoding = JwtDecoding;
/**
* A data-flow node that collects methods encoding a JWT token.
*
@@ -566,9 +521,6 @@ class JwtDecoding extends DataFlow::Node instanceof JwtDecoding::Range {
predicate verifiesSignature() { super.verifiesSignature() }
}
/** DEPRECATED: Alias for JwtDecoding */
deprecated class JWTDecoding = JwtDecoding;
/** Provides classes for modeling Email APIs. */
module EmailSender {
/**

View File

@@ -29,23 +29,14 @@ class LdapFullHost extends StrConst {
}
}
/** DEPRECATED: Alias for LdapFullHost */
deprecated class LDAPFullHost = LdapFullHost;
class LdapSchema extends StrConst {
LdapSchema() { this.getText().regexpMatch(getSchemaRegex()) }
}
/** DEPRECATED: Alias for LdapSchema */
deprecated class LDAPSchema = LdapSchema;
class LdapPrivateHost extends StrConst {
LdapPrivateHost() { this.getText().regexpMatch(getPrivateHostRegex()) }
}
/** DEPRECATED: Alias for LdapPrivateHost */
deprecated class LDAPPrivateHost = LdapPrivateHost;
predicate concatAndCompareAgainstFullHostRegex(LdapSchema schema, StrConst host) {
not host instanceof LdapPrivateHost and
(schema.getText() + host.getText()).regexpMatch(getFullHostRegex())
@@ -56,9 +47,6 @@ class LdapBothStrings extends BinaryExpr {
LdapBothStrings() { concatAndCompareAgainstFullHostRegex(this.getLeft(), this.getRight()) }
}
/** DEPRECATED: Alias for LdapBothStrings */
deprecated class LDAPBothStrings = LdapBothStrings;
// schema + host
class LdapBothVar extends BinaryExpr {
LdapBothVar() {
@@ -73,9 +61,6 @@ class LdapBothVar extends BinaryExpr {
}
}
/** DEPRECATED: Alias for LdapBothVar */
deprecated class LDAPBothVar = LdapBothVar;
// schema + "somethingon.theinternet.com"
class LdapVarString extends BinaryExpr {
LdapVarString() {
@@ -89,9 +74,6 @@ class LdapVarString extends BinaryExpr {
}
}
/** DEPRECATED: Alias for LdapVarString */
deprecated class LDAPVarString = LdapVarString;
// "ldap://" + host
class LdapStringVar extends BinaryExpr {
LdapStringVar() {
@@ -103,9 +85,6 @@ class LdapStringVar extends BinaryExpr {
}
}
/** DEPRECATED: Alias for LdapStringVar */
deprecated class LDAPStringVar = LdapStringVar;
/**
* A taint-tracking configuration for detecting LDAP insecure authentications.
*/
@@ -125,6 +104,3 @@ class LdapInsecureAuthConfig extends TaintTracking::Configuration {
exists(LdapBind ldapBind | not ldapBind.useSsl() and sink = ldapBind.getHost())
}
}
/** DEPRECATED: Alias for LdapInsecureAuthConfig */
deprecated class LDAPInsecureAuthConfig = LdapInsecureAuthConfig;

View File

@@ -52,6 +52,3 @@ module NoSqlInjection {
ConvertedToDict() { this = "ConvertedToDict" }
}
}
/** DEPRECATED: Alias for NoSqlInjection */
deprecated module NoSQLInjection = NoSqlInjection;