Skip to content

Commit

Permalink
fix(php/symphony): split insecure cookie rule
Browse files Browse the repository at this point in the history
  • Loading branch information
elsapet committed Feb 1, 2024
1 parent 63b2b16 commit c615849
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 308 deletions.
87 changes: 87 additions & 0 deletions rules/php/symfony/cookie_missing_http_only.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
imports:
- php_shared_lang_instance
patterns:
- pattern: |
$<CLASS>::create($<_>, $<_>, $<_>, $<_>, $<_>, $<_>, $<HTTP_ONLY>$<...>)
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- variable: HTTP_ONLY
detection: php_symfony_cookie_missing_http_only_false
scope: cursor
- pattern: |
$<CLASS>::create(httpOnly: $<HTTP_ONLY>)
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- variable: HTTP_ONLY
detection: php_symfony_cookie_missing_http_only_false
scope: cursor
- pattern: |
new $<CLASS>($<_>, $<_>, $<_>, $<_>, $<_>, $<_>, $<HTTP_ONLY>$<...>)
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- variable: HTTP_ONLY
detection: php_symfony_cookie_missing_http_only_false
scope: cursor
- pattern: |
new $<CLASS>(httpOnly: $<HTTP_ONLY>)
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- variable: HTTP_ONLY
detection: php_symfony_cookie_missing_http_only_false
scope: cursor
- pattern: $<COOKIE>->withHttpOnly($<HTTP_ONLY>)
filters:
- variable: COOKIE
detection: php_symfony_cookie_missing_http_only_instance
scope: cursor
- variable: HTTP_ONLY
detection: php_symfony_cookie_missing_http_only_false
scope: cursor
auxiliary:
- id: php_symfony_cookie_missing_http_only_false
patterns:
- "false;"
- id: php_symfony_cookie_missing_http_only_instance
patterns:
- pattern: $<INSTANCE>;
filters:
- variable: INSTANCE
detection: php_shared_lang_instance
scope: cursor
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- pattern: |
$<CLASS>::create()
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- pattern: $<COOKIE>->$<_>()
filters:
- variable: COOKIE
detection: php_symfony_cookie_missing_http_only_instance
scope: cursor
languages:
- php
metadata:
description: "Missing 'HTTPOnly' options in cookie configuration."
remediation_message: |
## Description
The "HttpOnly" attribute when set to "true" protects the cookie value from
being accessed by client side JavaScript such as reading the "document.cookie"
values. By enabling this protection, a website that is vulnerable to Cross-Site
Scripting (XSS) will be able to block malicious scripts from accessing the
cookie value from JavaScript.
## Remediations
✅ Set `httpOnly` to `true` to avoid the cookie being sent by client-side scripts.
cwe_id:
- 1004
id: php_symfony_cookie_missing_http_only
documentation_url: https://docs.bearer.com/reference/rules/php_symfony_cookie_missing_http_only
cloud_code_suggestions: true
49 changes: 4 additions & 45 deletions rules/php/symfony/insecure_cookie.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,6 @@ patterns:
- variable: SECURE
detection: php_symfony_insecure_cookie_false
scope: cursor
- pattern: |
$<CLASS>::create($<_>, $<_>, $<_>, $<_>, $<_>, $<_>, $<HTTP_ONLY>$<...>)
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- variable: HTTP_ONLY
detection: php_symfony_insecure_cookie_false
scope: cursor
- pattern: |
$<CLASS>::create(httpOnly: $<HTTP_ONLY>)
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- variable: HTTP_ONLY
detection: php_symfony_insecure_cookie_false
scope: cursor
- pattern: |
new $<CLASS>($<_>, $<_>, $<_>, $<_>, $<_>, $<SECURE>$<...>)
filters:
Expand All @@ -49,22 +33,6 @@ patterns:
- variable: SECURE
detection: php_symfony_insecure_cookie_false
scope: cursor
- pattern: |
new $<CLASS>($<_>, $<_>, $<_>, $<_>, $<_>, $<_>, $<HTTP_ONLY>$<...>)
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- variable: HTTP_ONLY
detection: php_symfony_insecure_cookie_false
scope: cursor
- pattern: |
new $<CLASS>(httpOnly: $<HTTP_ONLY>)
filters:
- variable: CLASS
regex: \A(\\?Symfony\\Component\\HttpFoundation\\)?Cookie\z
- variable: HTTP_ONLY
detection: php_symfony_insecure_cookie_false
scope: cursor
- pattern: $<COOKIE>->withSecure($<SECURE>)
filters:
- variable: COOKIE
Expand All @@ -73,14 +41,6 @@ patterns:
- variable: SECURE
detection: php_symfony_insecure_cookie_false
scope: cursor
- pattern: $<COOKIE>->withHttpOnly($<HTTP_ONLY>)
filters:
- variable: COOKIE
detection: php_symfony_insecure_cookie_instance
scope: cursor
- variable: HTTP_ONLY
detection: php_symfony_insecure_cookie_false
scope: cursor
auxiliary:
- id: php_symfony_insecure_cookie_false
patterns:
Expand Down Expand Up @@ -108,18 +68,17 @@ auxiliary:
languages:
- php
metadata:
description: "Insecure options for cookie detected."
description: "Missing secure options for cookie detected."
remediation_message: |
## Description
To make sure cookies don't open your application up to exploits or
unauthorized access, make sure to set security options appropriately.
A cookie that is configured to be secure ensures that a client will only send the cookie to the server when HTTPS is being used.
This prevents the cookie from being observed by unauthorized third parties.
## Remediations
✅ Set `httpOnly` to `true` to avoid the cookie being sent by client-side scripts.
✅ Set `secure` to `true` to force cookies to only send over HTTPS.
cwe_id:
- 1004
- 614
id: php_symfony_insecure_cookie
documentation_url: https://docs.bearer.com/reference/rules/php_symfony_insecure_cookie
Expand Down
18 changes: 18 additions & 0 deletions tests/php/symfony/cookie_missing_http_only/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const {
createNewInvoker,
getEnvironment,
} = require("../../../helper.js")
const { ruleId, ruleFile, testBase } = getEnvironment(__dirname)

