Skip to content

Update hmac_timing_attack.py

526a108
Select commit
Loading
Failed to load commit list.
Closed

Update hmac_timing_attack.py #4

Update hmac_timing_attack.py
526a108
Select commit
Loading
Failed to load commit list.
Precaution / Precaution Unsubscribed failed Mar 14, 2025 in 0s

Found 1 failure, 1 warning, and 0 notices.

The check found 1 failure, 1 warning, and 0 notices. Review the documentation link on each issue to determine how to resolve. Alternatively, false positives can be suppressed. See documentation for details.

Details

PY034: Inadequate Encryption Strength

Expand for further details

This rule identifies instances where the key provided to hmac.digest() or
hmac.new() is considered too small relative to the digest algorithm's
digest size. Using keys that are too short can compromise the integrity and
security of the HMAC (Hash-based Message Authentication Code), making it less
resistant to brute-force attacks.

HMAC is a mechanism for message authentication using cryptographic hash
functions. The security of an HMAC depends significantly on the secret key's
strength. A key that is shorter than the hash function's output size
(digest size) can reduce the HMAC's effectiveness, making it more vulnerable
to attacks. It is essential to use keys of adequate length to maintain the
expected level of security, especially against brute-force attacks.

Ensure that the key length used with hmac.digest() or hmac.new() is at
least equal to the digest size of the hash function being used. This
compliance requirement helps maintain the cryptographic strength of the
HMAC and protects the integrity of the message authentication process.

Example

import hashlib
import hmac
import secrets


key = secrets.token_bytes(None)
message = b"Hello, world!"
hmac.new(key, msg=message, digestmod=hashlib.sha3_384)

??? example "Example Output"
> precli tests/unit/rules/python/stdlib/hmac/examples/hmac_new_weak_key_hashlib_sha3_384.py ⚠️ Warning on line 8 in tests/unit/rules/python/stdlib/hmac/examples/hmac_new_weak_key_hashlib_sha3_384.py PY034: Inadequate Encryption Strength The given key is only '32' bytes which is insufficient for the 'hashlib.sha3_384' algorithm.

Remediation

Adjust the key size to be at least the size of the digest.

import hashlib
import hmac
import secrets


key = secrets.token_bytes(nbytes=48)
message = b"Hello, world!"
hmac.new(key, msg=message, digestmod=hashlib.sha3_384)

Default Configuration

enabled = true
level = "warning"

See also

!!! info
- hmac — Keyed-Hashing for Message Authentication
- secrets — Generate secure random numbers for managing secrets
- CWE-326: Inadequate Encryption Strength

New in version 0.4.3

PY005: Observable Timing Discrepancy

Expand for further details

Do not use Python's == operator to compare HMAC digests. The == operator is
not designed to be used for cryptographic comparisons, and it can be
vulnerable to timing attacks. Instead, use the hmac.compare_digest() function
to compare HMAC digests.

The == operator works by comparing the length and contents of two objects.
However, this can be a problem for HMAC digests, because the length of an
HMAC digest is not necessarily unique. For example, two different messages
with the same key will have the same HMAC digest.

A timing attack is a type of attack that exploits the time it takes to
execute a piece of code. In the case of HMAC digests, a timing attack could
be used to determine whether two messages have the same HMAC digest. This
could be used to break the security of an HMAC-protected system.

The hmac.compare_digest() function is designed to be used for cryptographic
comparisons. It works by comparing the binary representations of two HMAC
digests. This makes it more resistant to timing attacks.

Example

import hmac


received_digest = (
    b"\xe2\x93\x08\x19T8\xdc\x80\xef\x87\x90m\x1f\x9d\xf7\xf2"
    "\xf5\x10>\xdbf\xa2\xaf\xf7x\xcdX\xdf"
)

key = b"my-super-duper-secret-key-string"
password = b"pass"
digest = hmac.digest(key, password, digest="sha224")

print(digest == received_digest)

??? example "Example Output"
> precli tests/unit/rules/python/stdlib/hmac/examples/hmac_timing_attack.py ⛔️ Error on line 13 in tests/unit/rules/python/stdlib/hmac/examples/hmac_timing_attack.py PY005: Observable Timing Discrepancy Comparing digests with the '==' operator is vulnerable to timing attacks.

Remediation

The recommendation is to replace the == operator with the function
compare_digest.

import hmac


received_digest = (
    b"\xe2\x93\x08\x19T8\xdc\x80\xef\x87\x90m\x1f\x9d\xf7\xf2"
    "\xf5\x10>\xdbf\xa2\xaf\xf7x\xcdX\xdf"
)

key = b"my-secret-key"
password = b"pass"
digest = hmac.digest(key, password, digest="sha224")

print(hmac.compare_digest(digest, received_digest))

Default Configuration

enabled = true
level = "error"

See also

!!! info
- hmac — Keyed-Hashing for Message Authentication
- CWE-208: Observable Timing Discrepancy

New in version 0.1.4

Precaution v0.7.9

Annotations

Check warning on line 14 in python/stdlib/hmac_timing_attack.py

See this annotation in the file changed.

@precaution precaution / Precaution Unsubscribed

PY034: Inadequate Encryption Strength

The given key is only '13' bytes which is insufficient for the
'sha224' algorithm.

Check failure on line 16 in python/stdlib/hmac_timing_attack.py

See this annotation in the file changed.

@precaution precaution / Precaution Unsubscribed

PY005: Observable Timing Discrepancy

Comparing digests with the '==' operator is vulnerable to timing
attacks.