Back to skill

Security audit

Deckly Redesign

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but it handles passwords, verification codes, presentation uploads, paid actions, and long-lived API keys in ways users should review carefully before installing.

Install only if you are comfortable sending presentation contents to Deckly and letting the agent manage a Deckly account. Avoid entering passwords or verification codes directly in chat, prefer a pre-created API token if possible, do not use this on confidential decks without data-handling approval, avoid custom DECKLY_API_BASE values unless you trust the destination, and review/revoke saved API keys when finished.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/deckly.py:12
Finding

Unrestricted API Base Override Can Exfiltrate Credentials and Documents

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/deckly.py:526
Finding

Account Passwords Are Collected in Chat and Exposed Through Command-Line Arguments

Content
View full analysis
# user reads the 6-digit code from their email: python scripts/deckly.py verify --email user@example.com --code 123456 ``` **If `signup` returns `status: account_exists`**, the email already has a Deckly account. Tell the user it will use their existing account, then ask for their password and run `login` (required to fetch a key): ```bash python scripts/deckly.py login --email user@example.com --password ``` ``` ```python su = sub.add_parser("signup") su.add_argument("--email", required=True) su.add_argument("--password", required=True) su.set_defaults(func=cmd_signup) vf = sub.add_parser("verify") vf.add_argument("--email", required=True) vf.add_argument("--code", required=True) vf.add_argument("--password") vf.set_defaults(func=cmd_verify) lg = sub.add_parser("login") lg.add_argument("--email", required=True) lg.add_argument("--password", required=True) lg.set_defaults(func=cmd_login) ``` ### Technical Analysis The Skill explicitly directs the agent to ask users to disclose passwords in the conversation and then supplies those passwords through command-line arguments. This unnecessarily places account credentials in several observable locations: - Agent and chat transcripts. - Shell history. - Process argument listings. - Terminal session recordings. - Automation logs and telemetry. - Error reports that capture invoked commands. Command-line arguments are not a suitable c ...[truncated 1601 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/deckly.py:38
Finding

Long-Lived API Key File Is Created Before Restrictive Permissions Are Enforced

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
README.md:22
Finding

Quick-Install Instructions Execute an Unpinned Third-Party Package

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (27)

Ssd 3

High
Category
Not specified by scanner
Confidence
100% confidence
Finding

The skill directs the agent to collect email, password, and a 6-digit email verification code in chat and then perform signup, verify, and login actions. This is highly sensitive authentication material, and handling it in the conversational channel creates a direct account-takeover and secret-exposure risk if logs, transcripts, or tool invocations are accessible.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill explicitly instructs the agent to ask the user for an email and password in chat, with no warning about sensitivity or safer alternatives. Collecting credentials in-band through the conversation exposes secrets to logging, retention, prompt leakage, and accidental disclosure to downstream tools or operators.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · reference.md (reported line 126)May include surrounding context.

md
TOKEN=...   # from /auth/login

# 1. create + upload
PID=$(curl -s -X POST "$BASE/projects" -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"name":"My Deck"}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["id"])')
curl -s -X POST "$BASE/projects/$PID/upload" -H "Authorization: Bearer $TOKEN" -F "file=@deck.pptx"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README says the skill uses the Deckly API to analyze and restyle PowerPoint/PDF decks, but it does not clearly warn that user files will be transmitted to a third-party service. This creates a real privacy and data-handling risk because users may provide confidential presentations without understanding that the content leaves the local environment.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger phrase 'Redesign this presentation to look more professional' is broad and maps to a common user intent, which can cause the skill to auto-activate in situations where the user did not explicitly consent to using Deckly or sending files to an external service. In this skill's context, that matters because activation may lead to third-party processing of presentation content, including potentially sensitive business or academic materials.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes shell commands, network access, environment-variable based credentials, and local file writes, but declares no explicit tool scope or permissions. That increases the chance an agent executes broader capabilities than necessary, making review, sandboxing, and least-privilege enforcement harder.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instruction to onboard users 'right in the chat' and specifically forbid sending them to a website removes user choice and pushes them toward insecure credential sharing. In this context, that coercive workflow materially increases the likelihood of credential compromise because the agent becomes the collection point for secrets.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

text

Notes:
- `verify` and `login` both create and save a `dk_` API key to `~/.deckly/credentials` (chmod 600). After that, never ask for credentials again unless the user switches accounts.
- New accounts get a free 3-slide preview (0 credits) — perfect for a first trial run.
- To use a different account, the user can pass `DECKLY_EMAIL`/`DECKLY_PASSWORD` or delete `~/.deckly/credentials`.

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

The skill persists an API key in ~/.deckly/credentials for reuse across sessions, creating long-lived local access to the user's Deckly account. Even with chmod 600, persistent tokens increase the blast radius of host compromise, multi-user environment mistakes, or unintended reuse by future tasks under the same agent context.

Content

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

text

Notes:
- `verify` and `login` both create and save a `dk_` API key to `~/.deckly/credentials` (chmod 600). After that, never ask for credentials again unless the user switches accounts.
- New accounts get a free 3-slide preview (0 credits) — perfect for a first trial run.
- To use a different account, the user can pass `DECKLY_EMAIL`/`DECKLY_PASSWORD` or delete `~/.deckly/credentials`.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

style_preset accepts: a text_style:<id> (e.g. text_style:minimalist_corporate), a template theme id (e.g. dark-blue-business), or any free-text style name (AI-generated). Also collect an optional --custom instruction from the user (e.g. "use our brand blue, keep it minimal").

