Back to skill

Security audit

OpenClaw YouTube Upload

Security checks for vulnerabilities and agentic risk

Overview

This YouTube upload skill is purpose-aligned, but it stores reusable OAuth access locally and reloads it with unsafe pickle deserialization, creating a material account-access and local-code-execution risk.

Review before installing. Only use this skill in a trusted, private directory; understand that approving OAuth once can allow later YouTube uploads without another browser approval while token.pickle remains present. Delete token.pickle and revoke the app in your Google account when finished. A safer version should replace pickle token storage with JSON or an OS keyring, use private file permissions, pin dependencies, and require explicit user approval before account-affecting uploads.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/upload.py:14
Finding

Unsafe Deserialization of an Attacker-Replaceable OAuth Token File

Content
View full analysis

Vulnerability Details

File Location: scripts/upload.py, lines 14-18
Vulnerability Type: Python pickle deserialization of an untrusted local file
Risk Level: High

python
token_file = 'token.pickle'
    
if os.path.exists(token_file):
    with open(token_file, 'rb') as token:
        creds = pickle.load(token)

Technical Analysis

The script loads token.pickle using pickle.load(). Python pickle data is executable serialization: specially constructed pickle opcodes can invoke arbitrary Python callables during deserialization. Consequently, a pickle file must never be treated as untrusted data.

The token path is a fixed relative path, so it resolves against the process's current working directory rather than a validated, private application-state directory. An attacker who can create or replace token.pickle in that directory can cause arbitrary code to execute before the script validates the credential or uploads a video.

Attack Path

  1. An attacker obtains write access to the directory from which the upload script will be invoked, or otherwise causes a crafted token.pickle to appear there.
  2. The attacker constructs a malicious pickle whose deserialization invokes an operating-system command or arbitrary Python callable.
  3. A user or Agent invokes scripts/upload.py.
  4. The script finds the attacker-controlled token.pickle.
  5. pickle.load(token) executes the embedded payload immediately.
  6. The payload operates with the same identity and permissions as the Agent or user running the skill.

Impact Assessment

Successful exploitation provides arbitrary code execution with the privileges of the upload process. Depending on the host's permissions, the attacker could read or modify accessible files, steal OAuth credentials and other local secrets, invoke available tools, alter subsequent skill behavior, or make network requests. The vulnerability does not independently grant ...[truncated 122 chars]

Remediation
View remediation

Remediation Suggestions

  • Eliminate pickle-based credential storage. Serialize credentials as non-executable JSON and reconstruct them using the supported Google authentication API, such as google.oauth2.credentials.Credentials.from_authorized_user_file().
  • Store state in a dedicated per-user application directory rather than the current working directory.
  • Create the state directory with owner-only permissions, such as mode 0700 on supported platforms.
  • Open the token file defensively, reject symbolic links, and require it to be a regular file owned by the expected user.
  • Validate the parsed credential structure before use.
  • Use atomic file replacement when updating credentials so interrupted writes cannot leave corrupt state.
  • If legacy pickle migration is necessary, perform it only through a separate, explicitly trusted migration process; do not automatically load arbitrary existing pickle files.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/upload.py:29
Finding

Reusable OAuth Credentials Stored Without Explicit Access Controls

Content
View full analysis

Vulnerability Details

File Location: scripts/upload.py, lines 29-30
Vulnerability Type: Insecure storage of sensitive OAuth credentials
Risk Level: Medium

python
with open(token_file, 'wb') as token:
    pickle.dump(creds, token)

Technical Analysis

The script writes reusable Google OAuth credentials to the predictable relative path token.pickle without explicitly enforcing owner-only file permissions. The resulting access mode depends on the host environment's umask and directory permissions. The stored credential may include a refresh token, allowing authorization to persist beyond the initial interactive OAuth flow.

Because subsequent uploads run silently using this token, disclosure of the file can permit another local user or process to reuse the granted YouTube upload authorization. Use of pickle also makes the file unsuitable as a safe or interoperable credential-storage format.

Attack Path

  1. The user completes the Google OAuth authorization flow and grants the youtube.upload scope.
  2. The script serializes the resulting credentials to token.pickle.
  3. The host's umask or containing-directory permissions allow another local account or process to read or copy the file.
  4. The attacker extracts or loads the OAuth access and refresh credentials.
  5. The attacker uses the stolen credentials through Google APIs or a compatible client.
  6. Requests are performed under the victim's granted YouTube upload authorization until the token is revoked or otherwise becomes unusable.

Impact Assessment

Exposure may allow unauthorized uploads to the YouTube account associated with the token. The observed OAuth scope is limited to https://www.googleapis.com/auth/youtube.upload, which reduces access compared with broad account scopes, but still permits content to be uploaded in the victim's name. This can result in reputational harm, policy violations, quota consumption, or publication of ...[truncated 99 chars]

Remediation
View remediation

Remediation Suggestions

  • Prefer an operating-system credential manager or keyring for refresh-token storage.
  • If file storage is required, use a dedicated per-user state directory with mode 0700 and create the credential file with mode 0600.
  • Avoid relying solely on the process umask; explicitly set and verify restrictive permissions after creation.
  • Reject symbolic links and non-regular files to reduce overwrite and redirection risks.
  • Write credentials atomically through a securely created temporary file in the same protected directory, then replace the destination.
  • Replace pickle with non-executable JSON serialization supported by Google's credential classes.
  • Document how users can revoke authorization through their Google account and securely remove local credentials.
  • Avoid including token contents in logs, exceptions, or diagnostic output.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:17
Finding

Unpinned Third-Party Dependencies Installed from a Mutable Package Index

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 17-20
Vulnerability Type: Unpinned runtime dependencies and non-reproducible installation
Risk Level: Medium

