T09 · Insecure Skill Coding Practices
- Location
scripts/pixiv.py:446- Finding
OAuth Bearer Token May Be Disclosed to an Unvalidated Download Host
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Pixiv skill is broadly aligned with Pixiv automation, but its account credential handling is inconsistent and includes a real risk of exposing OAuth tokens during image downloads.
Review before installing. Do not put Pixiv cookies or OAuth tokens in a shared repository or broad workspace, treat config.yaml as a secret file, and avoid download/like/follow/monitor commands unless you are comfortable with authenticated Pixiv account actions. The publisher should align the authentication model, remove or fix disabled login paths, avoid sending bearer tokens to image hosts, pin dependencies, and add explicit confirmation guidance for account-changing actions.
scripts/pixiv.py:446OAuth Bearer Token May Be Disclosed to an Unvalidated Download Host
scripts/get_rank.py:15Pixiv Session Cookie Is Stored and Read from a Plaintext Configuration File
requirements.txt:1Unpinned and Unnecessary Dependencies Increase Supply-Chain Exposure
The documented security model says the skill uses only Cookie authentication and does not perform automatic login, while the referenced behavior reportedly uses OAuth bearer tokens and token-refresh/login scaffolding for authenticated actions. This mismatch is dangerous because operators may trust a narrower credential model than what the code actually exercises, leading to accidental exposure of more powerful tokens, unexpected account actions, and weakened review of the real auth path.
The README instructs users to store a live Pixiv authentication cookie directly in a local config file, but does not warn that the cookie is a sensitive credential equivalent to an authenticated session token. This increases the risk of accidental disclosure through source control, logs, backups, screenshots, or file sharing, which could allow unauthorized account access and misuse of Pixiv actions such as viewing, downloading, liking, bookmarking, or following on behalf of the user.
The skill documentation exposes capabilities that imply file access, shell execution, and network operations, but it does not declare any tool scope restrictions such as allowed-tools or permissions. In an agent environment, that omission weakens containment and can let the skill be invoked with broader capabilities than users or orchestrators expect, increasing the chance of unintended file/system/network actions.
The skill instructs users to place a live Pixiv cookie in config.yaml but does not explicitly warn that this is a sensitive credential equivalent to account access. In agent or shared workspace contexts, such credentials can be exposed via logs, repository commits, backups, or broader file-read permissions, enabling account takeover or unauthorized use.
The documentation describes like/follow actions without clearly warning that they mutate the user's Pixiv account state. In an agent setting, insufficient disclosure can cause accidental or unauthorized social/account actions, creating privacy, trust, and account-integrity risks even if the API calls are otherwise legitimate.
This manifest-style configuration file uses Chinese-only natural-language comments and labels throughout, such as the title and inline field explanations. Because the file does not offer a language choice or document that the skill is intended only for a Chinese-speaking or region-specific audience, it appears to impose a specific language without user opt-in.
The client headers hard-code "Accept-Language": "zh-cn", which enforces a specific language/locale choice for requests. The file does not offer a user-selectable locale or document why Chinese is required, so this is a natural-language policy violation under the locale-choice rule.
The skill metadata and disabled login commands tell users to authenticate via a Cookie in config.yaml, but the actual API implementation uses OAuth bearer and refresh tokens from pixiv.auth. This discrepancy can cause operators to place long-lived secrets into config files unnecessarily, misunderstand what credentials are active, and mishandle authentication data in ways that increase secret exposure risk.
The application request headers again hard-code "Accept-Language": "zh-cn" for normal API calls. Because the skill does not present a locale option or clearly justify a China-specific restriction, it violates the language/locale policy criterion.
The command registrations advertise working login capabilities such as "交互式 OAuth 登录", "浏览器自动登录并自动提取回调", and "生成 OAuth 授权链接 / 提交授权回调". However, the corresponding handlers at L657-L676 immediately raise an error saying these login flows were removed and instruct the user to use cookies manually, which directly contradicts the documented command intent.
The user-facing skill documentation is presented in Chinese throughout, with no indication that the language is optional or that the skill is intentionally region- or locale-specific. This can violate language or locale policy when a skill forces a specific language without user opt-in.
The dependency specifier uses a lower bound only, so builds may resolve to different versions over time, including versions with newly introduced bugs or supply-chain compromises. In a skill that performs authenticated network actions using Pixiv cookies, dependency drift increases the chance of pulling a vulnerable HTTP client or parser into a privileged workflow.
requests>=2.31.0
PyYAML>=6.0
beautifulsoup4>=4.12.2
tqdm>=4.65.0
requests has multiple known advisories, and because the manifest does not pin an exact version, it is impossible to verify whether deployments avoid affected releases. In this skill, requests would likely carry authenticated Pixiv traffic and cookies, so a vulnerable version could expose credentials, mishandle redirects, or weaken transport assumptions.
PyYAML is unpinned, so installations may pull different releases depending on time and environment, making security posture non-reproducible. Because this skill explicitly relies on config.yaml for cookie-based authentication, an unsafe or vulnerable YAML parser version is especially relevant to handling sensitive local configuration.
requests>=2.31.0
PyYAML>=6.0
beautifulsoup4>=4.12.2
tqdm>=4.65.0
Pillow>=10.0.0
PyYAML has a history of unsafe deserialization and parsing flaws, and the unpinned manifest prevents verification that a safe version is installed. Since the skill depends on config.yaml for cookie-based authentication, any vulnerable YAML handling directly increases the risk to local secrets and execution safety.
beautifulsoup4 is specified with a minimum version only, which makes installs non-deterministic and can introduce vulnerable or incompatible releases later. While this library is lower risk than auth or crypto components, it still processes remote content and should be controlled in a network-scraping skill.
requests>=2.31.0
PyYAML>=6.0
beautifulsoup4>=4.12.2
tqdm>=4.65.0
Pillow>=10.0.0
fake-useragent>=1.4.0
tqdm is unpinned, so future installs may select versions with known CLI or packaging-related issues. Although its direct security criticality is lower, unpinned tooling still weakens reproducibility and can expand supply-chain exposure.
requests>=2.31.0
PyYAML>=6.0
beautifulsoup4>=4.12.2
tqdm>=4.65.0
Pillow>=10.0.0
fake-useragent>=1.4.0
aiohttp>=3.8.6
tqdm has published advisories, and without exact pinning there is no assurance that the installed version is unaffected. The practical danger here is lower than for parser or network libraries, but unverifiable versions still weaken supply-chain hygiene.
Pillow is unpinned even though image libraries have a long history of parsing vulnerabilities and resource-consumption issues. Since this skill downloads and processes artwork on demand, dependency drift in an image parser materially increases the attack surface from untrusted remote files.
PyYAML>=6.0
beautifulsoup4>=4.12.2
tqdm>=4.65.0
Pillow>=10.0.0
fake-useragent>=1.4.0
aiohttp>=3.8.6
asyncio>=3.4.3
Pillow has many historical vulnerabilities including parsing bugs and resource exhaustion issues, and the unpinned requirement means affected versions cannot be ruled out. Because this skill downloads and handles images from external sources, a vulnerable Pillow release materially increases risk from malicious or malformed image files.
fake-useragent is unpinned, which can lead to non-reproducible builds and supply-chain risk from future releases. The direct exploit impact is lower than core network or parser libraries, but it still introduces avoidable uncertainty in a scraping-oriented skill.
beautifulsoup4>=4.12.2
tqdm>=4.65.0
Pillow>=10.0.0
fake-useragent>=1.4.0
aiohttp>=3.8.6
asyncio>=3.4.3
pycryptodome>=3.19.0
aiohttp is unpinned, allowing future installations to resolve to different versions that may contain security flaws in HTTP handling, cookies, or request parsing. Because the skill performs authenticated network requests and likely handles session state, instability in an async HTTP client is security-relevant.
tqdm>=4.65.0
Pillow>=10.0.0
fake-useragent>=1.4.0
aiohttp>=3.8.6
asyncio>=3.4.3
pycryptodome>=3.19.0
qrcode>=7.4.2
aiohttp has multiple advisories and the manifest does not establish a known-safe version, leaving the deployed security state unverifiable. In a skill that performs authenticated HTTP operations and may manage cookies or redirects, this uncertainty is operationally dangerous.
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
Pillow>=10.0.0
fake-useragent>=1.4.0
aiohttp>=3.8.6
asyncio>=3.4.3
pycryptodome>=3.19.0
qrcode>=7.4.2
pycryptodome is unpinned, so deployments may pull different cryptographic library versions with varying security properties and bug exposure. In a skill that includes authenticated operations and potentially token/cookie handling, uncontrolled crypto dependency changes are high-risk from a supply-chain perspective.
fake-useragent>=1.4.0
aiohttp>=3.8.6
asyncio>=3.4.3
pycryptodome>=3.19.0
qrcode>=7.4.2