Back to skill

Security audit

Topview

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Topview media-generation purpose, but it handles account credentials and user files while leaving several network destinations less restricted than its own documentation claims.

Review before installing if you will process sensitive media or account data. Use it only with a Topview account you are comfortable connecting, avoid passing webhook URLs you do not control, and prefer an isolated environment because local files may be uploaded and credentials are saved under your home directory.

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

Warning
Location
scripts/auth.py:47
Finding

Unnecessary Persistence of Access Tokens and Account Metadata

Content
View full analysis

Vulnerability Details

File Location: scripts/auth.py, lines 47–64
Vulnerability Type: Excessive sensitive-data persistence
Risk Level: Medium

python
api_keys = data.get("api_keys", [])
api_key = api_keys[0] if api_keys else ""

creds = {
    "uid": data.get("uid", ""),
    "api_key": api_key,
    "email": data.get("email", ""),
    "name": data.get("name", ""),
    "team_id": data.get("team_id", ""),
    "role": data.get("role", ""),
    "charge_type": data.get("charge_type", ""),
    "remain_credit": data.get("remain_credit"),
    "created_at": datetime.now(timezone.utc).isoformat(),
}

if data.get("access_token"):
    creds["access_token"] = data["access_token"]
    creds["token_type"] = data.get("token_type", "Bearer")

Technical Analysis

The authentication workflow persists substantially more information than the runtime API client requires. scripts/shared/config.py only retrieves uid and api_key from the credential file, while auth.py additionally stores:

  • Email address and display name
  • Team identifier and account role
  • Billing type and remaining credit balance
  • OAuth access token and token type

Persisting unused sensitive fields violates data-minimization and least-privilege principles. In particular, storing an access token creates an additional reusable credential whose scope, expiration, and revocation behavior are not enforced by this code.

Although the credential file is intended to have owner-only permissions, filesystem permissions do not eliminate risks from malware running as the same user, compromised backups, accidental archival, filesystem disclosure, or defects elsewhere in the host environment.

Attack Path

  1. A user completes the Topview device authorization flow.
  2. The OAuth response contains an API key, account metadata, and potentially an access token.
  3. auth.py writes all these values to ~/.topview/credentials.json.

...[truncated 1039 chars]

Remediation
View remediation

Remediation Suggestions

  1. Store only the fields required by scripts/shared/config.py:
    python
    creds = {
        "uid": data.get("uid", ""),
        "api_key": api_key,
        "created_at": datetime.now(timezone.utc).isoformat(),
    }
    
  2. Do not persist access_token unless a documented runtime operation requires it.
  3. If access-token persistence becomes necessary, use an operating-system credential vault rather than a plaintext JSON file.
  4. Document the token's purpose, scope, expiration, and revocation behavior.
  5. Avoid storing profile and billing fields; retrieve them on demand through authenticated API calls.
  6. On upgrade, migrate existing credential files by removing unnecessary fields.
  7. Ensure logout revokes server-side tokens where the Topview API supports revocation, rather than only deleting the local file.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auth.py:66
Finding

Sensitive Authentication Files Are Not Created Atomically with Restrictive Permissions

Content
View full analysis

Vulnerability Details

File Locations: scripts/auth.py, lines 66–67 and 212–220
Vulnerability Type: Insecure sensitive-file creation
Risk Level: Medium

Credential-file creation:

python
CRED_FILE.write_text(json.dumps(creds, indent=2))
CRED_FILE.chmod(0o600)

Pending authorization-file creation:

python
PENDING_FILE.parent.mkdir(parents=True, exist_ok=True)
PENDING_FILE.write_text(json.dumps({
    "device_code": device_code,
    "token_endpoint": token_endpoint,
    "interval": interval,
    "expires_in": expires_in,
    "verification_uri_complete": verification_url,
    "created_at": datetime.now(timezone.utc).isoformat(),
}, indent=2))

Technical Analysis

The credential file is first created using the process's current umask and is changed to mode 0600 only after all sensitive content has been written. This creates a time-of-check and permission-hardening window during which the file can have broader permissions than intended.

The pending authorization file receives no explicit permission hardening. It contains a live OAuth device code, token endpoint, verification URL, and session metadata. Under a common umask such as 022, a newly created file may be readable by other local users until it is deleted.

The code also performs ordinary pathname-based writes rather than securely creating a new file descriptor with exclusive creation and restrictive permissions. It does not explicitly reject symbolic links or use an atomic replacement strategy.