bash
pip3 install google-api-python-client google-auth-oauthlib google-auth-httplib2

The same unpinned installation command also appears in README.md, lines 24-27.

Technical Analysis

The documented installation command retrieves the latest versions satisfying unconstrained dependency resolution from pip's configured package index. No lockfile, reviewed version constraints, package hashes, isolated environment, or explicit trusted index is supplied.

The listed package names are consistent with the expected Google libraries, and the audit found no evidence that the currently named packages are malicious. Nevertheless, the installation procedure is mutable and not reproducible. A future compromised package release, compromised transitive dependency, or untrusted pip index configuration could introduce code that executes during installation or import.

Attack Path

  1. A user or Agent follows the documented prerequisite instructions.
  2. pip3 contacts the package index configured in the local environment.
  3. Dependency resolution selects whichever package and transitive-dependency versions are available at that time.
  4. If the configured index or a selected release has been compromised, malicious package code is installed.
  5. The malicious component may execute during package installation or when scripts/upload.py imports the dependency.
  6. That code receives the privileges and local access of the user or Agent process.

Impact Assessment

Exploitation through a compromised dependency could result in arbitrary code execution in the installation or upload environment. Potential consequences include theft of the Google client secret or OAuth token, access to local video files, modification of skill behavior, and access to other ...[truncated 208 chars]

Remediation
View remediation

Remediation Suggestions

  • Define reviewed, exact dependency versions in a requirements or lock file.
  • Generate and verify cryptographic hashes for every direct and transitive package, for example by using a hash-locked requirements workflow.
  • Install dependencies with hash enforcement, such as python -m pip install --require-hashes -r requirements.txt.
  • Use an isolated virtual environment instead of modifying the host Python environment.
  • Specify and document the trusted package index or use an internally controlled package mirror.
  • Add automated dependency vulnerability and integrity scanning to the release process.
  • Review and update pinned versions through a controlled process rather than allowing installation-time resolution to select arbitrary future releases.
  • Keep README.md and SKILL.md synchronized so both direct users and Agents follow the hardened installation procedure.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (9)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 17)May include surrounding context.

md
---
name: youtube-upload
description: "Uploads a video to YouTube using the official YouTube Data API v3 and OAuth 2.0. Use this skill when the user asks to upload a video to YouTube. It supports titles, descriptions, privacy settings (public, private, unlisted), and large file chunking. Requires a Google Cloud 'client_secret.json' file."
metadata:
  openclaw:
    emoji: "📺"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 49)May include surrounding context.

md
---
name: youtube-upload
description: "Uploads a video to YouTube using the official YouTube Data API v3 and OAuth 2.0. Use this skill when the user asks to upload a video to YouTube. It supports titles, descriptions, privacy settings (public, private, unlisted), and large file chunking. Requires a Google Cloud 'client_secret.json' file."
metadata:
  openclaw:
    emoji: "📺"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 3)May include surrounding context.

md
---
name: youtube-upload
description: "Uploads a video to YouTube using the official YouTube Data API v3 and OAuth 2.0. Use this skill when the user asks to upload a video to YouTube. It supports titles, descriptions, privacy settings (public, private, unlisted), and large file chunking. Requires a Google Cloud 'client_secret.json' file."
metadata:
  openclaw:
    emoji: "📺"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 21)May include surrounding context.

md
---
name: youtube-upload
description: "Uploads a video to YouTube using the official YouTube Data API v3 and OAuth 2.0. Use this skill when the user asks to upload a video to YouTube. It supports titles, descriptions, privacy settings (public, private, unlisted), and large file chunking. Requires a Google Cloud 'client_secret.json' file."
metadata:
  openclaw:
    emoji: "📺"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 33)May include surrounding context.

md
---
name: youtube-upload
description: "Uploads a video to YouTube using the official YouTube Data API v3 and OAuth 2.0. Use this skill when the user asks to upload a video to YouTube. It supports titles, descriptions, privacy settings (public, private, unlisted), and large file chunking. Requires a Google Cloud 'client_secret.json' file."
metadata:
  openclaw:
    emoji: "📺"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/upload.py (reported line 74)May include surrounding context.

python
---
name: youtube-upload
description: "Uploads a video to YouTube using the official YouTube Data API v3 and OAuth 2.0. Use this skill when the user asks to upload a video to YouTube. It supports titles, descriptions, privacy settings (public, private, unlisted), and large file chunking. Requires a Google Cloud 'client_secret.json' file."
metadata:
  openclaw:
    emoji: "📺"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README explicitly states that after first-time OAuth approval, a local token is stored and subsequent uploads run silently and automatically, but it does not clearly warn users that this creates persistent delegated access to their YouTube account. In an agent-executed skill, that omission is security-relevant because users may approve once without understanding that future uploads can occur non-interactively as long as the token remains present.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill performs network-capable actions against the YouTube API but does not declare an explicit tool scope such as permissions or allowed-tools. That creates a governance and least-privilege gap: an agent may invoke networked behavior without a clear policy boundary or user-visible restriction, increasing the chance of unintended external data transfer.

Content

No source excerpt is available for this finding.

Insecure deserialization: pickle.load()

Medium
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

The script deserializes credentials from a local token.pickle file using pickle.load(), which can execute arbitrary code if that file is replaced or tampered with. In an agent/skill context, local files may be influenced by other processes or untrusted workspace contents, so this turns token restoration into a code-execution primitive.

Content

Scanner excerpt · scripts/upload.py (reported line 19)May include surrounding context.

python
if os.path.exists(token_file):
        with open(token_file, 'rb') as token:
            creds = pickle.load(token)
            
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:

Static analysis

No suspicious patterns detected.