HMAC (Hash-based Message Authentication Code) is a method for verifying the authenticity and integrity of a message. It is widely used in API authentication and other security protocols. HMAC generates a unique code by combining the message with a secret key and a cryptographic hash function. The server recomputes the HMAC during verification; if the values match, the data is confirmed to be authentic and untampered.
Configurations
HMAC authentication mechanism has the following configurations:
Configuration | Description |
|---|---|
Access Key | The unique identifier for the user or application. |
Secret Key | The secret key, also known as the HMAC key, is a confidential cryptographic key used to generate and verify HMAC values. This key is shared between the sender and receiver. |
Algorithm | Select from one of the following:
|
Signature header | The signature is commonly included in the |
Timestamp Header (Optional) | Including a timestamp header in HMAC authentication is a common practice that enhances security and helps prevent replay attacks. By adding a timestamp to the signed data, the server can validate that the request is recent and only accept it within a limited time window. |
Canonical Request Format (Optional) | A canonical request format is a standardized way of representing an HTTP request before generating an HMAC (Hash-based Message Authentication Code) signature. It ensures that both the client and server process the request data in a consistent manner, allowing them to compute and verify the HMAC accurately. |
Example
The following are some samples that you can use to configure the HMAC mechanism in the Advanced mode:
Sample 1
import hashlib
import hmac
import requests
def hmac_prehook(scanctx: ScanContext, pluginctx: PluginContext, testcase: TestCase, **kwargs) -> list[Assertion]:
attributes = testcase.get_attributes()
access_key = "your_access_key"
secret_key = "your_secret_key"
# set user
normal_user = True
bola_user = False
request_url = attributes.get_one("mutated.http.request.url", default="")
signature_header = "signature_header"
payload = attributes.get_one("mutated.http.request.body", default="")
hash_algorithm = hashlib.sha256
interim_signature = hmac.new(secret_key.encode(), payload.encode(), hash_algorithm).hexdigest()
hmac_signature = f'HMAC-SHA256 {access_key}:{interim_signature}'
attributes.set("mutated.auth.attribute", "mutated.http.request.header." + signature_header)
if normal_user:
attributes.set("mutated.role.user", hmac_signature)
attributes.set("mutated.http.request.header." + signature_header, hmac_signature)
if bola_user:
attributes.set("mutated.role.bolauser", hmac_signature)
return []