Skip to content

Commit

Permalink
feat(python): insecure cookie rule (CWE-614) (#393)
Browse files Browse the repository at this point in the history
  • Loading branch information
elsapet authored May 16, 2024
1 parent 34dbcf6 commit eb18ecf
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 0 deletions.
36 changes: 36 additions & 0 deletions rules/python/django/insecure_cookie.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
imports:
- python_shared_django_http_response
patterns:
- pattern: |
$<RESPONSE>.set_cookie($<...>secure=$<FALSE>$<...>)
filters:
- variable: RESPONSE
detection: python_shared_django_http_response
scope: cursor
- variable: "FALSE"
detection: python_django_insecure_cookie_false
scope: cursor
auxiliary:
- id: python_django_insecure_cookie_false
patterns:
- "False"
languages:
- python
severity: medium
metadata:
description: Missing Secure option in cookie configuration
remediation_message: |-
## Description
When a cookie lacks the Secure option, it can be transmitted over insecure connections, making it vulnerable to interception by unauthorized parties. The Secure option is important because it instructs the browser to only send the cookie over HTTPS, enhancing security.
## Remediations
- **Do** set the `secure` option to `True` for cookies to ensure they are only sent over HTTPS, enhancing the security of data transmission.
```python
HttpResponse.set_cookie(key, value, secure = True)
```
cwe_id:
- 614
id: python_django_insecure_cookie
documentation_url: https://docs.bearer.com/reference/rules/python_django_insecure_cookie
66 changes: 66 additions & 0 deletions rules/python/lang/insecure_cookie.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
imports:
- python_shared_lang_import2
patterns:
- pattern: |
$<COOKIE_SESSION>['secure'] = $<FALSE>
filters:
- variable: COOKIE_SESSION
detection: python_lang_insecure_cookie_session
scope: cursor
- variable: "FALSE"
detection: python_lang_insecure_cookie_false
scope: cursor
auxiliary:
- id: python_lang_insecure_cookie_false
patterns:
- "False"
- id: python_lang_insecure_cookie_session
patterns:
- pattern: $<COOKIE_INIT>[$<_>]
filters:
- variable: COOKIE_INIT
detection: python_lang_insecure_cookie_init
scope: result
- id: python_lang_insecure_cookie_init
patterns:
- pattern: $<COOKIE>()
filters:
- variable: COOKIE
detection: python_lang_insecure_cookie_class
scope: result
- id: python_lang_insecure_cookie_class
patterns:
- pattern: $<COOKIE_CLASS>
filters:
- variable: COOKIE_CLASS
detection: python_shared_lang_import2
scope: cursor
filters:
- variable: MODULE1
values: [http]
- variable: MODULE2
values: [cookies]
- variable: NAME
values:
- BaseCookie
- SimpleCookie
languages:
- python
severity: medium
metadata:
description: Missing Secure option in cookie configuration
remediation_message: |-
## Description
When a cookie lacks the Secure option, it can be transmitted over insecure connections, making it vulnerable to interception by unauthorized parties. The Secure option is important because it instructs the browser to only send the cookie over HTTPS, enhancing security.
## Remediations
- **Do** set the `secure` option to `True` for cookies to ensure they are only sent over HTTPS, enhancing the security of data transmission.
```python
cookie['my_session_id']['secure'] = True
```
cwe_id:
- 614
id: python_lang_insecure_cookie
documentation_url: https://docs.bearer.com/reference/rules/python_lang_insecure_cookie
20 changes: 20 additions & 0 deletions tests/python/django/insecure_cookie/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const {
createNewInvoker,
getEnvironment,
} = require("../../../helper.js")
const { ruleId, ruleFile, testBase } = getEnvironment(__dirname)

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

test("insecure_cookie", () => {
const testCase = "main.py"

const results = invoke(testCase)

expect(results).toEqual({
Missing: [],
Extra: []
})
})
})
13 changes: 13 additions & 0 deletions tests/python/django/insecure_cookie/testdata/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.http import HttpResponse

def bad():
response = HttpResponse()
# bearer:expected python_django_insecure_cookie
response.set_cookie("foo", "bar", max_age=None, secure=False, httponly=False)

def ok():
response = HttpResponse()

response.set_cookie("foo", "bar")
# still bad but not for this rule
response.set_cookie("foo", "bar", max_age=None, secure=True, httponly=False)
20 changes: 20 additions & 0 deletions tests/python/lang/insecure_cookie/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const {
createNewInvoker,
getEnvironment,
} = require("../../../helper.js")
const { ruleId, ruleFile, testBase } = getEnvironment(__dirname)

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

test("insecure_cookie", () => {
const testCase = "main.py"

const results = invoke(testCase)

expect(results).toEqual({
Missing: [],
Extra: []
})
})
})
7 changes: 7 additions & 0 deletions tests/python/lang/insecure_cookie/testdata/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from http.cookies import BaseCookie

cookie = BaseCookie()

cookie['session_id'] = 'abc123'
# bearer:expected python_lang_insecure_cookie
cookie['session_id']['secure'] = False

0 comments on commit eb18ecf

Please sign in to comment.