Back to skill

Security audit

podcast-transcribe

Security checks for vulnerabilities and agentic risk

Overview

This podcast transcription skill mostly matches its purpose, but it needs review because it promotes an under-disclosed referral link and fetches or forwards arbitrary podcast URLs without strong safety limits.

Review before installing. Use only trusted public podcast feeds, avoid private or signed media URLs, expect media URLs and filenames to be sent to AuralWise for transcription, and store the API key outside repos or shared folders. Check the output directory and disk space before batch runs, and prefer canonical AuralWise links over the referral link shown by the skill.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:34
Finding

Undisclosed Referral Link Injected into Agent Responses

Content
View full analysis
"语音转写需要 AuralWise API Key。请到 https://auralwise.cn/refid=asgbifle 注册并获取 API Key(在 Settings → API Key 管理页面生成,格式为 `asr_` 开头)。" ``` The referral URL is also repeated in `references/auralwise_api.md:7` and in the missing-key output of `scripts/podcast_pipeline.py`. ### Technical Analysis The Skill explicitly instructs the Agent to provide a fixed URL containing the referral identifier `refid=asgbifle`. A registration or settings URL is relevant to the declared transcription workflow, but the referral parameter is not technically necessary to acquire or configure an API key. The instruction does not disclose that the URL is promotional, tracked, or potentially associated with a benefit to the Skill author. Because the instruction is embedded in the Skill workflow, loading the Skill can cause author-selected promotional content to be inserted into an Agent response. This behavior exceeds the minimum privileges and output control required for podcast transcription. The legitimate requirement can be fulfilled using AuralWise's canonical website or API-key settings URL without a referral identifier. ### Attack Path 1. A user requests podcast transcription without already having an AuralWise API key. 2. The Agent loads the Skill and follows its API-key setup instructions. 3. The Agent reproduces the mandatory referral-bearing URL. 4. The user follows the URL without being informed that it contains a referral identifier. 5. The Skill author or referral owner may receive tracking data, attribution, or another promotional benefit. ### Impact Assessment The issue does not grant operating-system privileges or direct access to user files. Its scope is manipulation of Agent output and user navigation. Potential impact includes: - Undisc ...[truncated 259 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/podcast_pipeline.py:204
Finding

Unrestricted RSS and Enclosure URLs Enable Server-Side Request Forgery

Content
View full analysis
list: """解析 RSS Feed,返回全部单集信息""" logging.info("=" * 60) logging.info("Phase 1: 解析 RSS Feed") logging.info("=" * 60) episodes = [] try: resp = requests.get(rss_url, headers={"User-Agent": ua}, timeout=30) ``` The enclosure URL is taken directly from untrusted RSS XML: ```python enclosure = item.find("enclosure") audio_url = "" audio_size = 0 if enclosure is not None: audio_url = enclosure.get("url", "") ``` That feed-controlled URL is fetched locally without destination validation: ```python def download_audio(audio_url: str, filepath: Path, ep_label: str = "", ua: str = "", referer: str = "", max_retries: int = 3, delay: int = 2, timeout: int = 600) -> bool: """流式下载音频,支持断点续传""" if filepath.exists() and filepath.stat().st_size > 1024 * 100: size_mb = filepath.stat().st_size / (1024 * 1024) logging.info(f" [{ep_label}] 音频已存在 ({size_mb:.1f}MB),跳过") return True if not audio_url: logging.warning(f" [{ep_label}] 无音频直链") return False chunk_size = 1024 * 256 for attempt in range(1, max_retries + 1): try: logging.info(f" [{ep_label}] 下载中 (尝试 {attempt}/{max_retries})...") headers = {"User-Agent": ua} if referer: headers["Referer"] = referer resp = requests.get(audio_url, headers=headers, stream=True, timeout=timeout) ``` The same untrusted URL is forwarded to AuralWise, which is instructed to retrieve it: ```python payload = { "audio_url": audio_url, "audio_file ...[truncated 3773 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/podcast_pipeline.py:212
Finding

Unbounded Remote Responses Can Exhaust Memory and Disk

Content
View full analysis
0 else 0 logging.info( f" [{ep_label}] {downloaded/1024/1024:.0f}MB / " f"{total_size/1024/1024:.0f}MB ({pct:.0f}%) {speed:.1f}MB/s" ) ``` ### Technical Analysis The RSS request uses `resp.text`, causing the complete remote response to be held in memory. A timeout limits periods of inactivity but does not establish a maximum number of bytes. A server that continuously returns data can therefore produce a response substantially larger than a legitimate RSS feed. The audio downloader streams data ...[truncated 1807 chars]
Remediation
View remediation
max_bytes: raise ValueError("Download exceeds configured size limit") f.write(chunk) ``` 5. Check available disk space before starting each download and before beginning a batch. 6. Validate that the response has an expected audio media type. 7. Write downloads to a temporary partial filename and atomically rename the file only after successful validation. 8. Delete partial files after timeout, limit violation, or other failure. 9. Apply an XML parser strategy suitable for bounded, untrusted input. 10. Add process-level memory, execution-time, and filesystem quotas when running the Skill in an Agent environment. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
87% confidence
Finding

The core declared behavior largely matches the code: it processes a supplied podcast RSS feed, downloads audio, uses AuralWise for transcription, and stores transcript outputs. However, the description materially overstates two capabilities. First, it claims AI-generated overviews with book references, key concepts, and searchable keywords, but the code contains no such summarization or enrichment logic beyond saving transcripts and show notes. Second, it claims RSS feed discovery, while the code requires an explicit --rss-url and only parses that feed. There are no clearly harmful or unrelated undeclared behaviors; state persistence, logging, filtering, and retry logic are supporting details. Overall this is a partial but meaningful description/behavior mismatch.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The documented use of --env-file .env indicates the pipeline will read credentials from a plaintext file, which is a sensitive credential access pattern. In the context of an agent skill with file-read capability and no declared scope restrictions, this increases the risk of over-reading, accidental exposure, or secret reuse outside the user's intent.

Content

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

python3 scripts/podcast_pipeline.py
--rss-url "https://example.com/feed.xml"
--podcast-name "播客名称"
--env-file .env

text

**Test mode (recommended first run) — process 2 shortest episodes:**

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

This second example repeats the same credential-access pattern in a recommended test workflow, normalizing insecure secret handling. Because it is presented as standard usage, users are more likely to store real secrets in an easily exposed plaintext file.

Content

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

python3 scripts/podcast_pipeline.py
--rss-url "https://example.com/feed.xml"
--podcast-name "播客名称"
--env-file .env
--test 2

text

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The parameter table explicitly supports direct API key passing and .env-based secret loading, both of which are high-risk if not tightly controlled. CLI arguments may leak through shell history or process inspection, and .env files may leak through filesystem exposure or version control.

Content

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

md
| `--podcast-name` | No | Podcast name (default: "播客") |
| `--output-dir` | No | Output root dir (default: ~/Desktop/{name}合集) |
| `--api-key` | No | AuralWise API Key directly |
| `--env-file` | No | Path to .env file containing API Key |
| `--test N` | No | Test mode: process N shortest episodes |
| `--download-only` | No | Download audio only, skip transcription |
| `--transcribe-only` | No | Transcribe only, skip download |

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/podcast_pipeline.py (reported line 41)May include surrounding context.

python
# 仅转写(已有音频文件)
  python3 podcast_pipeline.py --rss-url "..." --transcribe-only

  # 从 .env 文件读取 API Key
  python3 podcast_pipeline.py --rss-url "..." --env-file .env

转写服务:AuralWise API (https://auralwise.cn)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/podcast_pipeline.py (reported line 42)May include surrounding context.

python
# 仅转写(已有音频文件)
  python3 podcast_pipeline.py --rss-url "..." --transcribe-only

  # 从 .env 文件读取 API Key
  python3 podcast_pipeline.py --rss-url "..." --env-file .env

转写服务:AuralWise API (https://auralwise.cn)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/podcast_pipeline.py (reported line 129)May include surrounding context.

python
# 仅转写(已有音频文件)
  python3 podcast_pipeline.py --rss-url "..." --transcribe-only

  # 从 .env 文件读取 API Key
  python3 podcast_pipeline.py --rss-url "..." --env-file .env

转写服务:AuralWise API (https://auralwise.cn)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/podcast_pipeline.py (reported line 758)May include surrounding context.

python
# 仅转写(已有音频文件)
  python3 podcast_pipeline.py --rss-url "..." --transcribe-only

  # 从 .env 文件读取 API Key
  python3 podcast_pipeline.py --rss-url "..." --env-file .env

转写服务:AuralWise API (https://auralwise.cn)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/podcast_pipeline.py (reported line 822)May include surrounding context.

python
# 仅转写(已有音频文件)
  python3 podcast_pipeline.py --rss-url "..." --transcribe-only

  # 从 .env 文件读取 API Key
  python3 podcast_pipeline.py --rss-url "..." --env-file .env

转写服务:AuralWise API (https://auralwise.cn)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly instructs access to environment files, local file reads/writes, and network calls, yet it declares no explicit tool scope or permission boundaries. That increases the chance an agent invokes broader capabilities than a user expects, especially when handling credentials and downloading external content.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger language is broad enough to match generic requests about downloading or converting audio, which can cause the skill to activate outside its intended podcast-specific context. Over-broad routing is risky because it can lead to unexpected network access, file creation, or credential prompts for tasks the user did not intend this skill to handle.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users to place a live API key into a local .env file without warning that it is a sensitive secret, how it should be protected, or that it must not be exposed in logs or shared directories. This creates a realistic risk of credential leakage through source control, filesystem exposure, or accidental reuse by other tools.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The prompt text shown to the user is only in Chinese, and the documented default transcription language is zh, but the skill does not say this is optional or ask the user to choose their preferred language. That creates a language/locale policy issue because the skill imposes a specific language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The skill sends authentication material and podcast-related processing requests to an external third-party API. External transmission is expected for cloud transcription, but it is still security-relevant because user-supplied audio URLs, account metadata, and possibly transcript content may leave the local environment.

Content

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

text
   AURALWISE_API_KEY=asr_user_provided_key
  1. Verify the Key — call GET https://api.auralwise.cn/v1/account with header X-API-Key: {key} to confirm balance and concurrency.
  2. If user only wants downloads (no transcription) — use --download-only flag, skip API Key requirement.

See references/auralwise_api.md for full API documentation.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The parameter table specifies --language defaulting to zh, which means the skill applies a locale choice by default. The document does not explain that this is configurable in practice for users or justify why Chinese must be the default for all uses.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
81% confidence
Finding

This reference file directs the skill to transmit data to an external API endpoint operated by AuralWise. External transmission is expected for a transcription integration, but in this skill it becomes security-relevant because podcast content, metadata, and potentially user-supplied audio URLs leave the local environment and are processed by a third party without accompanying security/privacy constraints in the documentation.

Content

Scanner excerpt · references/auralwise_api.md (reported line 23)May include surrounding context.

md
## API 端点

Base URL: `https://api.auralwise.cn/v1`

