-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(python): add argon2 password hashing rule
- Loading branch information
Showing
3 changed files
with
115 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
imports: | ||
- python_shared_lang_import1 | ||
- python_shared_lang_import3 | ||
- python_shared_lang_datatype | ||
patterns: | ||
- pattern: | | ||
$<ARGON_PASSWORD_HASHER>.hash($<PASSWORD>) | ||
filters: | ||
- variable: ARGON_PASSWORD_HASHER | ||
detection: python_lang_weak_password_hash_argon2_password_hasher | ||
scope: cursor | ||
- variable: PASSWORD | ||
detection: python_shared_lang_datatype | ||
scope: result | ||
auxiliary: | ||
- id: python_lang_weak_password_hash_argon2_password_hasher | ||
patterns: | ||
- pattern: $<ARGON_PASSWORD_HASHER>(type = $<INSECURE_ARGON2_TYPE>) | ||
filters: | ||
- variable: ARGON_PASSWORD_HASHER | ||
detection: python_shared_lang_import1 | ||
scope: cursor | ||
filters: | ||
- variable: MODULE1 | ||
values: [argon2] | ||
- variable: NAME | ||
values: [PasswordHasher] | ||
- variable: INSECURE_ARGON2_TYPE | ||
detection: python_shared_lang_import3 | ||
scope: cursor | ||
filters: | ||
- variable: MODULE1 | ||
values: [argon2] | ||
- variable: MODULE2 | ||
values: [low_level] | ||
- variable: MODULE3 | ||
values: [Type] | ||
- variable: NAME | ||
values: | ||
- D | ||
- I | ||
languages: | ||
- python | ||
only_data_types: | ||
- Passwords | ||
severity: high | ||
metadata: | ||
description: Usage of weak hashing library on a password (Argon2) | ||
remediation_message: |- | ||
## Description | ||
Choosing a weak hashing algorithm for passwords compromises security. Argon2 has three variants: Argon2i, Argon2d, and Argon2id. Argon2id is the strongest and most recommended for password hashing because of its balanced resistance against both side-channel and GPU attack vectors. | ||
## Remediations | ||
- **Do not** override the Argon2 type when implementing the argon2-cffi hashing library. | ||
```python | ||
from argon2 import PasswordHasher | ||
from argon2.low_level import Type | ||
ph = PasswordHasher(Type.I) // unsafe | ||
hash = ph.hash(current_user.password) | ||
``` | ||
- **Do** rely on the default Argon2 type (Argon2id) as it is the most secure. This ensures the highest level of security for password storage. | ||
```python | ||
from argon2 import PasswordHasher | ||
ph = PasswordHasher() // defaults to Argon2id | ||
hash = ph.hash(current_user.password) | ||
``` | ||
## References | ||
- [argon2-cffi documentation](https://argon2-cffi.readthedocs.io/en/stable/argon2.html) | ||
- [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) | ||
cwe_id: | ||
- 326 | ||
id: python_lang_weak_password_hash_argon2 | ||
documentation_url: https://docs.bearer.com/reference/rules/python_lang_weak_password_hash_argon2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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("weak_password_hash_argon2", () => { | ||
const testCase = "main.py" | ||
|
||
const results = invoke(testCase) | ||
|
||
expect(results).toEqual({ | ||
Missing: [], | ||
Extra: [] | ||
}) | ||
}) | ||
}) |
18 changes: 18 additions & 0 deletions
18
tests/python/lang/weak_password_hash_argon2/testdata/main.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from argon2 import PasswordHasher | ||
from argon2.low_level import Type | ||
|
||
ph = PasswordHasher(type=Type.I) | ||
# bearer:expected python_lang_weak_password_hash_argon2 | ||
hash = ph.hash(current_user.password) | ||
|
||
# ok | ||
# argon2id used | ||
ph = PasswordHasher(type=Type.ID) | ||
hash = ph.hash(current_user.password) | ||
|
||
ph = PasswordHasher() # default is argon2id | ||
hash = ph.hash(current_user.password) | ||
|
||
ph = PasswordHasher(type=Type.I) | ||
# not a password | ||
hash = ph.hash(current_user.email) |