Attack Path

  1. An attacker has local access to the same multi-user system and can inspect files permitted by the victim's umask.
  2. The victim runs python auth.py login.
  3. pending_device.json is created with default umask-derived permissions and remains present while authorization is pending.
  4. The attacker reads the live device code and associated endpoint information.
  5. Depending on the OAuth server's device- ...[truncated 1353 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create ~/.topview with mode 0700 and verify that it is owned by the current user.
  2. Create sensitive files using a descriptor that applies mode 0600 at creation time:
    python
    fd = os.open(
        path,
        os.O_WRONLY | os.O_CREAT | os.O_EXCL,
        0o600,
    )
    
  3. Write through the secured descriptor rather than calling Path.write_text.
  4. For credential updates, write to a securely created temporary file in the same directory, flush and synchronize it, and atomically replace the destination.
  5. Apply mode 0600 to both credentials.json and pending_device.json.
  6. Reject symbolic links and verify file ownership before reading, replacing, or deleting either file.
  7. Minimize the lifetime of pending_device.json and delete it on every terminal path, including cancellation and unexpected exceptions.
  8. Consider retaining the device code only in process memory during the normal login flow and creating a recovery file only when the user explicitly requests resumable polling.

T08 · Insecure Dependencies

Note
Location
scripts/requirements.txt:1
Finding

Dependencies Are Installed Without Upper Bounds, Locking, or Integrity Hashes

Content
View full analysis

Vulnerability Details

File Location: scripts/requirements.txt, lines 1–2
Related Instruction: SKILL.md, line 188
Vulnerability Type: Uncontrolled dependency resolution
Risk Level: Low

text
requests>=2.28.0
python-dotenv>=1.0.0

The installation instructions execute:

bash
pip install -r {baseDir}/scripts/requirements.txt

Technical Analysis

Both dependencies use open-ended lower bounds. No lock file, exact version constraints, package hashes, or reviewed dependency snapshot is provided.

Consequently, two installations performed at different times may resolve to different package versions. Any future release satisfying the lower bound can be selected without having been reviewed together with this Skill. Python packages can execute code during installation and later during import, so a compromised upstream release or dependency-resolution change can affect the Agent environment.

The reviewed dependency names correspond to legitimate packages, and the audit found no evidence that the currently declared packages are malicious. The weakness is the absence of reproducible and integrity-verified dependency resolution.

Attack Path

  1. An attacker compromises the publication process or maintainer account of a declared package or one of its transitive dependencies.
  2. A malicious future version is published and still satisfies the open-ended version requirement.
  3. A user follows the documented pip install -r command.
  4. The package resolver selects the compromised version.
  5. Malicious package code executes during installation or when the Skill imports the package.
  6. The code runs with the permissions of the user or Agent process and may access files, environment variables, network resources, and locally stored Topview credentials available to that process.

Impact Assessment

