Last active
October 1, 2021 04:44
-
-
Save inkz/29b811991d3d93487b155a23ec35d26c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rules: | |
- id: doctrine-dbal-dangerous-query | |
languages: | |
- php | |
message: Detected string concatenation with a non-literal variable in a Doctrine DBAL query method. This could lead to SQL | |
injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, used parameterized | |
queries or prepared statements instead. | |
metadata: | |
category: security | |
cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" | |
license: Commons Clause License Condition v1.0[LGPL-2.1-only] | |
owasp: 'A1: Injection' | |
references: | |
- https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/security.html | |
- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html | |
technology: | |
- doctrine | |
patterns: | |
- pattern-either: | |
- pattern: $CONNECTION->prepare($QUERY,...) | |
- pattern: $CONNECTION->createQuery($QUERY,...) | |
- pattern: $CONNECTION->executeQuery($QUERY,...) | |
- pattern-either: | |
- pattern-inside: | | |
use Doctrine\DBAL\Connection; | |
... | |
- pattern-inside: | | |
$CONNECTION = $SMTH->getConnection(...); | |
... | |
- pattern-not: $CONNECTION->prepare("...",...) | |
- pattern-not: $CONNECTION->createQuery("...",...) | |
- pattern-not: $CONNECTION->executeQuery("...",...) | |
severity: WARNING | |
- id: symfony-non-literal-redirect | |
patterns: | |
- pattern: $this->redirect(...) | |
- pattern-not: $this->redirect("...") | |
message: >- | |
The `redirect()` method does not check its destination in any way. If you redirect to a URL provided by end-users, your | |
application may be open to the unvalidated redirects security vulnerability. | |
Consider using literal values or an allowlist to validate URLs. | |
languages: [php] | |
metadata: | |
references: | |
- https://symfony.com/doc/current/controller.html#redirecting | |
- https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html | |
owasp: 'A1: Injection' | |
cwe: "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')" | |
category: security | |
technology: | |
- symfony | |
severity: WARNING | |
- id: doctrine-orm-dangerous-query | |
languages: | |
- php | |
message: >- | |
`$QUERY` Detected string concatenation with a non-literal variable in a Doctrine | |
QueryBuilder method. This could lead to SQL injection if the variable is | |
user-controlled and not properly sanitized. In order to prevent SQL | |
injection, used parameterized queries or prepared statements instead. | |
metadata: | |
category: security | |
cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" | |
license: Commons Clause License Condition v1.0[LGPL-2.1-only] | |
owasp: 'A1: Injection' | |
references: | |
- https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/query-builder.html#security-safely-preventing-sql-injection | |
- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html | |
technology: | |
- doctrine | |
mode: taint | |
pattern-sinks: | |
- patterns: | |
- pattern: $SINK | |
- pattern-either: | |
- pattern-inside: $QUERY->add(...,$SINK,...) | |
- pattern-inside: $QUERY->select(...,$SINK,...) | |
- pattern-inside: $QUERY->addSelect(...,$SINK,...) | |
- pattern-inside: $QUERY->delete(...,$SINK,...) | |
- pattern-inside: $QUERY->update(...,$SINK,...) | |
- pattern-inside: $QUERY->insert(...,$SINK,...) | |
- pattern-inside: $QUERY->from(...,$SINK,...) | |
- pattern-inside: $QUERY->join(...,$SINK,...) | |
- pattern-inside: $QUERY->innerJoin(...,$SINK,...) | |
- pattern-inside: $QUERY->leftJoin(...,$SINK,...) | |
- pattern-inside: $QUERY->rightJoin(...,$SINK,...) | |
- pattern-inside: $QUERY->where(...,$SINK,...) | |
- pattern-inside: $QUERY->andWhere(...,$SINK,...) | |
- pattern-inside: $QUERY->orWhere(...,$SINK,...) | |
- pattern-inside: $QUERY->groupBy(...,$SINK,...) | |
- pattern-inside: $QUERY->addGroupBy(...,$SINK,...) | |
- pattern-inside: $QUERY->having(...,$SINK,...) | |
- pattern-inside: $QUERY->andHaving(...,$SINK,...) | |
- pattern-inside: $QUERY->orHaving(...,$SINK,...) | |
- pattern-inside: $QUERY->orderBy(...,$SINK,...) | |
- pattern-inside: $QUERY->addOrderBy(...,$SINK,...) | |
- pattern-inside: $QUERY->set($SINK,...) | |
- pattern-inside: $QUERY->setValue($SINK,...) | |
- pattern-either: | |
- pattern-inside: | | |
$Q = $X->createQueryBuilder(); | |
... | |
- pattern-inside: | | |
$Q = new QueryBuilder(...); | |
... | |
pattern-sources: | |
- patterns: | |
- pattern-either: | |
- pattern: sprintf(...) | |
- pattern: | | |
"...".$SMTH | |
severity: WARNING | |
- id: ldap-bind-without-password | |
patterns: | |
- pattern-either: | |
- pattern: ldap_bind($LDAP, $DN, NULL) | |
- pattern: ldap_bind($LDAP, $DN, '') | |
- patterns: | |
- pattern: ldap_bind(...) | |
- pattern-not: ldap_bind($LDAP, $DN, $PASSWORD) | |
message: >- | |
Detected anonymous LDAP bind. | |
This permits anonymous users to execute LDAP statements. | |
Consider enforcing authentication for LDAP. | |
metadata: | |
references: | |
- https://www.php.net/manual/ru/function.ldap-bind.php | |
cwe: 'CWE-287: Improper Authentication' | |
owasp: 'A2: Broken Authentication' | |
category: security | |
technology: | |
- php | |
languages: [php] | |
severity: WARNING | |
- id: non-literal-header | |
patterns: | |
- pattern: header(...) | |
- pattern-not: header("...",...) | |
message: >- | |
Using user input when setting headers with `header()` is potentially dangerous. | |
This could allow an attacker to inject a new line and add a new header into the response. | |
This is called HTTP response splitting. | |
To fix, do not allow whitespace inside `header()`: '[^\s]+'. | |
metadata: | |
references: | |
- https://www.php.net/manual/ru/function.header.php | |
- https://owasp.org/www-community/attacks/HTTP_Response_Splitting | |
category: security | |
technology: | |
- php | |
cwe: "CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting')" | |
languages: [php] | |
severity: WARNING | |
- id: php-permissive-cors | |
patterns: | |
- pattern: header($VALUE,...) | |
- pattern-either: | |
- pattern: header("...",...) | |
- pattern-inside: | | |
$VALUE = "..."; | |
... | |
- metavariable-regex: | |
metavariable: $VALUE | |
regex: (\'|\")\s*(Access-Control-Allow-Origin|access-control-allow-origin)\s*:\s*(\*)\s*(\'|\") | |
message: >- | |
Access-Control-Allow-Origin response header is set to "*". | |
This will disable CORS Same Origin Policy restrictions. | |
metadata: | |
references: | |
- https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Allow-Origin | |
owasp: 'A6: Security Misconfiguration' | |
cwe: 'CWE-346: Origin Validation Error' | |
category: security | |
technology: | |
- php | |
languages: [php] | |
severity: WARNING | |
- id: unlink-use | |
patterns: | |
- pattern: unlink(...) | |
- pattern-not: unlink("...",...) | |
message: >- | |
Using user input when deleting files with `unlink()` is potentially dangerous. A malicious actor could use this to modify | |
or access files they have no right to. | |
metadata: | |
references: | |
- https://www.php.net/manual/en/function.unlink | |
- https://owasp.org/www-project-top-ten/2017/A5_2017-Broken_Access_Control.html | |
category: security | |
technology: | |
- php | |
owasp: 'A5: Broken Access Control' | |
cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')" | |
languages: [php] | |
severity: WARNING | |
- id: unserialize-use | |
patterns: | |
- pattern: unserialize(...) | |
- pattern-not: unserialize("...",...) | |
message: >- | |
Calling `unserialize()` with user input in the pattern can lead to arbitrary code execution. | |
Consider using JSON or structured data approaches (e.g. Google Protocol Buffers). | |
metadata: | |
references: | |
- https://www.php.net/manual/ru/function.unserialize.php | |
- https://owasp.org/www-project-top-ten/2017/A8_2017-Insecure_Deserialization.html | |
category: security | |
technology: | |
- php | |
owasp: 'A8: Insecure Deserialization' | |
cwe: 'CWE-502: Deserialization of Untrusted Data' | |
languages: [php] | |
severity: WARNING | |
- id: symfony-csrf-protection-disabled | |
patterns: | |
- pattern-either: | |
- pattern: $X->createForm($TYPE, $TASK, [..., 'csrf_protection' => false, ...], ...) | |
- pattern: $X->prependExtensionConfig('framework', [..., 'csrf_protection' => false, ...], ...) | |
- pattern: $X->loadFromExtension('framework', [..., 'csrf_protection' => false, ...], ...) | |
- pattern: $X->setDefaults([..., 'csrf_protection' => false, ...], ...) | |
- patterns: | |
- pattern-either: | |
- pattern: $X->createForm($TYPE, $TASK, [..., 'csrf_protection' => $VAL, ...], ...) | |
- pattern: $X->prependExtensionConfig('framework', [..., 'csrf_protection' => $VAL, ...], ...) | |
- pattern: $X->loadFromExtension('framework', [..., 'csrf_protection' => $VAL, ...], ...) | |
- pattern: $X->setDefaults([..., 'csrf_protection' => $VAL, ...], ...) | |
- pattern-inside: | | |
$VAL = false; | |
... | |
message: >- | |
CSRF is disabled for this configuration. This is a security risk. | |
Make sure that it is safe or consider setting `csrf_protection` property to `true`. | |
metadata: | |
references: | |
- https://symfony.com/doc/current/security/csrf.html | |
cwe: 'CWE-352: Cross-Site Request Forgery (CSRF)' | |
owasp: 'A6: Security Misconfiguration' | |
category: security | |
technology: | |
- symfony | |
languages: [php] | |
severity: WARNING | |
- id: symfony-permissive-cors | |
patterns: | |
- pattern-inside: | | |
use Symfony\Component\HttpFoundation\Response; | |
... | |
- pattern-either: | |
- patterns: | |
- pattern-either: | |
- pattern: | | |
new Symfony\Component\HttpFoundation\Response($X, $Y, $HEADERS, ...) | |
- pattern: new Response($X, $Y, $HEADERS, ...) | |
- pattern-either: | |
- pattern: new $R($X, $Y, [$KEY => $VALUE], ...) | |
- pattern-inside: | | |
$HEADERS = [$KEY => $VALUE]; | |
... | |
- patterns: | |
- pattern: $RES->headers->set($KEY, $VALUE) | |
- metavariable-regex: | |
metavariable: $KEY | |
regex: (\'|\")\s*(Access-Control-Allow-Origin|access-control-allow-origin)\s*(\'|\") | |
- metavariable-regex: | |
metavariable: $VALUE | |
regex: (\'|\")\s*(\*)\s*(\'|\") | |
message: >- | |
Access-Control-Allow-Origin response header is set to "*". | |
This will disable CORS Same Origin Policy restrictions. | |
metadata: | |
references: | |
- https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Allow-Origin | |
owasp: 'A6: Security Misconfiguration' | |
cwe: 'CWE-346: Origin Validation Error' | |
category: security | |
technology: | |
- symfony | |
languages: [php] | |
severity: WARNING |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment