diff --git a/PR_9_php/semgrep_php/doctrine/.DS_Store b/PR_9_php/semgrep_php/doctrine/.DS_Store new file mode 100644 index 0000000..fb7fffb Binary files /dev/null and b/PR_9_php/semgrep_php/doctrine/.DS_Store differ diff --git a/PR_9_php/semgrep_php/doctrine/security/.DS_Store b/PR_9_php/semgrep_php/doctrine/security/.DS_Store new file mode 100644 index 0000000..f2c6f05 Binary files /dev/null and b/PR_9_php/semgrep_php/doctrine/security/.DS_Store differ diff --git a/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-dbal-dangerous-query.php b/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-dbal-dangerous-query.php new file mode 100644 index 0000000..8f2b907 --- /dev/null +++ b/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-dbal-dangerous-query.php @@ -0,0 +1,57 @@ +getEntityManager()->getConnection(); + + $sql = "SELECT * FROM product p WHERE p.price > " . $_GET['cur_price']. " ORDER BY p.price ASC"; +// {fact rule=sql-injection@v1.0 defects=1} + // ruleid: doctrine-dbal-dangerous-query + $stmt = $conn->prepare($sql); +// {/fact} + $stmt->execute(['price' => $price]); + + return $stmt->fetchAllAssociative(); + } + + public function test2(): array + { + $conn = $this->getEntityManager()->getConnection(); + +// {fact rule=sql-injection@v1.0 defects=1} + // ruleid: doctrine-dbal-dangerous-query + $query = $conn->createQuery("SELECT u FROM User u WHERE u.username = '" . $_GET['username'] . "'"); +// {/fact} + $data = $query->getResult(); + return $data; + } + + public function okTest1(int $price): array + { + $conn = $this->getEntityManager()->getConnection(); + $sql = "SELECT * FROM users WHERE username = ?"; +// {fact rule=sql-injection@v1.0 defects=0} + // ok: doctrine-dbal-dangerous-query + $stmt = $conn->prepare($sql); +// {/fact} + $stmt->bindValue(1, $_GET['username']); + $resultSet = $stmt->executeQuery(); + return $resultSet; + } + + public function okTest2(int $price): array + { + $conn = $this->foobar(); + $sql = "SELECT * FROM users WHERE username = ?"; +// {fact rule=sql-injection@v1.0 defects=0} + // ok: doctrine-dbal-dangerous-query + $stmt = $conn->prepare($sql); +// {/fact} + $stmt->bindValue(1, $_GET['username']); + $resultSet = $stmt->executeQuery(); + return $resultSet; + } + +} diff --git a/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-dbal-dangerous-query.yaml b/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-dbal-dangerous-query.yaml new file mode 100644 index 0000000..0913b4a --- /dev/null +++ b/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-dbal-dangerous-query.yaml @@ -0,0 +1,43 @@ +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, use 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: + - A01:2017 - Injection + - A03:2021 - 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 + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - audit + likelihood: LOW + impact: HIGH + confidence: LOW + 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 diff --git a/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-orm-dangerous-query.php b/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-orm-dangerous-query.php new file mode 100644 index 0000000..4f613d2 --- /dev/null +++ b/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-orm-dangerous-query.php @@ -0,0 +1,46 @@ +createQueryBuilder(); + + $queryBuilder + ->select('id', 'name') + ->from('users') +// {fact rule=sql-injection@v1.0 defects=1} + // ruleid: doctrine-orm-dangerous-query + ->where('email = '.$input) +// {/fact} + ; +} + +function test2($email, $input) +{ + $queryBuilder = new QueryBuilder($this->connection); + + $queryBuilder + ->select('id', 'name') + ->from('users') + ->where('email = ?') + ->setParameter(0, $email) +// {fact rule=sql-injection@v1.0 defects=1} + // ruleid: doctrine-orm-dangerous-query + ->andWhere(sprintf('user = %s', $input)) +// {/fact} + ; +} + +function okTest1($input) +{ + $queryBuilder = $conn->createQueryBuilder(); + + $queryBuilder + ->select('id', 'name') + ->from('users') +// {fact rule=sql-injection@v1.0 defects=0} + // ok: doctrine-orm-dangerous-query + ->where('email = ?') +// {/fact} + ->setParameter(0, $input) + ; +} diff --git a/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-orm-dangerous-query.yaml b/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-orm-dangerous-query.yaml new file mode 100644 index 0000000..ba41281 --- /dev/null +++ b/PR_9_php/semgrep_php/doctrine/security/audit/doctrine-orm-dangerous-query.yaml @@ -0,0 +1,71 @@ +rules: +- 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, use 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: + - A01:2017 - Injection + - A03:2021 - 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 + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + likelihood: MEDIUM + impact: MEDIUM + confidence: MEDIUM + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $SINK + - pattern-either: + - pattern: $QUERY->add(...,$SINK,...) + - pattern: $QUERY->select(...,$SINK,...) + - pattern: $QUERY->addSelect(...,$SINK,...) + - pattern: $QUERY->delete(...,$SINK,...) + - pattern: $QUERY->update(...,$SINK,...) + - pattern: $QUERY->insert(...,$SINK,...) + - pattern: $QUERY->from(...,$SINK,...) + - pattern: $QUERY->join(...,$SINK,...) + - pattern: $QUERY->innerJoin(...,$SINK,...) + - pattern: $QUERY->leftJoin(...,$SINK,...) + - pattern: $QUERY->rightJoin(...,$SINK,...) + - pattern: $QUERY->where(...,$SINK,...) + - pattern: $QUERY->andWhere(...,$SINK,...) + - pattern: $QUERY->orWhere(...,$SINK,...) + - pattern: $QUERY->groupBy(...,$SINK,...) + - pattern: $QUERY->addGroupBy(...,$SINK,...) + - pattern: $QUERY->having(...,$SINK,...) + - pattern: $QUERY->andHaving(...,$SINK,...) + - pattern: $QUERY->orHaving(...,$SINK,...) + - pattern: $QUERY->orderBy(...,$SINK,...) + - pattern: $QUERY->addOrderBy(...,$SINK,...) + - pattern: $QUERY->set($SINK,...) + - pattern: $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 diff --git a/PR_9_php/semgrep_php/lang/security/assert-use.php b/PR_9_php/semgrep_php/lang/security/assert-use.php new file mode 100644 index 0000000..4e63f63 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/assert-use.php @@ -0,0 +1,33 @@ + 1'); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// todook: assert-use +assert($tainted > 1); +// {/fact} + +Route::get('bad', function ($name) { +// {fact rule=code-injection@v1.0 defects=1} + // ruleid: assert-use + assert($name); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} + // ok: assert-use + assert('2 > 1'); +// {/fact} + + // todook: assert-use + assert($name > 1); +}); diff --git a/PR_9_php/semgrep_php/lang/security/assert-use.yaml b/PR_9_php/semgrep_php/lang/security/assert-use.yaml new file mode 100644 index 0000000..f24b406 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/assert-use.yaml @@ -0,0 +1,41 @@ +rules: +- id: assert-use + mode: taint + pattern-sources: + - pattern-either: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER + - patterns: + - pattern: | + Route::$METHOD($ROUTENAME, function(..., $ARG, ...) { ... }) + - focus-metavariable: $ARG + pattern-sinks: + - patterns: + - pattern: assert($SINK, ...); + - pattern-not: assert("...", ...); + - pattern: $SINK + message: >- + Calling assert with user input is equivalent to eval'ing. + metadata: + owasp: + - A03:2021 - Injection + cwe: + - "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')" + references: + - https://www.php.net/manual/en/function.assert + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/AssertsSniff.php + category: security + technology: + - php + confidence: HIGH + subcategory: + - vuln + likelihood: MEDIUM + impact: MEDIUM + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/audit/assert-use-audit.php b/PR_9_php/semgrep_php/lang/security/audit/assert-use-audit.php new file mode 100644 index 0000000..b6cdf5d --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/audit/assert-use-audit.php @@ -0,0 +1,71 @@ +name); +// {/ex-fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert('2 > 1'); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert($user_input > 1); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert($ok < 1 || $ok > 2); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert($ok->count < 1 || $ok > 2); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert($ok != "something"); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert($ok!="something"); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert($ok instanceof FakeClass); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert($ok[$param] instanceof FakeClass); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert($ok['foo'] instanceof FakeClass); +// {/fact} + +// {fact rule=code-injection@v1.0 defects=0} +// ok: assert-use-audit +assert($ok->property instanceof FakeClass); +// {/fact} \ No newline at end of file diff --git a/PR_9_php/semgrep_php/lang/security/audit/assert-use-audit.yaml b/PR_9_php/semgrep_php/lang/security/audit/assert-use-audit.yaml new file mode 100644 index 0000000..e7e0791 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/audit/assert-use-audit.yaml @@ -0,0 +1,29 @@ +rules: +- id: assert-use-audit + patterns: + - pattern: assert($ASSERT, ...); + - pattern-not: assert("...", ...); + - metavariable-regex: + metavariable: $ASSERT + # explanation - alphanumerics, array references (literal or variable), object properties + regex: \A\$[A-Za-z\[\]\-_'"\$]+(\-\>\w+)?\Z + message: >- + Calling assert with user input is equivalent to eval'ing. + metadata: + owasp: + - A03:2021 - Injection + cwe: + - "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')" + references: + - https://www.php.net/manual/en/function.assert + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/AssertsSniff.php + category: security + technology: + - php + confidence: LOW + subcategory: + - audit + likelihood: LOW + impact: HIGH + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/audit/openssl-decrypt-validate.php b/PR_9_php/semgrep_php/lang/security/audit/openssl-decrypt-validate.php new file mode 100644 index 0000000..8039e16 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/audit/openssl-decrypt-validate.php @@ -0,0 +1,82 @@ +- + Backticks use may lead to command injection vulnerabilities. + metadata: + cwe: + - "CWE-94: Improper Control of Generation of Code ('Code Injection')" + references: + - https://www.php.net/manual/en/language.operators.execution.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/BackticksSniff.php + category: security + technology: + - php + owasp: + - A03:2021 - Injection + cwe2022-top25: true + subcategory: + - audit + likelihood: LOW + impact: HIGH + confidence: LOW + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/curl-ssl-verifypeer-off.php b/PR_9_php/semgrep_php/lang/security/curl-ssl-verifypeer-off.php new file mode 100644 index 0000000..7936d67 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/curl-ssl-verifypeer-off.php @@ -0,0 +1,16 @@ +- + SSL verification is disabled but should not be (currently CURLOPT_SSL_VERIFYPEER= + $IS_VERIFIED) + metadata: + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + references: + - https://www.saotn.org/dont-turn-off-curlopt_ssl_verifypeer-fix-php-configuration/ + category: security + technology: + - php + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + subcategory: + - vuln + likelihood: LOW + impact: LOW + confidence: MEDIUM + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/deserialization.php b/PR_9_php/semgrep_php/lang/security/deserialization.php new file mode 100644 index 0000000..866cd67 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/deserialization.php @@ -0,0 +1,34 @@ + + "blue", + "size" => "medium", + "shape" => "sphere"); +// {fact rule=untrusted-deserialization@v1.0 defects=0} +// ok: extract-user-data +extract($var_array, EXTR_PREFIX_SAME, "wddx"); +// {/fact} + +$bad = $_GET['some_param']; +// {fact rule=untrusted-deserialization@v1.0 defects=1} +// ruleid:extract-user-data +extract($bad, EXTR_PREFIX_SAME, "wddx"); +// {/fact} +echo "$color, $size, $shape, $wddx_size\n"; + +$bad2 = $_FILES["/some/bad/path"]; +// {fact rule=untrusted-deserialization@v1.0 defects=1} +// ruleid:extract-user-data +extract($bad2, EXTR_PREFIX_SAME, "wddx"); +// {/fact} + +// {fact rule=untrusted-deserialization@v1.0 defects=0} +// ok: extract-user-data +$ok = $_FILES["/some/bad/path"]; +// {/fact} +extract($ok, EXTR_SKIP, "wddx"); +?> diff --git a/PR_9_php/semgrep_php/lang/security/deserialization.yaml b/PR_9_php/semgrep_php/lang/security/deserialization.yaml new file mode 100644 index 0000000..a35a4f8 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/deserialization.yaml @@ -0,0 +1,35 @@ +rules: +- id: extract-user-data + mode: taint + pattern-sources: + - pattern-either: + - pattern: $_GET[...] + - pattern: $_FILES[...] + - pattern: $_POST[...] + pattern-sinks: + - pattern: extract(...) + pattern-sanitizers: + - pattern: extract($VAR, EXTR_SKIP,...) + message: Do not call 'extract()' on user-controllable data. If you must, then you must also provide + the EXTR_SKIP flag to prevent overwriting existing variables. + languages: + - php + metadata: + category: security + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + technology: + - php + references: + - https://www.php.net/manual/en/function.extract.php#refsect1-function.extract-notes + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + likelihood: MEDIUM + impact: MEDIUM + confidence: MEDIUM + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/eval-use.php b/PR_9_php/semgrep_php/lang/security/eval-use.php new file mode 100644 index 0000000..2499ac1 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/eval-use.php @@ -0,0 +1,11 @@ +//- + Evaluating non-constant commands. This can lead to command injection. + metadata: + cwe: + - "CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')" + references: + - https://www.php.net/manual/en/function.eval + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/NoEvalsSniff.php + category: security + technology: + - php + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - audit + likelihood: LOW + impact: HIGH + confidence: LOW + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/exec-use.php b/PR_9_php/semgrep_php/lang/security/exec-use.php new file mode 100644 index 0000000..ca9c958 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/exec-use.php @@ -0,0 +1,41 @@ +- + Executing non-constant commands. This can lead to command injection. + metadata: + cwe: + - "CWE-94: Improper Control of Generation of Code ('Code Injection')" + references: + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/SystemExecFunctionsSniff.php + category: security + technology: + - php + owasp: + - A03:2021 - Injection + cwe2022-top25: true + subcategory: + - audit + likelihood: LOW + impact: HIGH + confidence: LOW + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/file-inclusion.php b/PR_9_php/semgrep_php/lang/security/file-inclusion.php new file mode 100644 index 0000000..07abe0a --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/file-inclusion.php @@ -0,0 +1,74 @@ +- + Detected non-constant file inclusion. This can lead to local file inclusion (LFI) or remote file inclusion + (RFI) if user input reaches this statement. LFI and RFI could lead to sensitive files being obtained + by attackers. Instead, explicitly specify what to include. If that is not a viable solution, validate + user input thoroughly. + metadata: + cwe: + - "CWE-98: Improper Control of Filename for Include/Require Statement in PHP Program ('PHP Remote\ + \ File Inclusion')" + references: + - https://www.php.net/manual/en/function.include.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/EasyRFISniff.php + - https://en.wikipedia.org/wiki/File_inclusion_vulnerability#Types_of_Inclusion + category: security + technology: + - php + owasp: + - A03:2021 - Injection + subcategory: + - audit + likelihood: LOW + impact: MEDIUM + confidence: LOW + languages: [php] + severity: ERROR + mode: taint + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: basename($PATH, ...) + - pattern-inside: linkinfo($PATH, ...) + - pattern-inside: readlink($PATH, ...) + - pattern-inside: realpath($PATH, ...) + - pattern-inside: include_safe(...) + pattern-sinks: + - patterns: + - pattern-inside: $FUNC(...); + - pattern: $VAR + - metavariable-regex: + metavariable: $FUNC + regex: \b(include|include_once|require|require_once)\b diff --git a/PR_9_php/semgrep_php/lang/security/ftp-use.php b/PR_9_php/semgrep_php/lang/security/ftp-use.php new file mode 100644 index 0000000..c785cd0 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/ftp-use.php @@ -0,0 +1,16 @@ +- + FTP allows for unencrypted file transfers. Consider using an encrypted alternative. + metadata: + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + references: + - https://www.php.net/manual/en/intro.ftp.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/FringeFunctionsSniff.php + category: security + technology: + - php + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + subcategory: + - audit + likelihood: LOW + impact: MEDIUM + confidence: LOW + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/injection/echoed-request.php b/PR_9_php/semgrep_php/lang/security/injection/echoed-request.php new file mode 100644 index 0000000..e2b0500 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/injection/echoed-request.php @@ -0,0 +1,118 @@ +- + `Echo`ing user input risks cross-site scripting vulnerability. + You should use `htmlentities()` when showing data to users. + languages: [php] + severity: ERROR + pattern-sources: + - pattern: $_REQUEST + - pattern: $_GET + - pattern: $_POST + pattern-sinks: + - pattern: echo ...; + - pattern: print(...); + pattern-sanitizers: + - pattern: isset(...) + - pattern: empty(...) + - pattern: htmlentities(...) + - pattern: htmlspecialchars(...) + metadata: + technology: + - php + cwe: + - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')" + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + category: security + references: + - https://www.php.net/manual/en/function.htmlentities.php + - https://www.php.net/manual/en/reserved.variables.request.php + - https://www.php.net/manual/en/reserved.variables.post.php + - https://www.php.net/manual/en/reserved.variables.get.php + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + likelihood: MEDIUM + impact: MEDIUM + confidence: MEDIUM diff --git a/PR_9_php/semgrep_php/lang/security/injection/tainted-filename.php b/PR_9_php/semgrep_php/lang/security/injection/tainted-filename.php new file mode 100644 index 0000000..c8ec246 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/injection/tainted-filename.php @@ -0,0 +1,30 @@ +- + File name based on user input risks server-side request forgery. + metadata: + technology: + - php + category: security + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery_%28SSRF%29 + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + impact: MEDIUM + likelihood: MEDIUM + confidence: MEDIUM + languages: [php] + mode: taint + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: basename($PATH, ...) + - pattern-inside: linkinfo($PATH, ...) + - pattern-inside: readlink($PATH, ...) + - pattern-inside: realpath($PATH, ...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: opcache_compile_file($FILENAME, ...) + - pattern-inside: opcache_invalidate($FILENAME, ...) + - pattern-inside: opcache_is_script_cached($FILENAME, ...) + - pattern-inside: runkit7_import($FILENAME, ...) + - pattern-inside: readline_read_history($FILENAME, ...) + - pattern-inside: readline_write_history($FILENAME, ...) + - pattern-inside: rar_open($FILENAME, ...) + - pattern-inside: zip_open($FILENAME, ...) + - pattern-inside: gzfile($FILENAME, ...) + - pattern-inside: gzopen($FILENAME, ...) + - pattern-inside: readgzfile($FILENAME, ...) + - pattern-inside: hash_file($ALGO, $FILENAME, ...) + - pattern-inside: hash_update_file($CONTEXT, $FILENAME, ...) + - pattern-inside: pg_trace($FILENAME, ...) + - pattern-inside: dio_open($FILENAME, ...) + - pattern-inside: finfo_file($FINFO, $FILENAME, ...) + - pattern-inside: mime_content_type($FILENAME, ...) + - pattern-inside: chgrp($FILENAME, ...) + - pattern-inside: chmod($FILENAME, ...) + - pattern-inside: chown($FILENAME, ...) + - pattern-inside: clearstatcache($CLEAR_REALPATH_CACHE, $FILENAME, ...) + - pattern-inside: file_exists($FILENAME, ...) + - pattern-inside: file_get_contents($FILENAME, ...) + - pattern-inside: file_put_contents($FILENAME, ...) + - pattern-inside: file($FILENAME, ...) + - pattern-inside: fileatime($FILENAME, ...) + - pattern-inside: filectime($FILENAME, ...) + - pattern-inside: filegroup($FILENAME, ...) + - pattern-inside: fileinode($FILENAME, ...) + - pattern-inside: filemtime($FILENAME, ...) + - pattern-inside: fileowner($FILENAME, ...) + - pattern-inside: fileperms($FILENAME, ...) + - pattern-inside: filesize($FILENAME, ...) + - pattern-inside: filetype($FILENAME, ...) + - pattern-inside: fnmatch($PATTERN, $FILENAME, ...) + - pattern-inside: fopen($FILENAME, ...) + - pattern-inside: is_dir($FILENAME, ...) + - pattern-inside: is_executable($FILENAME, ...) + - pattern-inside: is_file($FILENAME, ...) + - pattern-inside: is_link($FILENAME, ...) + - pattern-inside: is_readable($FILENAME, ...) + - pattern-inside: is_uploaded_file($FILENAME, ...) + - pattern-inside: is_writable($FILENAME, ...) + - pattern-inside: lchgrp($FILENAME, ...) + - pattern-inside: lchown($FILENAME, ...) + - pattern-inside: lstat($FILENAME, ...) + - pattern-inside: parse_ini_file($FILENAME, ...) + - pattern-inside: readfile($FILENAME, ...) + - pattern-inside: stat($FILENAME, ...) + - pattern-inside: touch($FILENAME, ...) + - pattern-inside: unlink($FILENAME, ...) + - pattern-inside: xattr_get($FILENAME, ...) + - pattern-inside: xattr_list($FILENAME, ...) + - pattern-inside: xattr_remove($FILENAME, ...) + - pattern-inside: xattr_set($FILENAME, ...) + - pattern-inside: xattr_supported($FILENAME, ...) + - pattern-inside: enchant_broker_request_pwl_dict($BROKER, $FILENAME, ...) + - pattern-inside: pspell_config_personal($CONFIG, $FILENAME, ...) + - pattern-inside: pspell_config_repl($CONFIG, $FILENAME, ...) + - pattern-inside: pspell_new_personal($FILENAME, ...) + - pattern-inside: exif_imagetype($FILENAME, ...) + - pattern-inside: getimagesize($FILENAME, ...) + - pattern-inside: image2wbmp($IMAGE, $FILENAME, ...) + - pattern-inside: imagecreatefromavif($FILENAME, ...) + - pattern-inside: imagecreatefrombmp($FILENAME, ...) + - pattern-inside: imagecreatefromgd2($FILENAME, ...) + - pattern-inside: imagecreatefromgd2part($FILENAME, ...) + - pattern-inside: imagecreatefromgd($FILENAME, ...) + - pattern-inside: imagecreatefromgif($FILENAME, ...) + - pattern-inside: imagecreatefromjpeg($FILENAME, ...) + - pattern-inside: imagecreatefrompng($FILENAME, ...) + - pattern-inside: imagecreatefromtga($FILENAME, ...) + - pattern-inside: imagecreatefromwbmp($FILENAME, ...) + - pattern-inside: imagecreatefromwebp($FILENAME, ...) + - pattern-inside: imagecreatefromxbm($FILENAME, ...) + - pattern-inside: imagecreatefromxpm($FILENAME, ...) + - pattern-inside: imageloadfont($FILENAME, ...) + - pattern-inside: imagexbm($IMAGE, $FILENAME, ...) + - pattern-inside: iptcembed($IPTC_DATA, $FILENAME, ...) + - pattern-inside: mailparse_msg_extract_part_file($MIMEMAIL, $FILENAME, ...) + - pattern-inside: mailparse_msg_extract_whole_part_file($MIMEMAIL, $FILENAME, ...) + - pattern-inside: mailparse_msg_parse_file($FILENAME, ...) + - pattern-inside: fdf_add_template($FDF_DOCUMENT, $NEWPAGE, $FILENAME, ...) + - pattern-inside: fdf_get_ap($FDF_DOCUMENT, $FIELD, $FACE, $FILENAME, ...) + - pattern-inside: fdf_open($FILENAME, ...) + - pattern-inside: fdf_save($FDF_DOCUMENT, $FILENAME, ...) + - pattern-inside: fdf_set_ap($FDF_DOCUMENT, $FIELD_NAME, $FACE, $FILENAME, ...) + - pattern-inside: ps_add_launchlink($PSDOC, $LLX, $LLY, $URX, $URY, $FILENAME, ...) + - pattern-inside: ps_add_pdflink($PSDOC, $LLX, $LLY, $URX, $URY, $FILENAME, ...) + - pattern-inside: ps_open_file($PSDOC, $FILENAME, ...) + - pattern-inside: ps_open_image_file($PSDOC, $TYPE, $FILENAME, ...) + - pattern-inside: posix_access($FILENAME, ...) + - pattern-inside: posix_mkfifo($FILENAME, ...) + - pattern-inside: posix_mknod($FILENAME, ...) + - pattern-inside: ftok($FILENAME, ...) + - pattern-inside: fann_cascadetrain_on_file($ANN, $FILENAME, ...) + - pattern-inside: fann_read_train_from_file($FILENAME, ...) + - pattern-inside: fann_train_on_file($ANN, $FILENAME, ...) + - pattern-inside: highlight_file($FILENAME, ...) + - pattern-inside: php_strip_whitespace($FILENAME, ...) + - pattern-inside: stream_resolve_include_path($FILENAME, ...) + - pattern-inside: swoole_async_read($FILENAME, ...) + - pattern-inside: swoole_async_readfile($FILENAME, ...) + - pattern-inside: swoole_async_write($FILENAME, ...) + - pattern-inside: swoole_async_writefile($FILENAME, ...) + - pattern-inside: swoole_load_module($FILENAME, ...) + - pattern-inside: tidy_parse_file($FILENAME, ...) + - pattern-inside: tidy_repair_file($FILENAME, ...) + - pattern-inside: get_meta_tags($FILENAME, ...) + - pattern-inside: yaml_emit_file($FILENAME, ...) + - pattern-inside: yaml_parse_file($FILENAME, ...) + - pattern-inside: curl_file_create($FILENAME, ...) + - pattern-inside: ftp_chmod($FTP, $PERMISSIONS, $FILENAME, ...) + - pattern-inside: ftp_delete($FTP, $FILENAME, ...) + - pattern-inside: ftp_mdtm($FTP, $FILENAME, ...) + - pattern-inside: ftp_size($FTP, $FILENAME, ...) + - pattern-inside: rrd_create($FILENAME, ...) + - pattern-inside: rrd_fetch($FILENAME, ...) + - pattern-inside: rrd_graph($FILENAME, ...) + - pattern-inside: rrd_info($FILENAME, ...) + - pattern-inside: rrd_last($FILENAME, ...) + - pattern-inside: rrd_lastupdate($FILENAME, ...) + - pattern-inside: rrd_tune($FILENAME, ...) + - pattern-inside: rrd_update($FILENAME, ...) + - pattern-inside: snmp_read_mib($FILENAME, ...) + - pattern-inside: ssh2_sftp_chmod($SFTP, $FILENAME, ...) + - pattern-inside: ssh2_sftp_realpath($SFTP, $FILENAME, ...) + - pattern-inside: ssh2_sftp_unlink($SFTP, $FILENAME, ...) + - pattern-inside: apache_lookup_uri($FILENAME, ...) + - pattern-inside: md5_file($FILENAME, ...) + - pattern-inside: sha1_file($FILENAME, ...) + - pattern-inside: simplexml_load_file($FILENAME, ...) + - pattern: $FILENAME diff --git a/PR_9_php/semgrep_php/lang/security/injection/tainted-object-instantiation.php b/PR_9_php/semgrep_php/lang/security/injection/tainted-object-instantiation.php new file mode 100644 index 0000000..60061e2 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/injection/tainted-object-instantiation.php @@ -0,0 +1,20 @@ +- + Session key based on user input risks session poisoning. + The user can determine the key used for the session, and thus + write any session variable. Session variables are typically trusted + to be set only by the application, and manipulating the session can + result in access control issues. + metadata: + technology: + - php + category: security + cwe: + - 'CWE-284: Improper Access Control' + owasp: + - A01:2021 - Broken Access Control + references: + - https://en.wikipedia.org/wiki/Session_poisoning + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + impact: MEDIUM + likelihood: MEDIUM + confidence: MEDIUM + languages: [php] + mode: taint + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: $A . $B + - pattern: bin2hex(...) + - pattern: crc32(...) + - pattern: crypt(...) + - pattern: filter_input(...) + - pattern: filter_var(...) + - pattern: hash(...) + - pattern: md5(...) + - pattern: preg_filter(...) + - pattern: preg_grep(...) + - pattern: preg_match_all(...) + - pattern: sha1(...) + - pattern: sprintf(...) + - pattern: str_contains(...) + - pattern: str_ends_with(...) + - pattern: str_starts_with(...) + - pattern: strcasecmp(...) + - pattern: strchr(...) + - pattern: stripos(...) + - pattern: stristr(...) + - pattern: strnatcasecmp(...) + - pattern: strnatcmp(...) + - pattern: strncmp(...) + - pattern: strpbrk(...) + - pattern: strpos(...) + - pattern: strripos(...) + - pattern: strrpos(...) + - pattern: strspn(...) + - pattern: strstr(...) + - pattern: strtok(...) + - pattern: substr_compare(...) + - pattern: substr_count(...) + - pattern: vsprintf(...) + pattern-sinks: + - patterns: + - pattern-inside: $_SESSION[$KEY] = $VAL; + - pattern: $KEY diff --git a/PR_9_php/semgrep_php/lang/security/injection/tainted-sql-string.php b/PR_9_php/semgrep_php/lang/security/injection/tainted-sql-string.php new file mode 100644 index 0000000..439b750 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/injection/tainted-sql-string.php @@ -0,0 +1,91 @@ +prepare("INSERT INTO test(id, + label) VALUES (?, ?)");`) or a safe library. + metadata: + cwe: + - "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/SQL_Injection + category: security + technology: + - php + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + likelihood: HIGH + impact: MEDIUM + confidence: MEDIUM + mode: taint + pattern-sanitizers: + - pattern-either: + - pattern: mysqli_real_escape_string(...) + - pattern: real_escape_string(...) + - pattern: $MYSQLI->real_escape_string(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + pattern-sinks: + - pattern-either: + - patterns: + - pattern: | + sprintf($SQLSTR, ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - patterns: + - pattern: | + "...{$EXPR}..." + - pattern-regex: | + .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - patterns: + - pattern: | + "...$EXPR..." + - pattern-regex: | + .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - patterns: + - pattern: | + "...".$EXPR + - pattern-regex: | + .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* diff --git a/PR_9_php/semgrep_php/lang/security/injection/tainted-url-host.php b/PR_9_php/semgrep_php/lang/security/injection/tainted-url-host.php new file mode 100644 index 0000000..3cb22ef --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/injection/tainted-url-host.php @@ -0,0 +1,89 @@ +- + User data flows into the host portion of this manually-constructed URL. This could allow an attacker + to send data + to their own server, potentially exposing sensitive data such as cookies or authorization information + sent with this request. + They could also probe internal servers or other resources that the server runnig this code can access. + (This is called + server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist + for approved hosts hardcode + the correct host. + metadata: + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + category: security + technology: + - php + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + impact: MEDIUM + likelihood: MEDIUM + confidence: MEDIUM + mode: taint + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + pattern-sinks: + - pattern-either: + - patterns: + - pattern: | + sprintf($URLSTR, ...) + - metavariable-pattern: + metavariable: $URLSTR + language: generic + pattern: $SCHEME://%s + - patterns: + - pattern: | + "...{$EXPR}..." + - pattern-regex: | + .*://\{.* + - patterns: + - pattern: | + "...$EXPR..." + - pattern-regex: | + .*://\$.* + - patterns: + - pattern: | + "...".$EXPR + - pattern-regex: | + .*://["'].* diff --git a/PR_9_php/semgrep_php/lang/security/ldap-bind-without-password.php b/PR_9_php/semgrep_php/lang/security/ldap-bind-without-password.php new file mode 100644 index 0000000..39c5082 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/ldap-bind-without-password.php @@ -0,0 +1,54 @@ +- + Detected anonymous LDAP bind. + This permits anonymous users to execute LDAP statements. + Consider enforcing authentication for LDAP. + metadata: + references: + - https://www.php.net/manual/en/function.ldap-bind.php + cwe: + - 'CWE-287: Improper Authentication' + owasp: + - A02:2017 - Broken Authentication + - A07:2021 - Identification and Authentication Failures + category: security + technology: + - php + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW + languages: [php] + severity: WARNING diff --git a/PR_9_php/semgrep_php/lang/security/mb-ereg-replace-eval.php b/PR_9_php/semgrep_php/lang/security/mb-ereg-replace-eval.php new file mode 100644 index 0000000..8e79160 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/mb-ereg-replace-eval.php @@ -0,0 +1,16 @@ +- + Calling mb_ereg_replace with user input in the options can lead to arbitrary + code execution. The eval modifier (`e`) evaluates the replacement argument + as code. + metadata: + cwe: + - "CWE-94: Improper Control of Generation of Code ('Code Injection')" + references: + - https://www.php.net/manual/en/function.mb-ereg-replace.php + - https://www.php.net/manual/en/function.mb-regex-set-options.php + category: security + technology: + - php + owasp: + - A03:2021 - Injection + cwe2022-top25: true + subcategory: + - audit + likelihood: LOW + impact: MEDIUM + confidence: LOW + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/mcrypt-use.php b/PR_9_php/semgrep_php/lang/security/mcrypt-use.php new file mode 100644 index 0000000..f17650f --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/mcrypt-use.php @@ -0,0 +1,26 @@ +- + Mcrypt functionality has been deprecated and/or removed in recent PHP + versions. Consider using Sodium or OpenSSL. + metadata: + cwe: + - 'CWE-676: Use of Potentially Dangerous Function' + references: + - https://www.php.net/manual/en/intro.mcrypt.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php + category: security + technology: + - php + subcategory: + - audit + likelihood: LOW + impact: MEDIUM + confidence: LOW + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/md5-loose-equality.php b/PR_9_php/semgrep_php/lang/security/md5-loose-equality.php new file mode 100644 index 0000000..b5769dd --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/md5-loose-equality.php @@ -0,0 +1,26 @@ +- + Make sure comparisons involving md5 values are strict (use `===` not `==`) to + avoid type juggling issues + metadata: + cwe: + - 'CWE-697: Incorrect Comparison' + references: + - https://www.php.net/manual/en/types.comparisons.php + - https://www.whitehatsec.com/blog/magic-hashes/ + category: security + technology: + - php + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/md5-used-as-password.php b/PR_9_php/semgrep_php/lang/security/md5-used-as-password.php new file mode 100644 index 0000000..a675f17 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/md5-used-as-password.php @@ -0,0 +1,25 @@ +setPassword($pass); +// {/fact} +} + +function test2($value) { +// {fact rule=insecure-cryptography@v1.0 defects=1} + $pass = hash('md5', $value); + // ruleid: md5-used-as-password + $user->setPassword($pass); +// {/fact} +} + +function okTest1($value) { +// {fact rule=insecure-cryptography@v1.0 defects=0} + // ok: md5-used-as-password + $pass = hash('sha256', $value); +// {/fact} + $user->setPassword($pass); +} diff --git a/PR_9_php/semgrep_php/lang/security/md5-used-as-password.yaml b/PR_9_php/semgrep_php/lang/security/md5-used-as-password.yaml new file mode 100644 index 0000000..d2ae69e --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/md5-used-as-password.yaml @@ -0,0 +1,41 @@ +rules: +- id: md5-used-as-password + severity: WARNING + message: >- + It looks like MD5 is used as a password hash. MD5 is not considered a + secure password hash because it can be cracked by an attacker in a short + amount of time. Use a suitable password hashing function such as bcrypt. + You can use `password_hash($PASSWORD, PASSWORD_BCRYPT, $OPTIONS);`. + languages: [php] + metadata: + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/html/rfc6151 + - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://www.php.net/password_hash + category: security + technology: + - md5 + subcategory: + - vuln + likelihood: HIGH + impact: MEDIUM + confidence: MEDIUM + mode: taint + pattern-sources: + - patterns: + - pattern-either: + - pattern: md5(...) + - pattern: hash('md5', ...) + pattern-sinks: + - patterns: + - pattern: $FUNCTION(...) + - metavariable-regex: + metavariable: $FUNCTION + regex: (?i)(.*password.*) diff --git a/PR_9_php/semgrep_php/lang/security/non-literal-header.php b/PR_9_php/semgrep_php/lang/security/non-literal-header.php new file mode 100644 index 0000000..b2dcb01 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/non-literal-header.php @@ -0,0 +1,18 @@ +- + 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/en/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 Request/Response Splitting')" + owasp: + - A03:2021 - Injection + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW + languages: [php] + severity: WARNING diff --git a/PR_9_php/semgrep_php/lang/security/openssl-cbc-static-iv.php b/PR_9_php/semgrep_php/lang/security/openssl-cbc-static-iv.php new file mode 100644 index 0000000..9c5cd54 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/openssl-cbc-static-iv.php @@ -0,0 +1,70 @@ +- + 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: + - A07:2021 - Identification and Authentication Failures + cwe: + - 'CWE-346: Origin Validation Error' + category: security + technology: + - php + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW + languages: [php] + severity: WARNING diff --git a/PR_9_php/semgrep_php/lang/security/php-ssrf.php b/PR_9_php/semgrep_php/lang/security/php-ssrf.php new file mode 100644 index 0000000..0b2c443 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/php-ssrf.php @@ -0,0 +1,80 @@ + diff --git a/PR_9_php/semgrep_php/lang/security/php-ssrf.yaml b/PR_9_php/semgrep_php/lang/security/php-ssrf.yaml new file mode 100644 index 0000000..0b33f2b --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/php-ssrf.yaml @@ -0,0 +1,50 @@ +rules: + - id: php-ssrf + patterns: + - pattern-either: + - pattern: | + $VAR=$DATA; + ... + $FUNCS(...,$VAR, ...); + - pattern: $FUNCS(...,$DATA, ...); + - metavariable-pattern: + metavariable: $DATA + patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - metavariable-pattern: + metavariable: $FUNCS + patterns: + - pattern-either: + - pattern: curl_setopt + - pattern: fopen + - pattern: file_get_contents + - pattern: curl_init + - pattern: readfile + message: The web server receives a URL or similar request from an upstream + component and retrieves the contents of this URL, but it does not + sufficiently ensure that the request is being sent to the expected + destination. Dangerous function $FUNCS with payload $DATA + metadata: + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + cwe: + - "CWE-918: Server-Side Request Forgery (SSRF)" + category: security + technology: + - php + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + cwe2022-top25: true + subcategory: + - audit + likelihood: LOW + impact: HIGH + confidence: LOW + languages: + - php + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/phpinfo-use.php b/PR_9_php/semgrep_php/lang/security/phpinfo-use.php new file mode 100644 index 0000000..d7e669b --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/phpinfo-use.php @@ -0,0 +1,6 @@ +- + The 'phpinfo' function may reveal sensitive information about your environment. + metadata: + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + references: + - https://www.php.net/manual/en/function.phpinfo + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/PhpinfosSniff.php + category: security + technology: + - php + owasp: + - A01:2021 - Broken Access Control + cwe2021-top25: true + subcategory: + - vuln + likelihood: MEDIUM + impact: MEDIUM + confidence: MEDIUM + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/preg-replace-eval.php b/PR_9_php/semgrep_php/lang/security/preg-replace-eval.php new file mode 100644 index 0000000..93f77c7 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/preg-replace-eval.php @@ -0,0 +1,21 @@ +- + This rule has been deprecated, see https://github.com/returntocorp/semgrep-rules/issues/2506. + metadata: + cwe: + - "CWE-94: Improper Control of Generation of Code ('Code Injection')" + references: + - https://www.php.net/manual/en/function.preg-replace.php + - https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/PregReplaceSniff.php + category: security + deprecated: true + technology: + - php + owasp: + - A03:2021 - Injection + cwe2022-top25: true + subcategory: + - audit + likelihood: LOW + impact: HIGH + confidence: LOW + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/lang/security/redirect-to-request-uri.php b/PR_9_php/semgrep_php/lang/security/redirect-to-request-uri.php new file mode 100644 index 0000000..56d8adc --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/redirect-to-request-uri.php @@ -0,0 +1,56 @@ +- + Redirecting to the current request URL may redirect to another domain, if + the current path starts with two slashes. + E.g. in https://www.example.com//attacker.com, the value of REQUEST_URI + is //attacker.com, and redirecting to it will redirect to that domain. + metadata: + references: + - https://www.php.net/manual/en/reserved.variables.server.php + - https://owasp.org/www-project-top-ten/2017/A5_2017-Broken_Access_Control.html + category: security + technology: + - php + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + cwe: + - "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')" + likelihood: MEDIUM + impact: LOW + confidence: MEDIUM + subcategory: + - vuln + languages: [php] + severity: WARNING diff --git a/PR_9_php/semgrep_php/lang/security/tainted-exec.php b/PR_9_php/semgrep_php/lang/security/tainted-exec.php new file mode 100644 index 0000000..8ff1196 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/tainted-exec.php @@ -0,0 +1,45 @@ +/dev/null", $jobName); +// {fact rule=os-command-injection@v1.0 defects=1} +//ruleid: tainted-exec +system($cmd); +// {/fact} + +$errorCode = escapeshellarg($_POST['errorCode']); +$func = escapeshellarg($_POST['func']); +$uuid = str_replace(PHP_EOL, '', file_get_contents("/proc/sys/kernel/random/uuid")); +$logsCmd = sprintf('%s%s%s', + "wdlog -l INFO -s 'adminUI' -m 'firmware_upload_page' function:string=$func ", + "status:string='updateFail' errorCode:string=$errorCode ", + "corid:string='AUI:$uuid' >/dev/null 2>&1" +); +// {fact rule=os-command-injection@v1.0 defects=0} +//ok: tainted-exec +exec($logsCmd); +// {/fact} + +$arg = $_POST['arg']; +$cmd = "logwdweb --post_migration_onboarding -%s %s"; +$cmd_logwdweb = "logwdweb --post_migration_onboarding --page %s %s"; +$_arg = sprintf("--status %s", $arg); +$cmd = sprintf($cmd_logwdweb, "raidRoaming", $_arg); +// {fact rule=os-command-injection@v1.0 defects=1} +//ruleid: tainted-exec +pclose(popen($cmd, 'r')); +// {/fact} +?> diff --git a/PR_9_php/semgrep_php/lang/security/tainted-exec.yaml b/PR_9_php/semgrep_php/lang/security/tainted-exec.yaml new file mode 100644 index 0000000..118fbc3 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/tainted-exec.yaml @@ -0,0 +1,41 @@ +rules: +- id: tainted-exec + mode: taint + pattern-sources: + - pattern: $_REQUEST + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + pattern-sinks: + - pattern: exec(...) + - pattern: system(...) + - pattern: popen(...) + - pattern: passthru(...) + - pattern: shell_exec(...) + - pattern: pcntl_exec(...) + - pattern: proc_open(...) + pattern-sanitizers: + - pattern: escapeshellarg(...) + message: >- + Executing non-constant commands. This can lead to command injection. You should use `escapeshellarg()` when using command. + metadata: + cwe: + - "CWE-94: Improper Control of Generation of Code ('Code Injection')" + references: + - https://www.stackhawk.com/blog/php-command-injection/ + - https://brightsec.com/blog/code-injection-php/ + - https://www.acunetix.com/websitesecurity/php-security-2/ + category: security + technology: + - php + owasp: + - A03:2021 - Injection + cwe2022-top25: true + subcategory: + - vuln + likelihood: HIGH + impact: HIGH + confidence: MEDIUM + languages: [php] + severity: ERROR + diff --git a/PR_9_php/semgrep_php/lang/security/unlink-use.php b/PR_9_php/semgrep_php/lang/security/unlink-use.php new file mode 100644 index 0000000..60f12d8 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/unlink-use.php @@ -0,0 +1,12 @@ +- + 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: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + cwe: + - "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')" + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - audit + likelihood: LOW + impact: MEDIUM + confidence: LOW + languages: [php] + severity: WARNING diff --git a/PR_9_php/semgrep_php/lang/security/unserialize-use.php b/PR_9_php/semgrep_php/lang/security/unserialize-use.php new file mode 100644 index 0000000..eaad60e --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/unserialize-use.php @@ -0,0 +1,12 @@ +- + 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/en/function.unserialize.php + - https://owasp.org/www-project-top-ten/2017/A8_2017-Insecure_Deserialization.html + category: security + technology: + - php + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW + languages: [php] + severity: WARNING diff --git a/PR_9_php/semgrep_php/lang/security/weak-crypto.php b/PR_9_php/semgrep_php/lang/security/weak-crypto.php new file mode 100644 index 0000000..e0030a3 --- /dev/null +++ b/PR_9_php/semgrep_php/lang/security/weak-crypto.php @@ -0,0 +1,36 @@ +- + Detected usage of weak crypto function. Consider using stronger alternatives. + metadata: + cwe: + - 'CWE-328: Use of Weak Hash' + references: + - https://www.php.net/manual/en/book.sodium.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php + category: security + technology: + - php + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + subcategory: + - audit + likelihood: LOW + impact: MEDIUM + confidence: LOW + languages: [php] + severity: ERROR diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-active-debug-code.php b/PR_9_php/semgrep_php/laravel/security/laravel-active-debug-code.php new file mode 100644 index 0000000..11dd320 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-active-debug-code.php @@ -0,0 +1,37 @@ + 'true']); +// {/fact} + +// {fact rule=detect-activated-debug-feature@v1.0 defects=1} + // ruleid: laravel-active-debug-code + putenv("APP_DEBUG=true"); +// {/fact} + +// {fact rule=detect-activated-debug-feature@v1.0 defects=1} + // ruleid: laravel-active-debug-code + $_ENV['APP_DEBUG'] = 'true'; +// {/fact} + +// {fact rule=detect-activated-debug-feature@v1.0 defects=0} + // ok: laravel-active-debug-code + config(['app.debug' => 'false']); +// {/fact} + +// {fact rule=detect-activated-debug-feature@v1.0 defects=0} + // ok: laravel-active-debug-code + putenv("APP_DEBUG=false"); +// {/fact} + +// {fact rule=detect-activated-debug-feature@v1.0 defects=0} + // ok: laravel-active-debug-code + $_ENV['APP_DEBUG'] = 'false'; +// {/fact} + + // this is ok because it retrieves the value from the env file instead of setting it directly. +// {fact rule=detect-activated-debug-feature@v1.0 defects=0} + // ok: laravel-active-debug-code + $value = config('app.debug', 'true'); +// {/fact} +?> diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-active-debug-code.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-active-debug-code.yaml new file mode 100644 index 0000000..8722179 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-active-debug-code.yaml @@ -0,0 +1,35 @@ +rules: +- id: laravel-active-debug-code + patterns: + - pattern-either: + - pattern: | + putenv("APP_DEBUG=true") + - pattern: | + config(['app.debug' => 'true']) + - pattern: | + $_ENV["APP_DEBUG"] = 'true' + message: >- + Found an instance setting the APP_DEBUG environment variable to true. In your production environment, + this should + always be false. Otherwise, you risk exposing sensitive + configuration values to potential attackers. Instead, set this to false. + languages: + - php + severity: ERROR + metadata: + category: security + cwe: + - 'CWE-489: Active Debug Code' + owasp: + - A05:2021 - Security Misconfiguration + technology: + - php + - laravel + references: + - https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Laravel_Cheat_Sheet.md + - https://laravel.com/docs/9.x/configuration + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-api-route-sql-injection.php b/PR_9_php/semgrep_php/laravel/security/laravel-api-route-sql-injection.php new file mode 100644 index 0000000..5c393fe --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-api-route-sql-injection.php @@ -0,0 +1,34 @@ + diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-api-route-sql-injection.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-api-route-sql-injection.yaml new file mode 100644 index 0000000..ccd367b --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-api-route-sql-injection.yaml @@ -0,0 +1,40 @@ +rules: +- id: laravel-api-route-sql-injection + mode: taint + pattern-sources: + - patterns: + - focus-metavariable: $ARG + - pattern-inside: | + Route::$METHOD($ROUTE_NAME, function(...,$ARG,...){...}) + pattern-sanitizers: + - patterns: + - pattern: | + DB::raw("...",[...]) + pattern-sinks: + - patterns: + - pattern: | + DB::raw(...) + message: HTTP method [$METHOD] to Laravel route $ROUTE_NAME is vulnerable to SQL injection via string + concatenation or unsafe interpolation. + languages: + - php + severity: WARNING + metadata: + category: security + cwe: + - "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Laravel_Cheat_Sheet.md + technology: + - php + - laravel + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + likelihood: HIGH + impact: MEDIUM + confidence: MEDIUM \ No newline at end of file diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-blade-form-missing-csrf.blade.php b/PR_9_php/semgrep_php/laravel/security/laravel-blade-form-missing-csrf.blade.php new file mode 100644 index 0000000..a017544 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-blade-form-missing-csrf.blade.php @@ -0,0 +1,203 @@ +// {fact rule=cross-site-request-forgery@v1.0 defects=0} + +
+ @csrf +
+ + + @endif + + {{ trans('forms.settings.app-setup.banner-help') }} + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ +
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+ + +// {fact rule=cross-site-request-forgery@v1.0 defects=0} + +
+
+
+ {{ csrf_field() }} +
+ {{-- 订单编号 --}} + + +
+
+ {{-- 立即查询 --}} + + {{-- 重置 --}} + +
+
+
+
+// {/fact} diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-blade-form-missing-csrf.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-blade-form-missing-csrf.yaml new file mode 100644 index 0000000..7c87ef8 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-blade-form-missing-csrf.yaml @@ -0,0 +1,67 @@ +rules: +- id: laravel-blade-form-missing-csrf + message: >- + Detected a form executing a state-changing HTTP method `$METHOD` to route definition + `$...ROUTE` without a Laravel CSRF decorator or explicit CSRF token implementation. + If this form modifies sensitive state this will open your application to Cross-Site + Request Forgery (CSRF) attacks. + severity: WARNING + metadata: + likelihood: LOW + impact: MEDIUM + confidence: LOW + category: security + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + owasp: + - A01:2021 - Broken Access Control + references: + - https://laravel.com/docs/9.x/csrf + subcategory: + - audit + technology: + - php + - laravel + - blade + languages: + - generic + paths: + include: + - '*.blade.php' + patterns: + - pattern: | + action="$...ROUTE" + - pattern-inside: | +
+ ... + - pattern-not-inside: | + + - metavariable-pattern: + metavariable: $...ROUTE + language: generic + patterns: + - pattern-not-regex: \A\s*\Z + - pattern-not: '#' + - metavariable-regex: + metavariable: $METHOD + regex: (?i)(post|put|patch|delete) + - pattern-not-inside: | + + ... + ... + ... + @csrf + - pattern-not-inside: | + + ... + ... + ... + csrf_field() + - pattern-not-inside: | + + ... + ... + ... + csrf_token() diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-http-only.session.php b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-http-only.session.php new file mode 100644 index 0000000..e63f095 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-http-only.session.php @@ -0,0 +1,792 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-cookie-without-http-only-flag@v1.0 defects=1} + // ruleid: laravel-cookie-http-only + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => false, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-cookie-without-http-only-flag@v1.0 defects=0} + // ok: laravel-cookie-http-only + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => env("HTTP_ONLY", false), + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-cookie-without-http-only-flag@v1.0 defects=1} + // ruleid: laravel-cookie-http-only + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-cookie-without-http-only-flag@v1.0 defects=0} + // ok: laravel-cookie-http-only + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; +?> diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-http-only.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-http-only.yaml new file mode 100644 index 0000000..6b41f05 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-http-only.yaml @@ -0,0 +1,50 @@ +rules: +- id: laravel-cookie-http-only + patterns: + - pattern: | + 'cookie' + - pattern-inside: | + return [ + ..., + 'cookie' => env(...), + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'http_only' => true, + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'http_only' => env('$NAME', $DEFAULT), + ... + ]; + paths: + include: + - '*session.php' + message: >- + Found a configuration file where the HttpOnly attribute is not set to true. Setting `http_only` to + true makes sure that your cookies are inaccessible from Javascript, which + mitigates XSS attacks. Instead, set the 'http_only' like so: + `http_only` => true + languages: + - php + severity: ERROR + metadata: + category: security + cwe: + - "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag" + owasp: + - A05:2021 - Security Misconfiguration + technology: + - php + - laravel + references: + - https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Laravel_Cheat_Sheet.md + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-long-timeout.session.php b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-long-timeout.session.php new file mode 100644 index 0000000..377311b --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-long-timeout.session.php @@ -0,0 +1,594 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ +// {fact rule=sensitive-cookie-without-http-only-flag@v1.0 defects=1} + // ruleid: laravel-cookie-long-timeout + 'lifetime' => 40, + // {/fact} + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => false, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ +// {fact rule=sensitive-cookie-without-http-only-flag@v1.0 defects=0} + // ok: laravel-cookie-long-timeout + 'lifetime' => env('SESSION_LIFETIME', 120), + // {/fact} + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ +// {fact rule=sensitive-cookie-without-http-only-flag@v1.0 defects=0} + // ok: laravel-cookie-long-timeout + 'lifetime' => 20, + // {/fact} + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; +?> diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-long-timeout.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-long-timeout.yaml new file mode 100644 index 0000000..6103e1f --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-long-timeout.yaml @@ -0,0 +1,44 @@ +rules: +- id: laravel-cookie-long-timeout + patterns: + - pattern: | + 'lifetime' + - pattern-inside: | + return [ + ..., + 'lifetime' => $TIME, + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'lifetime' => env("$VAR", $DEFAULT), + ... + ]; + - metavariable-comparison: + metavariable: $TIME + comparison: $TIME > 30 + paths: + include: + - '*session.php' + message: >- + Found a configuration file where the lifetime attribute is over 30 minutes. + languages: + - php + severity: ERROR + metadata: + category: security + cwe: + - "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag" + owasp: + - A05:2021 - Security Misconfiguration + technology: + - php + - laravel + references: + - https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Laravel_Cheat_Sheet.md + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-null-domain.session.php b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-null-domain.session.php new file mode 100644 index 0000000..475996b --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-null-domain.session.php @@ -0,0 +1,791 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-information-leak@v1.0 defects=0} + // ok: laravel-cookie-null-domain + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => false, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-information-leak@v1.0 defects=1} + // ruleid: laravel-cookie-null-domain + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => "baddomain.com", + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => false, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-information-leak@v1.0 defects=1} + // ruleid: laravel-cookie-null-domain + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-information-leak@v1.0 defects=0} + // ok: laravel-cookie-null-domain + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => null, + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; +?> diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-null-domain.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-null-domain.yaml new file mode 100644 index 0000000..9140740 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-null-domain.yaml @@ -0,0 +1,50 @@ +rules: +- id: laravel-cookie-null-domain + patterns: + - pattern: | + 'cookie' + - pattern-inside: | + return [ + ..., + 'cookie' => env(...), + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'domain' => null, + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'domain' => env('$NAME', $DEFAULT), + ... + ]; + paths: + include: + - '*session.php' + message: >- + Found a configuration file where the domain attribute is not set to null. It is recommended (unless + you are using sub-domain route registrations) to set this attribute to null so that only the + same origin can set the cookie, thus protecting your cookies. + languages: + - php + severity: ERROR + metadata: + category: security + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + owasp: + - A01:2021 - Broken Access Control + technology: + - php + - laravel + references: + - https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Laravel_Cheat_Sheet.md + cwe2021-top25: true + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-same-site.session.php b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-same-site.session.php new file mode 100644 index 0000000..3481043 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-same-site.session.php @@ -0,0 +1,987 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-cookie-with-improper-same-site-attribute@v1.0 defects=1} + // ruleid: laravel-cookie-same-site + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => false, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-cookie-with-improper-same-site-attribute@v1.0 defects=1} + // ruleid: laravel-cookie-same-site + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-cookie-with-improper-same-site-attribute@v1.0 defects=0} + // ok: laravel-cookie-same-site + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => 'lax', + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-cookie-with-improper-same-site-attribute@v1.0 defects=0} + // ok: laravel-cookie-same-site + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => 'strict', + +]; + + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=sensitive-cookie-with-improper-same-site-attribute@v1.0 defects=0} + // ok: laravel-cookie-same-site + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => env("SAME_SITE", null), + +]; +?> diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-same-site.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-same-site.yaml new file mode 100644 index 0000000..51abea6 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-same-site.yaml @@ -0,0 +1,55 @@ +rules: +- id: laravel-cookie-same-site + patterns: + - pattern: | + 'cookie' + - pattern-inside: | + return [ + ..., + 'cookie' => env(...), + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'same_site' => 'lax', + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'same_site' => 'strict', + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'same_site' => env('$NAME', $DEFAULT), + ... + ]; + paths: + include: + - '*session.php' + message: >- + Found a configuration file where the same_site attribute is not set to 'lax' or 'strict'. + Setting 'same_site' to 'lax' or 'strict' restricts cookies to a first-party or same-site context, + which will protect your cookies and prevent CSRF. + languages: + - php + severity: ERROR + metadata: + category: security + cwe: + - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' + owasp: + - A01:2021 - Broken Access Control + technology: + - php + - laravel + references: + - https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Laravel_Cheat_Sheet.md + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-secure-set.session.php b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-secure-set.session.php new file mode 100644 index 0000000..af9c0c8 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-secure-set.session.php @@ -0,0 +1,792 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=insecure-cookie@v1.0 defects=0} + // ok: laravel-cookie-secure-set + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=insecure-cookie@v1.0 defects=1} + // ruleid: laravel-cookie-secure-set + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => false, + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=insecure-cookie@v1.0 defects=0} + // ok: laravel-cookie-secure-set + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => true, + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ +// {fact rule=insecure-cookie@v1.0 defects=1} + // ruleid: laravel-cookie-secure-set + 'cookie' => env( + 'SESSION_COOKIE', + str_slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + // {/fact} + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => null, + +]; +?> \ No newline at end of file diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-cookie-secure-set.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-secure-set.yaml new file mode 100644 index 0000000..3271327 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-cookie-secure-set.yaml @@ -0,0 +1,50 @@ +rules: +- id: laravel-cookie-secure-set + patterns: + - pattern: | + 'cookie' + - pattern-inside: | + return [ + ..., + 'cookie' => env(...), + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'secure' => true, + ... + ]; + - pattern-not-inside: | + return [ + ..., + 'secure' => env('$NAME', $DEFAULT), + ... + ]; + paths: + include: + - '*session.php' + message: >- + Found a configuration file where the secure attribute is not set to 'true'. + Setting 'secure' to 'true' prevents the client from transmitting the cookie over unencrypted channels + and therefore prevents cookies from being + stolen through man in the middle attacks. + languages: + - php + severity: ERROR + metadata: + category: security + cwe: + - "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute" + owasp: + - A05:2021 - Security Misconfiguration + technology: + - php + - laravel + references: + - https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Laravel_Cheat_Sheet.md + subcategory: + - audit + likelihood: LOW + impact: LOW + confidence: LOW \ No newline at end of file diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-dangerous-model-construction.php b/PR_9_php/semgrep_php/laravel/security/laravel-dangerous-model-construction.php new file mode 100644 index 0000000..3114cc8 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-dangerous-model-construction.php @@ -0,0 +1,25 @@ +where($tainted, 'John')->first(); +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=1} +// ruleid: laravel-sql-injection +$titles = DB::table('users')->pluck($tainted); +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=1} +// ruleid: laravel-sql-injection +DB::table('users')->orderBy($tainted); +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=1} +// ruleid: laravel-sql-injection +$price = DB::table('orders')->max($tainted); +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=1} +// ruleid: laravel-sql-injection +$query = DB::table('users')->select($tainted); +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=0} +// ok: laravel-sql-injection +$user = DB::table('users')->where('name', $tainted)->first(); +// {/fact} + +// https://laravel.com/docs/8.x/queries +// Raw statements will be injected into the query as strings, so you should be extremely careful to avoid creating SQL injection vulnerabilities. +// {fact rule=sql-injection@v1.0 defects=1} +// ruleid: laravel-sql-injection +$users = DB::table('users')->select(DB::raw($tainted)); +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=1} +// ruleid: laravel-sql-injection +$orders = DB::table('orders')->selectRaw($tainted); +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=1} +// ruleid: laravel-sql-injection +$orders = DB::table('orders')->whereRaw($tainted); +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=0} +// ok: laravel-sql-injection +$orders = DB::table('orders')->selectRaw('price * ? as price_with_tax', [$tainted]); +// {/fact} + diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-sql-injection.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-sql-injection.yaml new file mode 100644 index 0000000..820751b --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-sql-injection.yaml @@ -0,0 +1,131 @@ +rules: +- id: laravel-sql-injection + metadata: + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + cwe: + - "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" + category: security + technology: + - laravel + references: + - https://laravel.com/docs/8.x/queries + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + likelihood: HIGH + impact: MEDIUM + confidence: MEDIUM + severity: WARNING + message: >- + Detected a SQL query based on user input. + This could lead to SQL injection, which could potentially result in sensitive data being exfiltrated + by attackers. Instead, use parameterized queries and prepared statements. + languages: [php] + mode: taint + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: $SQL + - pattern-either: + - pattern-inside: DB::table(...)->whereRaw($SQL, ...) + - pattern-inside: DB::table(...)->orWhereRaw($SQL, ...) + - pattern-inside: DB::table(...)->groupByRaw($SQL, ...) + - pattern-inside: DB::table(...)->havingRaw($SQL, ...) + - pattern-inside: DB::table(...)->orHavingRaw($SQL, ...) + - pattern-inside: DB::table(...)->orderByRaw($SQL, ...) + - patterns: + - pattern: $EXPRESSION + - pattern-either: + - pattern-inside: DB::table(...)->selectRaw($EXPRESSION, ...) + - pattern-inside: DB::table(...)->fromRaw($EXPRESSION, ...) + - patterns: + - pattern: $COLUMNS + - pattern-either: + - pattern-inside: DB::table(...)->whereNull($COLUMNS, ...) + - pattern-inside: DB::table(...)->orWhereNull($COLUMN) + - pattern-inside: DB::table(...)->whereNotNull($COLUMNS, ...) + - pattern-inside: DB::table(...)->whereRowValues($COLUMNS, ...) + - pattern-inside: DB::table(...)->orWhereRowValues($COLUMNS, ...) + - pattern-inside: DB::table(...)->find($ID, $COLUMNS) + - pattern-inside: DB::table(...)->paginate($PERPAGE, $COLUMNS, ...) + - pattern-inside: DB::table(...)->simplePaginate($PERPAGE, $COLUMNS, ...) + - pattern-inside: DB::table(...)->cursorPaginate($PERPAGE, $COLUMNS, ...) + - pattern-inside: DB::table(...)->getCountForPagination($COLUMNS) + - pattern-inside: DB::table(...)->aggregate($FUNCTION, $COLUMNS) + - pattern-inside: DB::table(...)->numericAggregate($FUNCTION, $COLUMNS) + - pattern-inside: DB::table(...)->insertUsing($COLUMNS, ...) + - pattern-inside: DB::table(...)->select($COLUMNS) + - pattern-inside: DB::table(...)->get($COLUMNS) + - pattern-inside: DB::table(...)->count($COLUMNS) + - patterns: + - pattern: $COLUMN + - pattern-either: + - pattern-inside: DB::table(...)->whereIn($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereIn($COLUMN, ...) + - pattern-inside: DB::table(...)->whereNotIn($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereNotIn($COLUMN, ...) + - pattern-inside: DB::table(...)->whereIntegerInRaw($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereIntegerInRaw($COLUMN, ...) + - pattern-inside: DB::table(...)->whereIntegerNotInRaw($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereIntegerNotInRaw($COLUMN, ...) + - pattern-inside: DB::table(...)->whereBetweenColumns($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereBetween($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereBetweenColumns($COLUMN, ...) + - pattern-inside: DB::table(...)->whereNotBetween($COLUMN, ...) + - pattern-inside: DB::table(...)->whereNotBetweenColumns($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereNotBetween($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereNotBetweenColumns($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereNotNull($COLUMN) + - pattern-inside: DB::table(...)->whereDate($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereDate($COLUMN, ...) + - pattern-inside: DB::table(...)->whereTime($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereTime($COLUMN, ...) + - pattern-inside: DB::table(...)->whereDay($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereDay($COLUMN, ...) + - pattern-inside: DB::table(...)->whereMonth($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereMonth($COLUMN, ...) + - pattern-inside: DB::table(...)->whereYear($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereYear($COLUMN, ...) + - pattern-inside: DB::table(...)->whereJsonContains($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereJsonContains($COLUMN, ...) + - pattern-inside: DB::table(...)->whereJsonDoesntContain($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereJsonDoesntContain($COLUMN, ...) + - pattern-inside: DB::table(...)->whereJsonLength($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereJsonLength($COLUMN, ...) + - pattern-inside: DB::table(...)->having($COLUMN, ...) + - pattern-inside: DB::table(...)->orHaving($COLUMN, ...) + - pattern-inside: DB::table(...)->havingBetween($COLUMN, ...) + - pattern-inside: DB::table(...)->orderBy($COLUMN, ...) + - pattern-inside: DB::table(...)->orderByDesc($COLUMN) + - pattern-inside: DB::table(...)->latest($COLUMN) + - pattern-inside: DB::table(...)->oldest($COLUMN) + - pattern-inside: DB::table(...)->forPageBeforeId($PERPAGE, $LASTID, $COLUMN) + - pattern-inside: DB::table(...)->forPageAfterId($PERPAGE, $LASTID, $COLUMN) + - pattern-inside: DB::table(...)->value($COLUMN) + - pattern-inside: DB::table(...)->pluck($COLUMN, ...) + - pattern-inside: DB::table(...)->implode($COLUMN, ...) + - pattern-inside: DB::table(...)->min($COLUMN) + - pattern-inside: DB::table(...)->max($COLUMN) + - pattern-inside: DB::table(...)->sum($COLUMN) + - pattern-inside: DB::table(...)->avg($COLUMN) + - pattern-inside: DB::table(...)->average($COLUMN) + - pattern-inside: DB::table(...)->increment($COLUMN, ...) + - pattern-inside: DB::table(...)->decrement($COLUMN, ...) + - pattern-inside: DB::table(...)->where($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhere($COLUMN, ...) + - pattern-inside: DB::table(...)->addSelect($COLUMN) + - patterns: + - pattern: $QUERY + - pattern-inside: DB::unprepared($QUERY) \ No newline at end of file diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-unsafe-validator.php b/PR_9_php/semgrep_php/laravel/security/laravel-unsafe-validator.php new file mode 100644 index 0000000..86b93e9 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-unsafe-validator.php @@ -0,0 +1,192 @@ +middleware("auth"); + } + + function index(){ + if(Auth::user()->accesslevel == env("ACCTNG_HEAD")){ + $accounts = \App\ChartOfAccount::orderBy("accounting_name")->get(); + return view("accounting.chart_of_accounts.index", compact("accounts")); + } + } + + function new_account(Request $request){ + if(Auth::user()->accesslevel == env("ACCTNG_HEAD")){ + $validate = Validator::make($request->all(),[ +// {fact rule=sql-injection@v1.0 defects=0} + // ok: laravel-unsafe-validator + "accounting_code" => "required|unique:chart_of_accounts", +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=0} + // ok: laravel-unsafe-validator + "accounting_name" => "required|unique:chart_of_accounts", +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=0} + // ok: laravel-unsafe-validator + "some_property" => [ Rule::unique("some_column_name")->ignore(Auth::user()->id, "pk_column_name"), "required" ] + ]); +// {/fact} + + if($validate->fails()){ + return redirect()->back()->withErrors($validate); + } + + $newaccount = new \App\ChartOfAccount; + $newaccount->accounting_code = $request->accounting_code; + $newaccount->accounting_name = $request->accounting_name; + $newaccount->category = $request->category; + $newaccount->save(); + + return redirect()->back()->withSuccess("Successfully created!"); + } + } + + function print_lists(){ + if(Auth::user()->accesslevel == env("ACCTNG_HEAD")){ + $accounts = \App\ChartOfAccount::orderBy("accounting_name")->get(); + $pdf = PDF::loadView('accounting.chart_of_accounts.print_lists',compact('accounts')); + $pdf->setPaper('letter','portrait'); + return $pdf->stream("chart_of_accounts.pdf"); + } + } + + function delete_account($id){ + if(Auth::user()->accesslevel == env("ACCTNG_HEAD")){ + $account = \App\ChartOfAccount::find($id); + + $exists = \App\Accounting::where(function($query) use($account){ + $query->where("accounting_code", $account->accounting_code) + ->orWhere("accounting_name", $account->accounting_name); + })->get(); + + if($exists->isEmpty()){ + $account->delete(); + + return redirect()->back()->withSuccess("Account already deleted!"); + }else{ + + return redirect()->back()->withErrors("The account you are trying to delete already have a record."); + } + + } + } + + function update_account($id){ + if(Auth::user()->accesslevel == env("ACCTNG_HEAD")){ + $account = \App\ChartOfAccount::find($id); + + $exists = \App\Accounting::where(function($query) use($account){ + $query->where("accounting_code", $account->accounting_code) + ->orWhere("accounting_name", $account->accounting_name); + })->get(); + + if($exists->isEmpty()){ + return view("accounting.chart_of_accounts.update_form", compact("id","account")); + }else{ + return redirect()->back()->withErrors("The account you are trying to update already have a record."); + } + + } + } + + function update_account_post(Request $request){ + $validate = Validator::make($request->all(),[ +// {fact rule=sql-injection@v1.0 defects=1} + // ruleid: laravel-unsafe-validator + "accounting_code" => [ Rule::unique("chart_of_accounts")->ignore($request->chart_id,"id"), "required" ], +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=1} + // ruleid: laravel-unsafe-validator + "accounting_name" => [ Rule::unique("chart_of_accounts")->ignore($request->chart_id,"id"), "required" ], + ]); +// {/fact} + + if($validate->fails()){ + return redirect(url("/accounting/chart_of_accounts"))->withErrors($validate); + } + + $newaccount = \App\ChartOfAccount::find($request->chart_id); + $newaccount->accounting_code = $request->accounting_code; + $newaccount->accounting_name = $request->accounting_name; + $newaccount->category = $request->category; + $newaccount->save(); + + return redirect(url("/accounting/chart_of_accounts"))->withSuccess("Successfully updated!"); + } + + function update_account_post2(Request $request){ + $validate = Validator::make($request->all(),[ + "accounting_code" => [ +// {fact rule=sql-injection@v1.0 defects=1} + // ruleid: laravel-unsafe-validator + Rule::unique("chart_of_accounts")->ignore($id, $request->input('column')), +// {/fact} + "required" + ], + ]); + + if($validate->fails()){ + return redirect(url("/accounting/chart_of_accounts"))->withErrors($validate); + } + + $newaccount = \App\ChartOfAccount::find($request->chart_id); + $newaccount->accounting_code = $request->accounting_code; + $newaccount->accounting_name = $request->accounting_name; + $newaccount->category = $request->category; + $newaccount->save(); + + return redirect(url("/accounting/chart_of_accounts"))->withSuccess("Successfully updated!"); + } +} + + +use Illuminate\Foundation\Http\FormRequest; +use Illuminate\Validation\Rule; + + +class TestRequest extends FormRequest +{ + public function rules() + { + + $id = $this->query->get('hello'); +// {fact rule=sql-injection@v1.0 defects=1} + // ruleid: laravel-unsafe-validator + $test_unique1 = Rule::unique('users')->ignore($id); +// {/fact} + + $hello = 1; +// {fact rule=sql-injection@v1.0 defects=1} + // ruleid: laravel-unsafe-validator + $test_unique2 = Rule::unique('users')->ignore($hello, $this->input('hello')); +// {/fact} + +// {fact rule=sql-injection@v1.0 defects=0} + // ok: laravel-unsafe-validator + $ok_unique = Rule::unique('users')->ignore($this->user()->id); +// {/fact} + + return [ + 'title' => [ + 'required', + $test_unique1, + $test_unique2 + ] + ]; + } +} diff --git a/PR_9_php/semgrep_php/laravel/security/laravel-unsafe-validator.yaml b/PR_9_php/semgrep_php/laravel/security/laravel-unsafe-validator.yaml new file mode 100644 index 0000000..3a582d4 --- /dev/null +++ b/PR_9_php/semgrep_php/laravel/security/laravel-unsafe-validator.yaml @@ -0,0 +1,64 @@ +rules: +- id: laravel-unsafe-validator + mode: taint + pattern-sources: + - patterns: + - pattern: | + public function $F(...,Request $R,...){...} + - focus-metavariable: $R + - patterns: + - pattern-either: + - pattern: | + $this->$PROPERTY + - pattern: | + $this->$PROPERTY->$GET + - metavariable-pattern: + metavariable: $PROPERTY + patterns: + - pattern-either: + - pattern: query + - pattern: request + - pattern: headers + - pattern: cookies + - pattern: cookie + - pattern: files + - pattern: file + - pattern: allFiles + - pattern: input + - pattern: all + - pattern: post + - pattern: json + - pattern-either: + - pattern-inside: | + class $CL extends Illuminate\Http\Request {...} + - pattern-inside: | + class $CL extends Illuminate\Foundation\Http\FormRequest {...} + pattern-sinks: + - patterns: + - pattern: | + Illuminate\Validation\Rule::unique(...)->ignore(...,$IGNORE,...) + - focus-metavariable: $IGNORE + message: Found a request argument passed to an `ignore()` definition in a Rule constraint. This + can lead to SQL injection. + languages: + - php + severity: ERROR + metadata: + category: security + cwe: + - "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + technology: + - php + - laravel + references: + - https://laravel.com/docs/9.x/validation#rule-unique + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - vuln + likelihood: HIGH + impact: MEDIUM + confidence: MEDIUM \ No newline at end of file diff --git a/PR_9_php/semgrep_php/symfony/security/audit/symfony-csrf-protection-disabled.php b/PR_9_php/semgrep_php/symfony/security/audit/symfony-csrf-protection-disabled.php new file mode 100644 index 0000000..77b5203 --- /dev/null +++ b/PR_9_php/semgrep_php/symfony/security/audit/symfony-csrf-protection-disabled.php @@ -0,0 +1,148 @@ +setDefaults([ + 'data_class' => Type::class, + 'csrf_protection' => false + ]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=1} + // ruleid: symfony-csrf-protection-disabled + $resolver->setDefaults(array( + 'csrf_protection' => false + )); +// {/fact} + + + $csrf = false; +// {fact rule=coral-csrf-rule@v1.0 defects=1} + // ruleid: symfony-csrf-protection-disabled + $resolver->setDefaults([ + 'csrf_protection' => $csrf + ]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=0} + // ok: symfony-csrf-protection-disabled + $resolver->setDefaults([ + 'csrf_protection' => true + ]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=0} + // ok: symfony-csrf-protection-disabled + $resolver->setDefaults([ + 'data_class' => Type::class, + ]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=0} + // ok: symfony-csrf-protection-disabled + $resolver->setDefaults($options); + } +// {/fact} +} + +class TestExtension extends Extension implements PrependExtensionInterface +{ + public function prepend(ContainerBuilder $container) + { + +// {fact rule=coral-csrf-rule@v1.0 defects=1} + // ruleid: symfony-csrf-protection-disabled + $container->prependExtensionConfig('framework', ['csrf_protection' => false,]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=1} + // ruleid: symfony-csrf-protection-disabled + $container->prependExtensionConfig('framework', ['something_else' => true, 'csrf_protection' => false,]); +// {/fact} + + $csrfOption = false; +// {fact rule=coral-csrf-rule@v1.0 defects=1} + // ruleid: symfony-csrf-protection-disabled + $container->prependExtensionConfig('framework', ['csrf_protection' => $csrfOption,]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=1} + // ruleid: symfony-csrf-protection-disabled + $container->loadFromExtension('framework', ['csrf_protection' => false,]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=0} + // ok: symfony-csrf-protection-disabled + $container->loadFromExtension('framework', ['csrf_protection' => null,]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=0} + // ok: symfony-csrf-protection-disabled + $container->prependExtensionConfig('framework', ['csrf_protection' => true,]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=0} + // ok: symfony-csrf-protection-disabled + $container->prependExtensionConfig('framework', ['csrf_protection' => null,]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=0} + // ok: symfony-csrf-protection-disabled + $container->prependExtensionConfig('something_else', ['csrf_protection' => false,]); +// {/fact} + } +} + +class MyController1 extends AbstractController +{ + public function action() + { +// {fact rule=coral-csrf-rule@v1.0 defects=1} + // ruleid: symfony-csrf-protection-disabled + $this->createForm(TaskType::class, $task, [ + 'other_option' => false, + 'csrf_protection' => false, + ]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=1} + // ruleid: symfony-csrf-protection-disabled + $this->createForm(TaskType::class, $task, array( + 'csrf_protection' => false, + )); +// {/fact} + + $csrf = false; +// {fact rule=coral-csrf-rule@v1.0 defects=1} + // ruleid: symfony-csrf-protection-disabled + $this->createForm(TaskType::class, $task, array( + 'csrf_protection' => $csrf, + )); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=0} + // ok: symfony-csrf-protection-disabled + $this->createForm(TaskType::class, $task, ['csrf_protection' => true]); +// {/fact} + +// {fact rule=coral-csrf-rule@v1.0 defects=0} + // ok: symfony-csrf-protection-disabled + $this->createForm(TaskType::class, $task, ['other_option' => false]); +// {/fact} + + $this->redirectToRoute('/'); + } +} diff --git a/PR_9_php/semgrep_php/symfony/security/audit/symfony-csrf-protection-disabled.yaml b/PR_9_php/semgrep_php/symfony/security/audit/symfony-csrf-protection-disabled.yaml new file mode 100644 index 0000000..fac8ae7 --- /dev/null +++ b/PR_9_php/semgrep_php/symfony/security/audit/symfony-csrf-protection-disabled.yaml @@ -0,0 +1,39 @@ +rules: +- 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 protection 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: + - A01:2021 - Broken Access Control + category: security + technology: + - symfony + cwe2022-top25: true + cwe2021-top25: true + subcategory: + - audit + likelihood: LOW + impact: MEDIUM + confidence: LOW + languages: [php] + severity: WARNING diff --git a/PR_9_php/semgrep_php/symfony/security/audit/symfony-non-literal-redirect.php b/PR_9_php/semgrep_php/symfony/security/audit/symfony-non-literal-redirect.php new file mode 100644 index 0000000..38ef94b --- /dev/null +++ b/PR_9_php/semgrep_php/symfony/security/audit/symfony-non-literal-redirect.php @@ -0,0 +1,49 @@ +get('foobar'); +// {fact rule=open-redirect@v1.0 defects=1} + // ruleid: symfony-non-literal-redirect + return $this->redirect($foobar); +// {/fact} + } + + public function test2(): RedirectResponse + { + $addr = $request->query->get('page', 1); +// {fact rule=open-redirect@v1.0 defects=1} + // ruleid: symfony-non-literal-redirect + return $this->redirect('https://'. $addr); +// {/fact} + } + + public function okTest1(): RedirectResponse + { + $foobar = $session->get('foobar'); +// {fact rule=open-redirect@v1.0 defects=0} + // ok: symfony-non-literal-redirect + return $this->redirectToRoute($foobar); +// {/fact} + } + + public function okTest2(): RedirectResponse + { +// {fact rule=open-redirect@v1.0 defects=0} + // ok: symfony-non-literal-redirect + return $this->redirect('http://symfony.com/doc'); +// {/fact} + } + + public function okTest3(): RedirectResponse + { +// {fact rule=open-redirect@v1.0 defects=0} + // ok: symfony-non-literal-redirect + return $this->redirect(); +// {/fact} + } + +} diff --git a/PR_9_php/semgrep_php/symfony/security/audit/symfony-non-literal-redirect.yaml b/PR_9_php/semgrep_php/symfony/security/audit/symfony-non-literal-redirect.yaml new file mode 100644 index 0000000..0704a27 --- /dev/null +++ b/PR_9_php/semgrep_php/symfony/security/audit/symfony-non-literal-redirect.yaml @@ -0,0 +1,29 @@ +rules: +- id: symfony-non-literal-redirect + patterns: + - pattern: $this->redirect(...) + - pattern-not: $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: + - A01:2021 - Broken Access Control + cwe: + - "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')" + category: security + technology: + - symfony + subcategory: + - audit + likelihood: LOW + impact: MEDIUM + confidence: LOW + severity: WARNING diff --git a/PR_9_php/semgrep_php/symfony/security/audit/symfony-permissive-cors.php b/PR_9_php/semgrep_php/symfony/security/audit/symfony-permissive-cors.php new file mode 100644 index 0000000..96413b4 --- /dev/null +++ b/PR_9_php/semgrep_php/symfony/security/audit/symfony-permissive-cors.php @@ -0,0 +1,69 @@ + '*']); +// {/fact} + +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=1} +// ruleid: symfony-permissive-cors +$response = new Response('content', Response::HTTP_OK, Array('Access-Control-Allow-Origin' => '*')); +// {/fact} + +// {ex-fact rule=origins-verified-cross-origin-communications@v1.0 defects=1} +// ruleid: symfony-permissive-cors +//$response = new response('content', Response::HTTP_OK, Array('Access-Control-Allow-Origin' => '*')); +// {/ex-fact} + +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=1} +// ruleid: symfony-permissive-cors +$response = new FooResponse('content', Response::HTTP_OK, ['Access-Control-Allow-Origin' => '*']); +// {/fact} + + +$headers = ['Access-Control-Allow-Origin' => '*']; +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=1} +// ruleid: symfony-permissive-cors +$response = new Response('content', Response::HTTP_OK, $headers); +// {/fact} + + +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=1} +// ruleid: symfony-permissive-cors +$response->headers->set(' access-control-allow-origin ', ' * '); +// {/fact} + + +$safe = ['foo' => 'bar']; +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=0} +// ok: symfony-permissive-cors +$response = new Response('content', Response::HTTP_OK, $safe); +// {/fact} + +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=0} +// ok: symfony-permissive-corsx +$response = new Response('content', Response::HTTP_OK, ['Access-Control-Allow-Origin' => 'https://www.example.com']); +// {/fact} + +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=0} +// ok: symfony-permissive-cors +$response = new Response('content', Response::HTTP_OK, ['Other-Property' => '*']); +// {/fact} + +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=0} +// ok: symfony-permissive-cors +$response = new Foo('content', Response::HTTP_OK, ['Access-Control-Allow-Origin' => '*']); +// {/fact} + +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=0} +// ok: symfony-permissive-cors +$response->headers->set('Access-Control-Allow-Origin', 'foo'); +// {/fact} + +// {fact rule=origins-verified-cross-origin-communications@v1.0 defects=0} +// ok: symfony-permissive-cors +$response->headers->set('Other-Property', '*'); +// {/fact} diff --git a/PR_9_php/semgrep_php/symfony/security/audit/symfony-permissive-cors.yaml b/PR_9_php/semgrep_php/symfony/security/audit/symfony-permissive-cors.yaml new file mode 100644 index 0000000..264f239 --- /dev/null +++ b/PR_9_php/semgrep_php/symfony/security/audit/symfony-permissive-cors.yaml @@ -0,0 +1,45 @@ +rules: +- 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: + - A07:2021 - Identification and Authentication Failures + cwe: + - 'CWE-346: Origin Validation Error' + category: security + technology: + - symfony + subcategory: + - audit + likelihood: LOW + impact: MEDIUM + confidence: LOW + languages: [php] + severity: WARNING diff --git a/PR_9_php/semgrep_php/wordpress-plugins/security/audit/wp-ajax-no-auth-and-auth-hooks-audit.php b/PR_9_php/semgrep_php/wordpress-plugins/security/audit/wp-ajax-no-auth-and-auth-hooks-audit.php new file mode 100644 index 0000000..d2ae977 --- /dev/null +++ b/PR_9_php/semgrep_php/wordpress-plugins/security/audit/wp-ajax-no-auth-and-auth-hooks-audit.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/PR_9_php/semgrep_php/wordpress-plugins/security/audit/wp-ajax-no-auth-and-auth-hooks-audit.yaml b/PR_9_php/semgrep_php/wordpress-plugins/security/audit/wp-ajax-no-auth-and-auth-hooks-audit.yaml new file mode 100644 index 0000000..abb520d --- /dev/null +++ b/PR_9_php/semgrep_php/wordpress-plugins/security/audit/wp-ajax-no-auth-and-auth-hooks-audit.yaml @@ -0,0 +1,33 @@ +rules: + - id: wp-ajax-no-auth-and-auth-hooks-audit + patterns: + - pattern: add_action($HOOK,...) + - metavariable-regex: + metavariable: $HOOK + regex: "'wp_ajax_.*'" + message: >- + These hooks allow the developer to handle the custom AJAX + endpoints."wp_ajax_$action" hook get fires for any authenticated user and + "wp_ajax_nopriv_$action" hook get fires for non-authenticated users. + paths: + include: + - wp-content/plugins/**/*.php + languages: + - php + severity: WARNING + metadata: + category: security + confidence: LOW + likelihood: LOW + impact: MEDIUM + subcategory: + - audit + technology: + - Wordpress Plugins + references: + - https://github.com/wpscanteam/wpscan/wiki/WordPress-Plugin-Security-Testing-Cheat-Sheet#authorisation + - https://developer.wordpress.org/reference/hooks/wp_ajax_action/ + owasp: + - A01:2021 - Broken Access Control + cwe: + - "CWE-285: Improper Authorization"