T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/post_tweet.py:14- Finding
Unvalidated User Identifier Allows Cross-Account Credential Selection and Path Traversal
- Content
View full analysis
Vulnerability Details
File Location:
scripts/get_timeline.py:10-16,scripts/get_user_tweets.py:10-16,scripts/like_tweet.py:10-16,scripts/post_tweet.py:14-21,scripts/reply_tweet.py:10-16,scripts/retweet.py:10-16, andscripts/search_tweets.py:11-17
Vulnerability Type: Improper access control and path traversal
Risk Level: HighVulnerable Code
The following representative implementation appears in
scripts/post_tweet.py:14-21:python def load_credentials(user_id): """Load Twitter credentials for user""" cred_path = os.path.join(SKILL_DIR, 'credentials', f'{user_id}.json') if not os.path.exists(cred_path): raise Exception(f"No credentials found for user {user_id}. Configure Twitter credentials first.") with open(cred_path, 'r') as f: creds = json.load(f)The same credential-path construction pattern is repeated across all seven scripts:
python cred_path = os.path.join(SKILL_DIR, 'credentials', f'{user_id}.json')Technical Analysis
The caller directly controls
user_id, which is interpolated into a filesystem path without format validation, canonicalization, or a containment check. There is also no authorization check that binds the requesteduser_idto the authenticated caller.This creates two related access-control weaknesses:
- A caller who knows another user's identifier can select that user's credential file directly.
- Path components such as
..can escape the intendedcredentialsdirectory. Because the implementation appends.json, the target must be a reachable JSON file with a compatibletwitterobject.
The credentials are subsequently used to call X APIs. Although the scripts do not print the credentials directly, an attacker can potentially use another account's credentials indirectly through the supported read and write operations.
Attack Path
- The attacker obtains the ability to invok ...[truncated 1513 chars]
- Remediation
View remediation
Remediation Suggestions
-
Validate
user_idagainst a strict allowlist before using it in a path. For example, permit only the exact identifier format required by the application:python import re if not re.fullmatch(r'[A-Za-z0-9_-]+', user_id): raise ValueError("Invalid user identifier") -
Resolve and verify the canonical credential path:
python credentials_dir = os.path.realpath(os.path.join(SKILL_DIR, "credentials")) cred_path = os.path.realpath( os.path.join(credentials_dir, f"{user_id}.json") ) if os.path.commonpath([credentials_dir, cred_path]) != credentials_dir: raise ValueError("Credential path escapes the credential directory") -
Do not treat a caller-supplied account identifier as proof of authorization. Obtain the user identity from a trusted authentication context and map it internally to the appropriate credential record.
-
Centralize credential loading in one hardened module rather than duplicating the vulnerable implementation across every script.
-
Use opaque internal credential-record identifiers where practical, and ensure that a caller can access only records explicitly assigned to that caller.
-
Add tests covering absolute paths,
..traversal, encoded separators, symbolic links, malformed identifiers, and attempts to select another user's credentials. -
After remediation, review invocation logs for suspicious user identifiers and rotate tokens if cross-account use may already have occurred.
-