3. Redesign — for first-time users this automatically runs as a free 3-slide preview. Otherwise confirm cost with quote first.

bash
python scripts/deckly.py quote <project_id> --slides 1-12        # check cost / can_afford

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 · reference.md (reported line 15)May include surrounding context.

bash
# 1. register -> emails a 6-digit code
curl -s -X POST "$BASE/auth/register" -H 'Content-Type: application/json' \
  -d '{"email":"you@example.com","password":"chosen-pw"}'
# 2. verify with the code -> returns a JWT
curl -s -X POST "$BASE/auth/verify-email" -H 'Content-Type: application/json' \

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 · reference.md (reported line 126)May include surrounding context.

md
TOKEN=...   # from /auth/login

# 1. create + upload
PID=$(curl -s -X POST "$BASE/projects" -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"name":"My Deck"}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["id"])')
curl -s -X POST "$BASE/projects/$PID/upload" -H "Authorization: Bearer $TOKEN" -F "file=@deck.pptx"

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

This endpoint uploads an entire local presentation file to an external third-party service. In the context of a skill that may process sensitive corporate decks, that creates real confidentiality risk if users are not explicitly warned that deck contents leave the local environment and are stored/processed remotely.

Content

Scanner excerpt · reference.md (reported line 128)May include surrounding context.

md
# 1. create + upload
PID=$(curl -s -X POST "$BASE/projects" -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"name":"My Deck"}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["id"])')
curl -s -X POST "$BASE/projects/$PID/upload" -H "Authorization: Bearer $TOKEN" -F "file=@deck.pptx"

# 2. extract, then poll until status == extracted
curl -s -X POST "$BASE/projects/$PID/analyze" -H "Authorization: Bearer $TOKEN"

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill goes beyond deck-redesign functionality by implementing signup, login, token minting, and persistent credential storage. That expands the trust boundary substantially: the agent can collect user credentials, create long-lived API keys, and retain them for future runs, which increases risk if the host, logs, or local filesystem are compromised.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code reads DECKLY_EMAIL and DECKLY_PASSWORD from the environment, exchanges them for a JWT, then creates and persists a durable API key for the agent. This is dangerous because it silently converts highly sensitive credentials into reusable long-term access that can survive beyond the user’s immediate session and be abused if the config file is exposed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

When DECKLY_EMAIL and DECKLY_PASSWORD are present, the skill transmits them to the remote /auth/login endpoint without any user-facing disclosure in the workflow. Even over HTTPS, silently using environment-provided credentials in an agent context can surprise users and administrators and may violate expectations around secret handling.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/deckly.py (reported line 67)May include surrounding context.

python
password = os.environ.get("DECKLY_PASSWORD")
    if email and password:
        data = _request(base, "POST", "/auth/login",
                        body={"email": email, "password": password}, auth=False)
        return data["access_token"]
    raise DecklyError(
        "No credentials. Run 'signup' + 'verify' to register in-conversation, "

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/deckly.py (reported line 78)May include surrounding context.

python
password = os.environ.get("DECKLY_PASSWORD")
    if email and password:
        data = _request(base, "POST", "/auth/login",
                        body={"email": email, "password": password}, auth=False)
        return data["access_token"]
    raise DecklyError(
        "No credentials. Run 'signup' + 'verify' to register in-conversation, "

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/deckly.py (reported line 218)May include surrounding context.

python
password = os.environ.get("DECKLY_PASSWORD")
    if email and password:
        data = _request(base, "POST", "/auth/login",
                        body={"email": email, "password": password}, auth=False)
        return data["access_token"]
    raise DecklyError(
        "No credentials. Run 'signup' + 'verify' to register in-conversation, "

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/deckly.py (reported line 241)May include surrounding context.

python
password = os.environ.get("DECKLY_PASSWORD")
    if email and password:
        data = _request(base, "POST", "/auth/login",
                        body={"email": email, "password": password}, auth=False)
        return data["access_token"]
    raise DecklyError(
        "No credentials. Run 'signup' + 'verify' to register in-conversation, "

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/deckly.py (reported line 254)May include surrounding context.

python
password = os.environ.get("DECKLY_PASSWORD")
    if email and password:
        data = _request(base, "POST", "/auth/login",
                        body={"email": email, "password": password}, auth=False)
        return data["access_token"]
    raise DecklyError(
        "No credentials. Run 'signup' + 'verify' to register in-conversation, "

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/deckly.py (reported line 278)May include surrounding context.

python
password = os.environ.get("DECKLY_PASSWORD")
    if email and password:
        data = _request(base, "POST", "/auth/login",
                        body={"email": email, "password": password}, auth=False)
        return data["access_token"]
    raise DecklyError(
        "No credentials. Run 'signup' + 'verify' to register in-conversation, "

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/deckly.py (reported line 279)May include surrounding context.

python
password = os.environ.get("DECKLY_PASSWORD")
    if email and password:
        data = _request(base, "POST", "/auth/login",
                        body={"email": email, "password": password}, auth=False)
        return data["access_token"]
    raise DecklyError(
        "No credentials. Run 'signup' + 'verify' to register in-conversation, "

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The upload function sends the entire local presentation file to a remote service, but the code provides no disclosure, confirmation, or data-handling notice before transmission. Since decks commonly contain confidential business, financial, legal, or personal information, silent exfiltration to a third party is a meaningful privacy and compliance risk.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.secret_argv_exposure

Instructions pass high-value credentials through process argv.

Critical
Code
suspicious.secret_argv_exposure
Location
SKILL.md:30