Back to skill

Security audit

Bark Notification

Security checks for vulnerabilities and agentic risk

Overview

The skill is a straightforward Bark notification helper, but it can leak task details if users put sensitive information in notifications or logs.

Install only if you are comfortable sending task titles, project names, machine name, status, and short summaries to Bark. Do not include secrets or sensitive incident details in summaries, keep CODEX_BARK_BASE_URL on a trusted HTTPS Bark endpoint, and avoid using --dry-run with a real Bark key in logged environments.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/send_bark_notification.py:93
Finding

Custom Bark endpoint permits plaintext transmission and credential redirection

Content
View full analysis

Vulnerability Details

File Location: scripts/send_bark_notification.py, lines 93-123
Vulnerability Type: Unvalidated notification endpoint and potentially insecure transport
Risk Level: Medium

python
base_url = os.environ.get("CODEX_BARK_BASE_URL", "https://api.day.app")

if not machine_name:
    sys.stderr.write("Missing CODEX_MACHINE_NAME.\n")
    return 1
if not bark_key:
    sys.stderr.write("Missing CODEX_BARK_KEY.\n")
    return 1

task_title = args.task_title.strip()
status = args.status.strip()
summary = args.summary.strip()
if not task_title:
    sys.stderr.write("--task-title must be non-empty.\n")
    return 1
if not summary:
    sys.stderr.write("--summary must be non-empty.\n")
    return 1

project_name = args.project_name or _get_project_name(Path.cwd())

body = "\n".join(
    [
        f"Device: {machine_name}",
        f"Project: {project_name}",
        f"Status: {status}",
        f"Summary: {summary}",
    ]
)

url = f"{base_url.rstrip('/')}/{parse.quote(bark_key)}"
payload = parse.urlencode({"title": task_title, "body": body}).encode("utf-8")

if args.dry_run:
    print("POST", url)
    print("title:", task_title)
    print("body:", body)
    return 0

req = request.Request(url, data=payload, method="POST")
try:
    with request.urlopen(req, timeout=args.timeout) as resp:

Technical Analysis

The CODEX_BARK_BASE_URL environment variable is used directly to construct the destination URL. The implementation does not parse or validate its scheme, hostname, port, embedded credentials, or destination.

Consequently, an http:// value can cause the Bark key, machine name, project name, status, title, and task summary to be transmitted without transport encryption. An attacker who can influence the process environment can also replace the legitimate Bark service with an attacker-controlled endpoint. Percent-encoding bark_key only ...[truncated 1310 chars]

Remediation
View remediation

Remediation Suggestions

Parse CODEX_BARK_BASE_URL with urllib.parse.urlsplit and enforce the following controls before constructing the request:

  1. Require the https scheme and reject plaintext HTTP.
  2. Reject URLs containing embedded usernames or passwords.
  3. Require a non-empty hostname and reject malformed URLs.
  4. Allowlist api.day.app by default. If self-hosted Bark servers are supported, require users to explicitly configure trusted HTTPS hostnames.
  5. Consider rejecting fragments, unexpected query parameters, and nonstandard ports.
  6. Document that the task title and summary leave the local system and must not contain secrets.
  7. Where feasible, keep certificate verification enabled and provide no option to disable it.

A hardened implementation should construct the final URL only after successful validation and should fail closed with a clear error message when the endpoint is not trusted.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/send_bark_notification.py:118
Finding

Dry-run mode prints the Bark credential and notification metadata

Content
View full analysis

Vulnerability Details

File Location: scripts/send_bark_notification.py, lines 118-121
Vulnerability Type: Sensitive information exposure through standard output
Risk Level: Medium

python
if args.dry_run:
    print("POST", url)
    print("title:", task_title)
    print("body:", body)
    return 0

Technical Analysis

The url variable contains CODEX_BARK_KEY as its final path component. Dry-run mode prints that complete URL without redaction. It also prints the title and body, including the configured machine name, resolved project name, execution status, and task summary.

Dry-run output is commonly retained in terminal history, CI/CD logs, agent transcripts, support bundles, or centralized log systems. Although no network request is made in this mode, exposing the credential through standard output expands access to any user or service that can read those logs.

Attack Path

  1. A user or automated validation job invokes the script with --dry-run.
  2. The script constructs a URL containing the real CODEX_BARK_KEY.
  3. The complete URL and notification body are written to standard output.
  4. A terminal recorder, CI log collector, agent transcript, or other logging system stores the output.
  5. An attacker or unauthorized user with access to those records extracts the Bark key.
  6. The attacker uses the key with the Bark API to send unauthorized push notifications to the associated device.

Impact Assessment

Exploitation does not provide local system privileges or code execution. It may disclose the Bark credential, machine identity, project name, task title, status, and summary. Possession of the key can enable unauthorized push notifications and associated phishing or nuisance activity. The metadata disclosure scope depends on the contents supplied by the caller and the accessibility and retention period of captured output.

Remediation
View remediation

Remediation Suggestions

Never print the complete credential-bearing URL. Replace the Bark key with a fixed redaction marker before displaying the dry-run destination, for example:

python
print("POST", f"{base_url.rstrip('/')}/***")

Additional hardening should include:

  1. Print only a sanitized destination hostname rather than the full request URL.
  2. Redact or omit the notification body by default because summaries may contain sensitive information.
  3. Add an explicit option, such as --show-payload, if payload inspection is necessary, accompanied by a warning that the output may be logged.
  4. Ensure errors and debug logging never include the Bark key.
  5. If exposure has already occurred, rotate the affected Bark key and remove it from retained logs where possible.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (4)

Tainted flow: 'req' from os.environ.get (line 127, credential/environment) → urllib.request.urlopen (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 · scripts/send_bark_notification.py (reported line 129)May include surrounding context.

python
req = request.Request(url, data=payload, method="POST")
    try:
        with request.urlopen(req, timeout=args.timeout) as resp:
            response_body = resp.read().decode("utf-8", errors="ignore").strip()
    except error.HTTPError as exc:
        sys.stderr.write(f"HTTP {exc.code}: {exc.reason}\n")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill invokes a local Python script that reads environment variables, reads local files for project name resolution, and sends network requests, but it declares no explicit tool scope or permissions. This creates a least-privilege gap: consumers and enforcement layers cannot easily understand or constrain the skill’s actual capabilities, increasing the chance of unintended data access or exfiltration.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

The skill is designed to transmit task metadata to an external Bark service, including device name, project name, status, and summary. Even though the text says to avoid secrets, summaries and project names can still contain sensitive operational details, so this is a real external data transmission risk in the context of agent task outputs.

Content

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

You can add the following lines to ~/.bashrc (Linux) or ~/.zshrc (macOS) to set environment variables:

text
export CODEX_MACHINE_NAME="Machine-name" # e.g., Macbook
export CODEX_BARK_KEY="" # https://api.day.app/<CODEX_BARK_KEY>/
export CODEX_BARK_BASE_URL="https://api.day.app"

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The skill instructs the agent to generate and send a completion summary after each run, which can persist sensitive session-derived information outside the original execution context via push notification history. The warning to avoid secrets helps, but it is insufficient because model-generated summaries may still include confidential details, filenames, incident context, or other sensitive metadata.

Content

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

md
- Generate a short task title (3-8 words).
- Pick an execution status: `success`, `failed`, `partial`, `blocked`, etc.
- Write a brief result summary; avoid secrets.

Run:

Static analysis

No suspicious patterns detected.