Back to skill

Security audit

YouTube Publisher

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent YouTube uploader, but it needs Review because it requests broad YouTube OAuth authority and stores a refreshable account token locally without enforcing restrictive file permissions.

Install only if you are comfortable granting this skill meaningful YouTube account access. Before use, review the Google OAuth consent scopes, run dependencies in a virtual environment, keep client_secret.json and token.json private with restrictive permissions, explicitly confirm channel/account and privacy setting before each upload, and revoke the Google OAuth grant if you stop using the skill or suspect token exposure.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/youtube_upload.py:36
Finding
OAuth Authorization Requests Excessive YouTube Account Privileges<![CDATA[ ## Vulnerability Details **File Location**: `scripts/youtube_upload.py`, lines 36-40 **Vulnerability Type**: Excessive OAuth scopes and violation of least privilege **Risk Level**: Medium ### Vulnerable Code ```python SCOPES = [ "https://www.googleapis.com/auth/youtube.upload", "https://www.googleapis.com/auth/youtube", "https://www.googleapis.com/auth/youtube.force-ssl", ] ``` ### Technical Analysis The application requests three overlapping OAuth scopes, including the broad `youtube` scope. This grants authority to manage YouTube account resources beyond the upload operation and read-only commands exposed by the script. The broad authorization is applied unconditionally by `get_authenticated_service()`, so even commands that only list channels, videos, or playlists receive the same account-management permissions as mutating operations. Combining this with a persistent refresh token increases the consequences of token disclosure. At minimum, the general `youtube` scope is redundant when narrower scopes are used. Operations with materially different privilege requirements should not automatically share one broadly authorized credential. ### Attack Path 1. A user completes the OAuth flow and approves all scopes requested by the script. 2. Google issues credentials containing a refresh token with the approved YouTube privileges. 3. The application stores those credentials in `token.json`. 4. An attacker who obtains the token through local file access, malware, accidental backup exposure, or another vulnerability refreshes the access token. 5. The attacker invokes YouTube Data API operations allowed by the broad scopes. 6. The attacker can modify account resources beyond the minimum privileges needed for a simple upload or listing command. ### Impact Assessment Successful exploitation requires access to the OAuth credentials rather than merely control over ordinary command-line metadata. The exposed authorization may permit broad mo ...[truncated 309 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the general `https://www.googleapis.com/auth/youtube` scope unless a documented operation strictly requires it. 2. Determine the minimum Google scope required for every implemented command. 3. Use read-only authorization for `channels`, `list`, and `playlists` where possible. 4. Use `youtube.upload` only for video-upload operations. 5. Isolate playlist-modification authorization from read-only and upload-only credentials if the required Google scope is substantially broader. 6. Store separately authorized tokens for privilege tiers rather than granting every command a single union of all scopes. 7. Clearly display the requested privileges before starting the consent flow. 8. After reducing scopes, revoke existing tokens and require reauthorization so previously issued broad grants cannot continue to be used. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/youtube_upload.py:106
Finding
Refreshable OAuth Token Is Written Without Enforced Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/youtube_upload.py`, lines 106-109 **Vulnerability Type**: Insecure storage of sensitive OAuth credentials **Risk Level**: High ### Vulnerable Code ```python # 保存 token with open(TOKEN_FILE, "w") as f: f.write(credentials.to_json()) print(f"💾 Token 已保存: {TOKEN_FILE}") ``` ### Technical Analysis The application serializes OAuth credentials, potentially including a long-lived refresh token, directly to `token.json`. It uses the default behavior of `open()` and does not enforce owner-only permissions. For a newly created file, effective permissions depend on the process umask. Under a permissive umask, the token may be readable by other local users or processes. If the file already exists with unsafe permissions, opening it for writing does not correct those permissions. A refresh token is security-sensitive because it can be exchanged for new access tokens after the current access token expires. The risk is amplified by the broad OAuth scopes requested elsewhere in the same script. ### Attack Path 1. The victim runs the authorization command and grants access to the YouTube account. 2. The script writes the serialized credential to `~/.openclaw/workspace/skills/youtube-publisher/token.json`. 3. The file is created under the process's default umask, or a pre-existing token file retains permissive permissions. 4. Another local user, compromised process, backup agent, or service with filesystem access reads the file. 5. The attacker extracts the refresh token and associated OAuth client information. 6. The attacker exchanges the refresh token at Google's token endpoint for an access token. 7. The attacker calls YouTube APIs using the privileges approved during authorization. ### Impact Assessment An attacker who can read the credential file may impersonate the authorized user to the YouTube API for as long as the refresh grant remains valid. Because the applic ...[truncated 431 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the token file atomically with owner-only mode `0600`. 2. Explicitly verify and repair permissions when loading an existing token. 3. Ensure the parent credential directory is accessible only by its owner, preferably mode `0700`. 4. Prefer an operating-system credential store or keychain over a plaintext JSON file. 5. Avoid printing sensitive credential contents or including the token file in logs, archives, source-control commits, or broadly readable backups. 6. Handle write failures without leaving partially written credentials. An atomic owner-only write can be implemented with a temporary file in the same protected directory, followed by `os.replace()`. At minimum, enforce permissions after writing: ```python with open(TOKEN_FILE, "w", encoding="utf-8") as f: f.write(credentials.to_json()) os.chmod(TOKEN_FILE, 0o600) ``` For stronger creation-time protection, use `os.open()` with explicit permissions: ```python fd = os.open( TOKEN_FILE, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600, ) with os.fdopen(fd, "w", encoding="utf-8") as f: f.write(credentials.to_json()) os.chmod(TOKEN_FILE, 0o600) ``` Existing tokens created by affected versions should have their permissions corrected. If unauthorized access is suspected, revoke the OAuth grant and generate a new token after applying the fix. ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:66
Finding
Third-Party Python Dependencies Are Installed Without Version or Integrity Pinning<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 66; `scripts/youtube_upload.py`, lines 18 and 76 **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Low ### Vulnerable Code `SKILL.md` instructs users to install mutable package versions: ```bash pip3 install google-api-python-client google-auth-oauthlib google-auth-httplib2 ``` The script documentation and dependency error path provide a similar unpinned instruction: ```python 前提: 1. pip3 install google-api-python-client google-auth-oauthlib ``` ```python except ImportError: print("❌ 缺少依赖库,请运行:") print(" pip3 install google-api-python-client google-auth-oauthlib") sys.exit(1) ``` ### Technical Analysis The project does not provide a locked dependency manifest, exact versions, or package hashes. Following the installation instructions causes `pip` to resolve whichever compatible releases and transitive dependencies are available at installation time. The named packages correspond to expected Google client libraries; the audit found no evidence of deliberate typosquatting or a currently malicious package. The weakness is the absence of reproducibility and integrity controls. A future compromised release, compromised package index, unsafe index configuration, or malicious transitive dependency could therefore be installed without a project-level verification boundary. Installing into the global Python environment, as suggested by `pip3 install`, can also expose unrelated applications to dependency conflicts and increases the privileges available to package installation behavior. ### Attack Path 1. A user follows the documented `pip3 install` instruction. 2. `pip` resolves the latest available direct and transitive dependency versions from its configured index. 3. An upstream package, dependency release, index, or local package-source configuration is compromised. 4. Because the project supplies neither pinned versions ...[truncated 830 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a reviewed dependency manifest with exact versions for direct and transitive dependencies. 2. Generate and verify cryptographic hashes, for example by using a hash-locked requirements file and `pip install --require-hashes`. 3. Use a lock-generation workflow that preserves reproducibility while permitting controlled security updates. 4. Install dependencies inside a dedicated virtual environment rather than the system or user-wide Python environment. 5. Explicitly use a trusted package index and review environments for unexpected custom `index-url` or `extra-index-url` settings. 6. Add automated dependency vulnerability and provenance scanning. 7. Document a controlled update process that validates new versions before changing the lock file. The installation documentation should reference the locked file, for example: ```bash python3 -m venv .venv . .venv/bin/activate python3 -m pip install --require-hashes -r requirements.txt ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### 5. Token 过期
脚本会自动刷新 Token。如果持续失败,删除 `token.json` 重新授权:
```bash
rm ~/.openclaw/workspace/skills/youtube-publisher/token.json
python3 {baseDir}/scripts/youtube_upload.py auth
```
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Credential Access

High
Category
Privilege Escalation
Content
前提:
  1. pip3 install google-api-python-client google-auth-oauthlib
  2. 从 Google Cloud Console 下载 OAuth 凭证文件 (client_secret.json)
  3. 放置到 ~/.openclaw/workspace/skills/youtube-publisher/client_secret.json
"""
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
前提:
  1. pip3 install google-api-python-client google-auth-oauthlib
  2. 从 Google Cloud Console 下载 OAuth 凭证文件 (client_secret.json)
  3. 放置到 ~/.openclaw/workspace/skills/youtube-publisher/client_secret.json
"""
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
前提:
  1. pip3 install google-api-python-client google-auth-oauthlib
  2. 从 Google Cloud Console 下载 OAuth 凭证文件 (client_secret.json)
  3. 放置到 ~/.openclaw/workspace/skills/youtube-publisher/client_secret.json
"""
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
前提:
  1. pip3 install google-api-python-client google-auth-oauthlib
  2. 从 Google Cloud Console 下载 OAuth 凭证文件 (client_secret.json)
  3. 放置到 ~/.openclaw/workspace/skills/youtube-publisher/client_secret.json
"""
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
前提:
  1. pip3 install google-api-python-client google-auth-oauthlib
  2. 从 Google Cloud Console 下载 OAuth 凭证文件 (client_secret.json)
  3. 放置到 ~/.openclaw/workspace/skills/youtube-publisher/client_secret.json
"""
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
前提:
  1. pip3 install google-api-python-client google-auth-oauthlib
  2. 从 Google Cloud Console 下载 OAuth 凭证文件 (client_secret.json)
  3. 放置到 ~/.openclaw/workspace/skills/youtube-publisher/client_secret.json
"""
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill documents capabilities that require network access and local file writes, but it does not declare any explicit tool scope or permission boundaries. In an agent environment, this increases the chance that the skill can be invoked with broader-than-expected authority, reducing reviewability and user awareness of what the skill may access or modify.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill describes upload functionality but does not prominently warn that video files and metadata are sent to YouTube using OAuth-authenticated API calls and may be published publicly if the privacy flag is set accordingly. This weakens informed consent and increases the risk of users unintentionally disclosing sensitive media or metadata.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The invocation example uses broad natural-language phrasing like '帮我把 ... 上传到 YouTube' without requiring confirmation of privacy state, destination account, or publication intent. In agentic use, this can trigger high-impact actions from casual prompts and lead to accidental uploads or public disclosure of media.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The upload function hard-codes the default language parameter to "zh-Hans", which causes uploads to be tagged with a specific language unless the user explicitly overrides it. This is a natural-language locale policy concern because the script imposes a language default rather than making language selection neutral or opt-in.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The command-line interface sets `--language` to `zh-Hans` by default, so users who do not notice or supply the flag will have their content labeled as Chinese. This enforces a specific locale without opt-in and matches the policy-violation category for language or locale constraints.

Static analysis

No suspicious patterns detected.