### 1. 查询账户信息

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document explicitly instructs users to provide publicly accessible audio URLs to a third-party transcription provider, but it does not warn that podcast audio, feed-derived media, or any non-public audio would be exposed to that external service. In this skill context, the feature is core functionality rather than overtly malicious, but the missing privacy/data-handling disclosure creates a real risk of unintended data sharing and policy violations if users process private or copyrighted content they do not expect to leave the local workflow.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/podcast_pipeline.py (reported line 341)May include surrounding context.

python
class AuralWiseTranscriber:
    """AuralWise API 客户端"""

    BASE_URL = "https://api.auralwise.cn/v1"

    # 默认转写选项(播客单人主讲场景)
    DEFAULT_OPTIONS = {

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The default options hard-code asr_language to zh, which imposes a specific language/locale behavior by default. Although a --language flag exists later, the built-in default still forces Chinese unless the user notices and overrides it.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends episode audio URLs and filenames to a third-party transcription service without an explicit privacy disclosure or user confirmation. Even when only a URL is transmitted, this shares listening targets and content with an external processor and may expose private, unlisted, paid, or internal podcast media to that service.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This is a real external transmission: the script posts user-supplied podcast audio URLs, filenames, and transcription options to AuralWise. In the context of a transcription skill this behavior is expected, but it is still security-relevant because it transfers content context to a third party and can implicate privacy, confidentiality, and compliance concerns if users are not clearly informed.

Content

Scanner excerpt · scripts/podcast_pipeline.py (reported line 387)May include surrounding context.

python
for attempt in range(1, max_retries + 1):
            try:
                resp = requests.post(
                    f"{self.BASE_URL}/tasks",
                    headers=self.headers,
                    json=payload,

Tainted flow: 'task_id' from requests.get (line 395, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/podcast_pipeline.py (reported line 435)May include surrounding context.

python
return "timeout"

            try:
                resp = requests.get(
                    f"{self.BASE_URL}/tasks/{task_id}",
                    headers=self.headers,
                    timeout=10,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script persistently writes transcripts, subtitles, show notes, logs, and pipeline state to disk without any consent prompt, privacy notice, retention control, or permission hardening. Podcast audio may contain sensitive personal data or licensed content, and these artifacts create a local confidentiality risk if stored in shared directories or synced folders.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The overview states that the skill downloads all episodes and produces audio, transcript, notes, logs, and state files, which can materially affect local storage and user data layout. The markdown does not include a clear warning about disk usage, output location, or that batch mode may write many files automatically.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file presents all instructions, examples, and headings exclusively in Chinese, which can amount to a language/locale policy violation when no user opt-in or alternative language is offered. The document also does not state that it is intentionally region-specific or limited to Chinese-speaking users.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/podcast_pipeline.py:825

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:38