Back to skill

Security audit

Design Daily

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent design-news tool, but it needs review because it stores API keys in a local plaintext file and uses unsafe shell command construction during setup.

Install only if you are comfortable providing Serper and DeepSeek API keys, having them stored in a local .env file, and sending search-result material plus your configured design preferences to external APIs. Prefer setting API keys through your environment instead of running the setup wizard, restrict .env permissions if you use it, avoid install paths with spaces or shell metacharacters, and review any cron entry before copying it.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Warning
Location
setup.py:284
Finding

API Credentials Stored Without Restrictive File Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
setup.py:541
Finding

Shell Command Injection Through Unquoted Interpreter and Script Paths

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
setup.py:396
Finding

Unsafe Path Interpolation in Suggested Crontab Entry

Content
View full analysis
> {BASE_DIR.resolve()}/logs/cron.log 2>&1" ) print(f""" {CYAN}── 定时运行设置(可选)──{RESET} 如需每天 {push_time} 自动运行,执行: {BOLD}crontab -e{RESET} 添加这一行: {YELLOW}{cron_line}{RESET} """) ``` ### Technical Analysis The generated cron command inserts the resolved project directory into shell syntax without quoting it. A path containing whitespace can make the command fail, while a path containing shell metacharacters can alter the command that cron executes. The function only prints the entry. It does not call `crontab`, edit system files, or automatically register a scheduled task. Therefore, the scheduling behavior is optional, disclosed, and appropriate for a daily-news Skill. It is not unauthorized persistence by itself. The security issue arises only if a user manually copies the unsafe generated entry into crontab. ### Attack Path 1. The project is placed in a directory containing whitespace or attacker-controlled shell metacharacters. 2. The user runs the setup wizard. 3. `print_crontab()` displays a cron entry containing the unquoted path. 4. The user manually copies that line into `crontab -e`. 5. Cron invokes the entry through a shell at the selected time. 6. Shell metacharacters in the path execute attacker-selected commands on every scheduled run. ### Impact Assessment If exploited, commands execute persistently under the account that installed the cron entry. The attacker may obtain the same file, process, and network access as that user. There is no evidence that the Skill automatically installs persistence or requests elevated scheduling privileges ...[truncated 91 chars]
Remediation
View remediation
> {log_path} 2>&1" ) ``` - Warn users that the entry will execute with their account privileges. - Continue requiring explicit manual opt-in rather than automatically modifying crontab. - Consider generating a small wrapper script with fixed permissions instead of a complex shell command. ]]>

other

Warning
Location
brief.py:68
Finding

Indirect Prompt Injection Through Untrusted Search Results

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (33)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · brief.py (reported line 124)May include surrounding context.

python
if not DEEPSEEK_KEY:
        raise EnvironmentError("DEEPSEEK_API_KEY 未设置,请检查环境变量")

    resp = requests.post(
        DEEPSEEK_URL,
        headers={
            "Authorization": f"Bearer {DEEPSEEK_KEY}",

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · fetch.py (reported line 168)May include surrounding context.

python
if tbs:
        payload["tbs"] = tbs

    resp = requests.post(
        SERPER_URL,
        headers={"X-API-KEY": SERPER_KEY, "Content-Type": "application/json"},
        json=payload,

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented purpose is a design-news brief, but the described behavior includes collecting and validating API keys, writing secrets to local files, generating cron instructions, and executing another program. This mismatch is dangerous because users may consent to a harmless content skill while unintentionally granting credential handling, persistence-related setup, and code execution capabilities that exceed the stated purpose.

Content

No source excerpt is available for this finding.

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 · run.py (reported line 25)May include surrounding context.

python
# ── 自动加载 .env(setup.py 写入的 key)─────────────────────────────────────
def load_dotenv():
    env_path = BASE_DIR / ".env"
    if env_path.exists():
        import os
        for line in env_path.read_text(encoding="utf-8").splitlines():

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 · setup.py (reported line 6)May include surrounding context.

python
"""
setup.py
Design Brief Skill 一键配置向导
运行后自动生成 .env 和 config.yaml
"""

import os

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 · setup.py (reported line 291)May include surrounding context.

python
"""
setup.py
Design Brief Skill 一键配置向导
运行后自动生成 .env 和 config.yaml
"""

import os

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The script writes API credentials directly to a local .env file in plaintext. In a developer-tooling context this is common, but it remains dangerous because secrets may be exposed through weak filesystem permissions, accidental commits, shared machines, or backup/sync systems.

Content

Scanner excerpt · setup.py (reported line 285)May include surrounding context.

python
# ── 写入文件 ──────────────────────────────────────────────────────────────────

def write_env(serper_key: str, deepseek_key: str):
    env_path = BASE_DIR / ".env"
    env_path.write_text(
        f"SERPER_API_KEY={serper_key}\n"
        f"DEEPSEEK_API_KEY={deepseek_key}\n",

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · setup.py (reported line 547)May include surrounding context.

python
os.environ["SERPER_API_KEY"]   = serper_key
        os.environ["DEEPSEEK_API_KEY"] = deepseek_key
        os.chdir(BASE_DIR)
        os.system(f"{sys.executable} {BASE_DIR / 'run.py'}")


if __name__ == "__main__":

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares required environment variables, package installation, file editing, scheduled execution, and direct command invocation, but it does not define any explicit tool permissions or allowed-tool scope. In an agent environment, this over-broad implicit capability can let the skill access network, shell, and local files beyond what users reasonably expect, increasing the blast radius if the implementation is changed or abused.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language instructions, setup steps, and examples are presented only in Chinese, which can force a specific language experience on users who invoke the skill via English triggers such as 'design brief' or 'design news today'. The file does not state that the skill is Chinese-only, region-specific, or provide any language-selection option.

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 · brief.py (reported line 14)May include surrounding context.

python
import requests

DEEPSEEK_KEY   = os.environ.get("DEEPSEEK_API_KEY", "")
DEEPSEEK_URL   = "https://api.deepseek.com/chat/completions"
DEEPSEEK_MODEL = "deepseek-chat"

# ── System Prompt ─────────────────────────────────────────────────────────────

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 · setup.py (reported line 214)May include surrounding context.

python
import requests

DEEPSEEK_KEY   = os.environ.get("DEEPSEEK_API_KEY", "")
DEEPSEEK_URL   = "https://api.deepseek.com/chat/completions"
DEEPSEEK_MODEL = "deepseek-chat"

# ── System Prompt ─────────────────────────────────────────────────────────────

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This function sends aggregated prompt content to an external API, which is a real security-relevant data flow in an agent skill context. Because the prompt is built from raw source material and favorite_designer metadata, the skill can exfiltrate sensitive or internal content to a third party if upstream inputs are not trusted or filtered.

Content

Scanner excerpt · brief.py (reported line 124)May include surrounding context.

python
if not DEEPSEEK_KEY:
        raise EnvironmentError("DEEPSEEK_API_KEY 未设置,请检查环境变量")

    resp = requests.post(
        DEEPSEEK_URL,
        headers={
            "Authorization": f"Bearer {DEEPSEEK_KEY}",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code transmits raw_items content, titles, snippets, URLs, and possibly user preference data to a third-party LLM service without any consent gate, redaction step, or documented data handling control. If the upstream content or user-associated metadata contains confidential, proprietary, or personal information, this creates an external data exposure risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This manifest/config file contains user-facing instructions and field guidance almost exclusively in Chinese, which effectively forces a specific language for users configuring the skill. There is no visible opt-in, alternative language option, or justification that the skill is intended only for a Chinese-speaking region or audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The request payload hard-codes "hl": "en" and "gl": "us", which imposes a specific language and geographic locale on every search. This is a natural-language policy concern because the file contains no opt-in, fallback, or justification for forcing English/US results despite supporting Chinese-language roles and queries elsewhere in the skill.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · fetch.py (reported line 168)May include surrounding context.

python
if tbs:
        payload["tbs"] = tbs

    resp = requests.post(
        SERPER_URL,
        headers={"X-API-KEY": SERPER_KEY, "Content-Type": "application/json"},
        json=payload,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring and user-facing usage text are entirely in Chinese, and later log/output strings throughout the file are also Chinese-only. This imposes a specific language on users without any opt-in or indication that the skill is intentionally limited to a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script announces that it will generate a .env file, but it does not provide an explicit security warning about storing live API credentials in plaintext on disk. Local plaintext secret storage increases exposure if the workstation, repository, backups, or file permissions are not properly controlled.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

User-facing prompts, descriptions, and guidance throughout the script are written in Chinese, and the title/brief do not indicate that the skill is Chinese-only or provide any opt-in language selection. This creates a language-policy concern because the locale is effectively forced without explicit user choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The wizard asks users to paste API keys, then immediately transmits those secrets to third-party services for validation without a clear, explicit privacy warning at the time of collection. While the destinations are the intended vendors, users should be informed that their entered credentials will be sent over the network for verification.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

This duplicate finding describes the same secret-bearing Serper validation request. In context, the risk is not malicious exfiltration but undisclosed outbound handling of credentials.

Content

Scanner excerpt · setup.py (reported line 200)May include surrounding context.

python
def verify_serper_key(key: str) -> bool:
    try:
        resp = requests.post(
            "https://google.serper.dev/search",
            headers={"X-API-KEY": key, "Content-Type": "application/json"},
            json={"q": "design news", "num": 1},

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

This duplicate finding describes the same secret-bearing Serper validation request. In context, the risk is not malicious exfiltration but undisclosed outbound handling of credentials.

Content

Scanner excerpt · setup.py (reported line 200)May include surrounding context.

python
def verify_serper_key(key: str) -> bool:
    try:
        resp = requests.post(
            "https://google.serper.dev/search",
            headers={"X-API-KEY": key, "Content-Type": "application/json"},
            json={"q": "design news", "num": 1},

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

This duplicate finding refers to the same DeepSeek credential validation request. The concern remains that a sensitive token is transmitted externally without especially prominent disclosure at entry time.

Content

Scanner excerpt · setup.py (reported line 213)May include surrounding context.

python
def verify_deepseek_key(key: str) -> bool:
    try:
        resp = requests.post(
            "https://api.deepseek.com/chat/completions",
            headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
            json={

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

This duplicate finding refers to the same DeepSeek credential validation request. The concern remains that a sensitive token is transmitted externally without especially prominent disclosure at entry time.

Content

Scanner excerpt · setup.py (reported line 213)May include surrounding context.

python
def verify_deepseek_key(key: str) -> bool:
    try:
        resp = requests.post(
            "https://api.deepseek.com/chat/completions",
            headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
            json={

Static analysis

No suspicious patterns detected.