T08 · Insecure Dependencies
- Location
scripts/ads.py:1- Finding
Unpinned Runtime Dependency Creates Supply-Chain Exposure
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill appears purpose-built for Amazon Ads management, but it handles long-lived ad account credentials in a local file and can make live business-impacting campaign changes.
Install only if you are comfortable giving this skill Amazon Ads credentials with campaign-management authority. Prefer a secure secret store or tightly permissioned environment variables over a skill-root .env file, use least-privilege or read-only credentials where possible, rotate credentials if exposed, and require explicit confirmation before any bid, pause, archive, or negative-keyword change.
scripts/ads.py:1Unpinned Runtime Dependency Creates Supply-Chain Exposure
SKILL.md:13Long-Lived Amazon Advertising Credentials Stored in a Plaintext Project File
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
def _refresh(self):
if self._token and time.time() < self._expiry:
return
r = requests.post(TOKEN_URL, data={
'grant_type': 'refresh_token',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
# Profiles (no scope header needed)
def list_profiles(self) -> list:
self._refresh()
r = requests.get(f'{BASE}/v2/profiles', headers={
'Authorization': f'Bearer {self._token}',
'Amazon-Advertising-API-ClientId': CLIENT_ID,
}, timeout=30)
The skill instructs operators to place Amazon Ads client credentials and a refresh token in a .env file alongside the script. In a shared agent/workspace environment, this creates a significant risk of credential leakage through file access, backups, accidental commits, or exposure to other tools running with the same permissions.
"""
Amazon Advertising API CLI — Sponsored Products (v3)
Env vars (set in .env alongside this script):
AMAZON_ADS_CLIENT_ID
AMAZON_ADS_CLIENT_SECRET
AMAZON_ADS_REFRESH_TOKEN
The code reads a .env file from the parent directory and imports any keys into process environment variables automatically. This broad local secret ingestion pattern increases exposure of sensitive tokens to the script and any imported libraries, and in an agent setting may normalize unsafe secret placement inside the working directory.
if k and k not in os.environ:
os.environ[k] = v
# Load skill .env (place credentials here after installing)
_load_env(Path(__file__).parent.parent / '.env')
CLIENT_ID = os.environ.get('AMAZON_ADS_CLIENT_ID', '')
The explicit instruction to 'place credentials here after installing' encourages storing long-lived Amazon Ads secrets adjacent to executable skill code. That co-location materially raises the risk of accidental disclosure or unauthorized reuse, especially in ecosystems where agents can inspect workspace files.
os.environ[k] = v
# Load skill .env (place credentials here after installing)
_load_env(Path(__file__).parent.parent / '.env')
CLIENT_ID = os.environ.get('AMAZON_ADS_CLIENT_ID', '')
CLIENT_SECRET = os.environ.get('AMAZON_ADS_CLIENT_SECRET', '')
The runtime error path tells the user to obtain credentials from the skill owner and add them to a local .env file, reinforcing an insecure secret-handling workflow. While not exfiltrating data itself, it promotes unsafe operational behavior that can lead to credential compromise in practice.
('AMAZON_ADS_REFRESH_TOKEN', REFRESH_TOKEN),
] if not v]
if missing:
env_path = Path(__file__).parent.parent / '.env'
print(
f"Missing credentials: {', '.join(missing)}\n"
"Please ask the skill owner to provide the Amazon Ads API credentials\n"
The skill can access environment variables and make network calls to a live advertising API, but it does not declare any explicit tool scope or allowed-tools restrictions. In a credentialed, action-capable skill, missing scope boundaries increases the chance of unintended data access or unauthorized state-changing operations if the platform grants broad defaults or if the skill is invoked in an unexpected context.
The manifest includes broad trigger phrases like '广告分析', 'campaign analysis', 'adjust bid', and 'pause campaign', which can overlap with ordinary user conversation and cause over-triggering. Because this skill can perform live ad-management actions, accidental activation could expose account performance data or tee up destructive changes such as bid edits, keyword pauses, or negative additions.
The instructions require the final report format in Chinese and use the directive "Always" without indicating that the user may choose another language. This is a natural-language locale policy concern because the skill forces a specific output language absent explicit user opt-in or a documented regional justification.
The script automatically loads highly sensitive advertising credentials from a local .env file without a meaningful safety warning about secret handling, local file exposure, or least-privilege use. In an agent-skill context, encouraging users to place long-lived API secrets beside executable code increases the chance of accidental disclosure, reuse by other tools, or unsafe operational practices.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
'FE': 'https://advertising-api-fe.amazon.com',
}
BASE = ENDPOINTS.get(REGION, ENDPOINTS['NA'])
TOKEN_URL = 'https://api.amazon.com/auth/o2/token'
# ── AdsClient ─────────────────────────────────────────────────────────────────