Back to skill

Security audit

Deskbird-Automator

Security checks for vulnerabilities and agentic risk

Overview

This skill automates Deskbird, but it needs review because it handles raw session credentials, stores them for recurring use, and includes broad request replay/probe tools that can send those credentials outside Deskbird.

Install only after reviewing the broad debugging commands and credential flow. Avoid sending live Deskbird Authorization headers, cookies, or refresh tokens through Telegram; use a local-only auth path if possible. If installed, restrict the env file to owner-only permissions, keep cron booking rules narrow, and do not use probe/replay with stored credentials or untrusted capture files.

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/deskbird_tool.py:2363
Finding

Stored authentication credentials can be transmitted to arbitrary network destinations

Content
View full analysis
str: return os.getenv("DESKBIRD_BASE_URL", "https://api.deskbird.com").rstrip("/") ``` ```python elif key_l in {"deskbird_base_url", "base_url", "baseurl"}: out["DESKBIRD_BASE_URL"] = val.rstrip("/") ``` ```python if args.base_url: values["DESKBIRD_BASE_URL"] = str(args.base_url).strip().rstrip("/") ``` ```python def cmd_replay(args: argparse.Namespace) -> int: load_dotenv(args.env_file, override=False) data = read_json(Path(args.file)) records = data.get("records", []) if not records: print("Keine Records in Capture-Datei vorhanden.") return 1 rec = pick_record(records, args.id) method = rec.get("method", "GET") url = rec.get("url", "") req = rec.get("request", {}) captured_headers = req.get("headers", {}) or {} body = req.get("body", None) if args.override_json: body = read_json(Path(args.override_json)) auth_headers = build_auth_headers_from_env() headers = prepare_headers_for_replay(captured_headers, auth_headers) if args.dry_run: print("Dry-Run aktiv, es wird kein API-Call ausgefuehrt.") print(f"Method: {method}") print(f"URL: {url}") print("Header:") for key, value in headers.items(): safe_val = redact_value(value) if looks_secret_header(key) else value print(f" {key}: {safe_val}") print("Body:") print(json.dumps(body, indent=2, ensure_ascii=True) if isinstance(body, (dict, list)) else body) return 0 response = perform_request(method, url, headers, body, args.timeout) print_response_summary(response, max_chars=args.max_body_chars) return 0 ``` ```python de ...[truncated 4262 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/deskbird_tool.py:614
Finding

Long-lived authentication credentials are persisted without enforced restrictive file permissions

Content
View full analysis
None: env_path = Path(env_file) ensure_parent(env_path) if not env_path.exists(): env_path.write_text("", encoding="utf-8") for key, value in values.items(): if not value: continue set_key(str(env_path), key, value, quote_mode="always") ``` The values written through this function include: ```python auth_related_keys = [ "DESKBIRD_AUTHORIZATION", "DESKBIRD_COOKIE", "DESKBIRD_X_CSRF_TOKEN", "DESKBIRD_X_XSRF_TOKEN", ] ``` The same environment file can also contain `DESKBIRD_FIREBASE_REFRESH_TOKEN`, which is specifically intended to support persistent automatic reauthentication. ### Technical Analysis The Skill stores bearer tokens, cookies, CSRF values, Firebase API keys, and long-lived Firebase refresh tokens as plaintext in an environment file. The wrapper creates that file with `touch`, while the Python implementation creates it with `Path.write_text()` and updates it through `python-dotenv`. Neither path explicitly enforces owner-only permissions such as mode `0600`. Consequently, the resulting mode depends on: - The process umask. - Existing permissions if the file already exists. - Permissions and ownership of a user-selected `DESKBIRD_ENV_FILE`. - Whether the selected path is a symbolic link. Because the Firebase refresh token can mint new bearer tokens, exposure is more serious than disclosure of a short-lived access token alone. ### Attack Path 1. The Skill executes with a permissive umask, points to an existing broadly readable file, or receives a `DESKBIRD_ENV_FILE` p ...[truncated 1301 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Credential-handling dependencies are installed from unpinned version ranges without integrity verification

Content
View full analysis
=1.50.0 requests>=2.32.0 python-dotenv>=1.0.1 urllib3<2 ``` The installation instructions are: ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt python -m playwright install chromium ``` ### Technical Analysis The requirements use open-ended minimum versions rather than exact reviewed versions. No lock file or package hashes are provided. The Playwright-managed Chromium binary is also installed without an explicitly documented and reviewed browser revision. As a result, two installations performed at different times may execute different package or browser code. These dependencies run in a process that captures browser requests, handles Deskbird tokens and cookies, submits Firebase refresh tokens, and sends authenticated API requests. This is a supply-chain hardening weakness rather than evidence that any currently named package is malicious. The package names are legitimate and no dependency-confusion or typosquatting package was identified in the audited files. ### Attack Path 1. A future package release satisfying one of the open version ranges is compromised, vulnerable, or behaviorally incompatible. 2. A user follows the documented `pip install -r requirements.txt` procedure. 3. The package resolver downloads the newer artifact because no exact version or hash is required. 4. The unreviewed dependency executes in the Skill's Python environment. 5. Because the process handles Deskbird and Firebase credentials, malicious dependency code could read those credentials, alter authenticated requests, or transmit secrets externally. The same general risk applies to an unreviewed Playwright browser artifact installed at setup time. ### Impact Assessment If a resolved dependency or browser artifact were ...[truncated 555 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (37)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared purpose presents a narrowly scoped Deskbird/Telegram automation skill, but the behavior described by analysis includes generic request capture, replay, and endpoint probing capabilities that are much broader and dual-use. That mismatch is dangerous because operators may trust and approve the skill based on its description while it can handle sensitive auth material and perform broader network actions than expected.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Verwende diesen Skill, um Deskbird ueber das lokale CLI (`scripts/deskbird_tool.py`) sicher zu bedienen und optional als wiederkehrende Cron-Session laufen zu l

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The template explicitly tells users to copy live Authorization headers and related session material from browser DevTools into Telegram, then import them for bot reuse. That exposes bearer/session credentials through a third-party messaging channel and bot processing path, increasing the risk of account takeover, session hijacking, and unintended retention in chat history or logs.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The template instructs users to paste live authorization headers or tokens into Telegram specifically so the bot can reuse them for subsequent authenticated API actions. In this skill context, that is especially dangerous because the bot is designed for recurring cron sessions and automated booking, so a stolen or retained token could enable repeated unauthorized actions against the user's Deskbird account.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script explicitly brands itself as a reverse-engineering helper and implements browser capture, request replay, and generalized API probing well beyond the stated Deskbird parking/auth automation scope. In an agent skill context, this enables collection and reuse of authenticated traffic against arbitrary Deskbird endpoints, materially expanding capability from task automation into credentialed reconnaissance and action replay.

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 · scripts/deskbird_tool.py (reported line 612)May include surrounding context.

python
return
    if "Cookie" in auth_headers:
        return
    raise ValueError("Keine Auth-Header gefunden. Bitte DESKBIRD_AUTHORIZATION oder DESKBIRD_COOKIE in .env setzen.")


def upsert_env_file(env_file: str, values: dict[str, str]) -> None:

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

python
return
    if "Cookie" in auth_headers:
        return
    raise ValueError("Keine Auth-Header gefunden. Bitte DESKBIRD_AUTHORIZATION oder DESKBIRD_COOKIE in .env setzen.")


def upsert_env_file(env_file: str, values: dict[str, str]) -> None:

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

python
return
    if "Cookie" in auth_headers:
        return
    raise ValueError("Keine Auth-Header gefunden. Bitte DESKBIRD_AUTHORIZATION oder DESKBIRD_COOKIE in .env setzen.")


def upsert_env_file(env_file: str, values: dict[str, str]) -> None:

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

python
return
    if "Cookie" in auth_headers:
        return
    raise ValueError("Keine Auth-Header gefunden. Bitte DESKBIRD_AUTHORIZATION oder DESKBIRD_COOKIE in .env setzen.")


def upsert_env_file(env_file: str, values: dict[str, str]) -> None:

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

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

python
save_auth_pair_store(store_path, state)
        raise ValueError("Pairing-Code ist abgelaufen. Bitte ein neues Pairing starten.")

    env_file = str(args.env_file or session.get("env_file") or ".env")
    start_url = str(args.start_url or session.get("start_url") or "https://app.deskbird.com")
    api_domain = str(args.api_domain or session.get("api_domain") or "api.deskbird.com")
    requested_min_valid_minutes = int(session.get("min_valid_minutes", 90))

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The command set includes generic capture, replay, and probe operations that let a user or agent inspect browser API behavior and send arbitrary authenticated requests. This is dangerous because it can be used to enumerate undocumented endpoints, replay sensitive state-changing calls, and exceed the principle of least privilege implied by the skill's stated purpose.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The auth-import feature explicitly supports importing Authorization/Cookie values from Telegram text into local secret storage. In the context of an agent skill, accepting raw credentials from chat channels raises serious credential-handling risk, including accidental forwarding, interception, or misuse of bearer tokens and session cookies.

Content

Scanner excerpt · scripts/deskbird_tool.py (reported line 2752)May include surrounding context.

python
p_auth_import = sub.add_parser(
        "auth-import",
        help="Importiert Authorization/Cookie aus DevTools- oder Telegram-Text nach .env",
    )
    p_auth_import.add_argument("--env-file", default=".env")
    p_auth_import.add_argument("--authorization", help="Kompletter Authorization-Header-Wert")

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The command arguments encourage direct ingestion of complete authorization headers, bearer tokens, and cookies into the tool. This is dangerous because it normalizes manual secret transfer and increases the blast radius if logs, shell history, chat transcripts, or local files are exposed.

Content

Scanner excerpt · scripts/deskbird_tool.py (reported line 2754)May include surrounding context.

python
"auth-import",
        help="Importiert Authorization/Cookie aus DevTools- oder Telegram-Text nach .env",
    )
    p_auth_import.add_argument("--env-file", default=".env")
    p_auth_import.add_argument("--authorization", help="Kompletter Authorization-Header-Wert")
    p_auth_import.add_argument("--token", help="Rohes Bearer-Token (JWT). 'Bearer ' wird automatisch ergaenzt.")
    p_auth_import.add_argument("--cookie", help="Kompletter Cookie-Header-Wert")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill directs the agent to use local scripts, environment-backed credentials, file operations on .env, and networked authentication/booking flows, but it declares no explicit tool scope or permissions. That omission weakens least-privilege controls and makes it easier for an agent runtime to grant broader capabilities than the skill actually needs, increasing the blast radius if the skill is misused or compromised.

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

md
Auswertung:

- Wenn `requires_reauth=false`: normal fortfahren.
- Wenn `requires_reauth=true`:
  - Wenn `DESKBIRD_FIREBASE_API_KEY` und `DESKBIRD_FIREBASE_REFRESH_TOKEN` vorhanden sind:
    - zuerst automatisch `./scripts/deskbird.sh auth-refresh --format json --min-valid-minutes 90` ausfuehren.

Static analysis

No suspicious patterns detected.