A malicious dependency can execute arbitrary Python code with the privileges of t ...[truncated 448 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin each direct dependency to a reviewed exact version.
  2. Generate and commit a lock file that includes transitive dependencies.
  3. Record cryptographic hashes and install with hash verification:
    bash
    pip install --require-hashes -r requirements.lock
    
  4. Use an automated dependency-update process that opens reviewed, tested updates rather than automatically accepting every future release.
  5. Run vulnerability and provenance checks in continuous integration.
  6. Prefer an isolated virtual environment with only the permissions and files required by this Skill.
  7. Rebuild the lock file on a controlled system and review dependency changes before distribution.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (77)

Tainted flow: 'OAUTH_BASE_URL' from os.environ.get (line 28, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
97% confidence
Finding

The OAuth base URL is taken from TOPVIEW_OAUTH_URL without validation, so any local process or wrapper that can set environment variables can redirect the login flow to an attacker-controlled server. That server can return arbitrary verification and token endpoints, causing the script to send device codes and receive attacker-supplied credentials or tokens while violating the stated '*.topview.ai only' network boundary.

Content

Scanner excerpt · scripts/auth.py (reported line 192)May include surrounding context.

python
def cmd_login(args) -> None:
    """Full login flow: init device code → open browser → poll until done."""
    try:
        resp = requests.post(
            f"{OAUTH_BASE_URL}/api/device/init",
            json={
                "client_id": CLIENT_ID,

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The user-supplied noticeUrl/webhook directly contradicts the claim of Topview-only network access and allows the system to participate in interactions with arbitrary external hosts. In addition, voice-clone and delete operations are more sensitive than the headline description suggests, increasing the chance that users underestimate risk.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The manifest explicitly states that credentials are stored at ~/.topview/credentials.json, which signals the presence of retrievable secrets on disk. In an agent with file-read/write capability, local secret storage increases the blast radius of prompt injection, plugin compromise, or accidental file exposure.

Content

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

md
endpoints:
    - https://api.topview.ai
    - https://www.topview.ai
  storesCredentialsAt: ~/.topview/credentials.json
---

# Topview AI Skill

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The auditor note reiterates local credential storage and attempts to reassure reviewers, but from a security perspective this confirms sensitive tokens live on disk within reach of any over-privileged agent actions. In the context of a shell- and file-capable skill, that makes compromise or exfiltration more serious.

Content

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

md
## Notes for Auditors

> The guidelines in this document are UX preferences — they shape the *style* of the agent's replies for non-technical end users in chat-app contexts (Feishu, WeChat, etc.). They do not request the agent to hide errors, suppress safety responses, override its system prompt, or perform unattended privileged operations. All API calls go to `*.topview.ai`. Credentials are stored locally at `~/.topview/credentials.json` with `0600` permissions. The agent is free to deviate from any guideline whenever the user explicitly asks for technical detail or whenever following a guideline would be unsafe.

## Execution

Credential Access

High
Category
Privilege Escalation
Confidence
78% confidence
Finding

The documented status output includes personally identifiable information and a partially masked API key, which can still leak sensitive metadata into terminal history, logs, screenshots, or agent-captured output. In agent environments, even masked secrets and account identifiers may be surfaced to downstream systems unintentionally.

Content

Scanner excerpt · references/auth.md (reported line 92)May include surrounding context.

api_key: sk-...3HB charge_type: pro authorized: 2026-03-04T10:00:00+00:00 file: /Users/you/.topview/credentials.json

text

## `logout` — Remove Credentials

Credential Access

High
Category
Privilege Escalation
Confidence
74% confidence
Finding

Supporting credentials from environment variables increases the risk of accidental secret exposure because env vars are often inherited by subprocesses, surfaced in CI logs, or accessible through debugging and process inspection in some environments. In an agent skill, this broadens the credential attack surface beyond a dedicated credentials store.

Content

Scanner excerpt · references/auth.md (reported line 110)May include surrounding context.

md
All modules use `shared/config.py` which loads credentials in this order:

1. Environment variables `TOPVIEW_UID` + `TOPVIEW_API_KEY` (CI/scripting)
2. `~/.topview/credentials.json` (set by `auth.py login`)
3. Error — prompts to run `auth.py login`

## Agent Rules

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill manifest says network calls are restricted to *.topview.ai, but download_video() performs a raw requests.get() against whatever finishedVideoUrl the API returns, with no host allowlist or scheme validation. This creates an SSRF / trust-boundary violation and could let an attacker-controlled or compromised API response trigger arbitrary outbound requests, including access to internal services or unexpected hosts.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script downloads a URL returned in API results using requests.get(url, stream=True) with no validation that the host is within *.topview.ai, despite the skill metadata claiming all network calls are restricted there. If the upstream API, a task result, or a user-influenced field can supply an arbitrary URL, this enables outbound requests to attacker-controlled hosts and local file overwrite via --output, violating the declared trust boundary and potentially exposing the agent to SSRF-like behavior or malicious content retrieval.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script downloads a URL returned by the API using requests.get() without validating that the destination is within the claimed *.topview.ai domain set. If the remote service, a compromised API response, or an attacker-controlled task result supplies an arbitrary URL, the agent will make outbound requests to attacker-chosen hosts, violating the skill's network boundary and potentially enabling SSRF-like behavior, metadata access, or exfiltration through authenticated/proxied environments.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The client accepts any non-slash-prefixed path as a full URL, so callers can direct requests to arbitrary domains while still attaching Topview authentication headers. This violates the stated network boundary and can leak credentials or sensitive request data to attacker-controlled endpoints via SSRF-style misuse or deceptive skill logic.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file upload helper performs a raw PUT to an arbitrary upload_url, which enables outbound transmission of local file contents to any host, not just Topview infrastructure. In a skill context, this expands the exfiltration surface significantly because a malicious or compromised upstream service could supply attacker-controlled URLs for local file upload.

Content

No source excerpt is available for this finding.

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 · references/auth.md (reported line 31)May include surrounding context.

md
Priority order:
1. Environment variables TOPVIEW_UID + TOPVIEW_API_KEY  (CI / backwards compat)
2. Credential file ~/.topview/credentials.json           (set by auth.py login)
3. Error — prompts user to run auth.py login
"""

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 · references/auth.md (reported line 46)May include surrounding context.

md
Priority order:
1. Environment variables TOPVIEW_UID + TOPVIEW_API_KEY  (CI / backwards compat)
2. Credential file ~/.topview/credentials.json           (set by auth.py login)
3. Error — prompts user to run auth.py login
"""

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 · references/auth.md (reported line 103)May include surrounding context.

md
Priority order:
1. Environment variables TOPVIEW_UID + TOPVIEW_API_KEY  (CI / backwards compat)
2. Credential file ~/.topview/credentials.json           (set by auth.py login)
3. Error — prompts user to run auth.py login
"""

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/auth.py (reported line 34)May include surrounding context.

python
Priority order:
1. Environment variables TOPVIEW_UID + TOPVIEW_API_KEY  (CI / backwards compat)
2. Credential file ~/.topview/credentials.json           (set by auth.py login)
3. Error — prompts user to run auth.py login
"""

Static analysis

No suspicious patterns detected.