T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/hash_tool.py:54
- Finding
- HMAC Secret Exposed Through Command-Line Arguments## Vulnerability Details **File Location**: `scripts/hash_tool.py`, lines 54-55 and 72 **Vulnerability Type**: Command-line secret exposure **Risk Level**: Medium ### Vulnerable Code ```python p = sub.add_parser('hmac', help='HMAC signature') p.add_argument('message'); p.add_argument('-k', '--key', required=True) ``` ```python elif args.command == 'hmac': print(f"HMAC-{args.algorithm}: {hmac_sign(args.message, args.key, args.algorithm)}") ``` ### Technical Analysis The HMAC interface requires users to provide the secret key through the `-k` or `--key` command-line argument. Command-line arguments are not an appropriate transport mechanism for sensitive credentials because they can be: - Recorded in interactive shell history. - Captured by command auditing or process-monitoring systems. - Observed through process inspection facilities while the command is running, subject to operating-system permissions. - Retained in terminal logs, automation logs, or diagnostic output that records invoked commands. The code does not itself transmit or print the key, but its required invocation method unnecessarily places the secret in externally observable process metadata. Exploitation requires local access to command history, process metadata, or command logs; no remote exploitation path was identified. ### Attack Path 1. A user invokes the HMAC operation with a sensitive key, for example: ```shell python3 scripts/hash_tool.py hmac "message" --key "sensitive-secret" ``` 2. The complete invocation is retained in shell history, automation logs, audit telemetry, or temporarily exposed through process inspection. 3. A local user, administrator, monitoring service, or attacker who has gained access to one of those data sources obtains the HMAC key. 4. The attacker uses the disclosed key to generate valid HMAC values for attacker-controlled messages. 5. If an external system relies on that key for message ...[truncated 657 chars]
- Remediation
- ## Remediation Suggestions Do not require secrets to be supplied as command-line arguments. 1. Prompt for the key without terminal echo by using `getpass.getpass()`: ```python import getpass key = getpass.getpass("HMAC key: ") print(f"HMAC-{args.algorithm}: {hmac_sign(args.message, key, args.algorithm)}") ``` 2. Make `--key` unnecessary and preferably remove it to prevent accidental insecure usage. 3. For automation, accept the key through standard input or a dedicated inherited file descriptor rather than process arguments. 4. If key-file support is added, require restrictive file permissions, avoid following untrusted symbolic links where applicable, and document secure file handling. 5. Avoid environment variables for long-lived secrets when stronger mechanisms are available, because environment data may also be exposed through process inspection, crash reports, or logs. 6. Clear references to the key as soon as practical, while recognizing that Python strings cannot be reliably erased from memory. 7. Update usage documentation so examples never place real HMAC secrets directly on the command line.