describe(ruleId, () => {
const invoke = createNewInvoker(ruleId, ruleFile, testBase)

test("cookie_missing_http_only", () => {
const testCase = "index.php"

const results = invoke(testCase)

expect(results.Missing).toEqual([])
expect(results.Extra).toEqual([])
})
})
26 changes: 26 additions & 0 deletions tests/php/symfony/cookie_missing_http_only/testdata/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Use bearer:expected php_symfony_cookie_missing_http_only to flag expected findings

<?php

use Symfony\Component\HttpFoundation\Cookie;

Cookie::create($name, $value, $expire, $path, $domain, false, $httpOnly);
// bearer:expected php_symfony_cookie_missing_http_only
Cookie::create($name, $value, $expire, $path, $domain, $secure, false, $raw);
// bearer:expected php_symfony_cookie_missing_http_only
Cookie::create($name, $value, httpOnly: false);

$cookie = Cookie::create($name, $value);
// bearer:expected php_symfony_cookie_missing_http_only
$cookie->withRaw(false)->withHttpOnly(false);

new Cookie($name, $value, secure: false);
// bearer:expected php_symfony_cookie_missing_http_only
new Cookie($name, $value, $expire, $path, $domain, $secure, false, $raw);
// bearer:expected php_symfony_cookie_missing_http_only
new Cookie($name, $value, httpOnly: false);

$cookie = new Cookie($name, $value);
$cookie->withRaw(false)->withSecure(false);
// bearer:expected php_symfony_cookie_missing_http_only
$cookie->withRaw(false)->withHttpOnly(false);
Loading

0 comments on commit c615849

Please sign in to comment.