T09 · Insecure Skill Coding Practices
- Location
SKILL.md:12- Finding
Private Trading Key Stored and Loaded as Plaintext
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 12–18 and 40–46
Vulnerability Type: Plaintext sensitive credential storage
Risk Level: HighThe skill instructs users to place a Tiger Brokers private key directly in a plaintext JSON file:
json { "tiger_id": "your_tiger_id", "account": "your_account", "private_key_pk8": "your_private_key" }It then reads that credential from the filesystem and assigns it directly to the live trading client:
python with open('~/.tiger-config.json', 'r') as f: config = json.load(f) client_config = TigerOpenClientConfig() client_config.tiger_id = config['tiger_id'] client_config.account = config['account'] client_config.private_key = config['private_key_pk8']Technical Analysis
The documented configuration design stores a private authentication key without encryption, access-control validation, or secret-manager integration. Any process or user capable of reading the configuration file can recover the Tiger Brokers account identifier and private key.
The instructions also do not require restrictive file permissions such as mode
0600. Consequently, an insecureumask, accidental backup, synchronization utility, diagnostic collection process, or local information-disclosure flaw could expose the credential.In addition, Python does not expand
~automatically inopen('~/.tiger-config.json', ...). Although this commonly causes a file-not-found error, a pre-existing attacker-controlled directory named~under the working directory could cause the program to load an unintended configuration. This should not be relied upon as the primary exploit path, but it further weakens configuration integrity.Attack Path
- A user follows the setup instructions and writes the Tiger Brokers private key to
~/.tiger-config.json. - The file is created with permissions that permit access by another local principal, or it is exp ...[truncated 853 chars]
- A user follows the setup instructions and writes the Tiger Brokers private key to
- Remediation
View remediation
Remediation Suggestions
- Store the private key in an operating-system keychain, hardware-backed secret store, or dedicated secrets manager rather than embedding it in JSON.
- If a local file is unavoidable, keep the private key in a separate file encrypted at rest and enforce owner-only permissions (
0600) and a private parent directory (0700). - Resolve the configuration path safely with
pathlib.Path.home()oros.path.expanduser()rather than passing a literal~toopen(). - Verify that the resolved configuration path is a regular file owned by the expected user and is not a symbolic link.
- Validate file permissions before loading credentials and refuse to continue if group or world access is enabled.
- Avoid printing, logging, or returning the private key in exceptions or diagnostic output.
- Support credential rotation and document immediate revocation procedures for suspected exposure.
- Prefer scoped credentials and broker-side controls that restrict account access, order value, eligible instruments, and withdrawal capabilities.
