Back to skill

Security audit

Tabstack Extractor

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but its recommended dependency install runs a mutable remote script directly in the user's shell and it under-discloses some third-party data and credential handling risks.

Install only if you are comfortable sending target URLs, schemas, and extracted page content to Tabstack. Prefer package-manager installation over the curl-pipe-bash command, use an environment variable or secure credential store instead of a plaintext config file, and avoid using the skill on internal, authenticated, private, or sensitive pages unless you explicitly intend that third-party processing.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:17
Finding

Unverified Remote Installer Piped Directly into Bash

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 17
Vulnerability Type: Remote payload retrieval and execution
Risk Level: Critical

Vulnerable Code:

bash
curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash

Technical Analysis

The installation instructions download a shell script from a mutable upstream branch and execute it immediately. The remote content is not pinned to an immutable release or commit and is not subject to checksum, signature, or manual verification before execution.

The apparent upstream GitHub repository may currently be legitimate, but the effective payload can change after this Skill has been reviewed. Compromise of the repository, maintainer account, upstream branch, or delivery path could therefore convert this instruction into arbitrary code execution. Piping directly to Bash also prevents the user from inspecting the downloaded artifact before it runs.

This behavior is unnecessary for the Skill's minimum operational privileges. Installing a dependency may be legitimate, but executing mutable remote content without verification is not required to install it safely.

Attack Path

  1. An attacker compromises the upstream repository, a maintainer account, or another part of the remote delivery chain.
  2. The attacker modifies the installer served from the mutable master branch.
  3. A user follows the Skill's recommended Quick Start instruction.
  4. curl downloads the attacker-controlled shell content.
  5. Bash executes the content immediately without integrity or authenticity verification.
  6. The payload performs arbitrary actions with the permissions of the user running the command.

Impact Assessment

Successful exploitation provides arbitrary local command execution under the invoking user's account. The payload could read or modify user-accessible files, inspect environment variables and credentials, alter local configurat ...[truncated 389 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the direct curl | bash installation instruction.
  2. Prefer a trusted package manager with version pinning, such as the documented Nix or Homebrew alternatives.
  3. If direct installation is necessary:
    • Pin an immutable release version or commit instead of using master.
    • Download the artifact to a local file without executing it.
    • Verify a publisher-provided cryptographic signature or checksum obtained through a trusted channel.
    • Inspect the downloaded script before execution.
    • Execute it as an unprivileged user and document any permissions it requires.
  4. Use curl --fail --show-error --location so HTTP failures are not silently treated as installer content.
  5. Document the exact dependency version and update process so changes can be reviewed before deployment.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/tabstack_curl.sh:35
Finding

Unsafe JSON Construction from User-Controlled URL Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/tabstack_curl.sh, lines 35–61
Vulnerability Type: Improper encoding of untrusted data in JSON request bodies
Risk Level: Medium

Vulnerable Code:

bash
extract_markdown() {
    local url="$1"
    echo "Extracting markdown from: $url"
    
    curl -s -X POST "${TABSTACK_BASE_URL}/extract/markdown" \
        -H "Authorization: Bearer ${API_KEY}" \
        -H "Content-Type: application/json" \
        -d "{\"url\": \"$url\"}" \
        --max-time 30
}
bash
extract_json() {
    local url="$1"
    local schema_file="$2"
    
    echo "Extracting JSON from: $url"
    echo "Using schema: $schema_file"
    
    # Read schema file
    if [[ ! -f "$schema_file" ]]; then
        echo "Error: Schema file not found: $schema_file"
        exit 1
    fi
    
    local schema
    schema=$(cat "$schema_file")
    
    curl -s -X POST "${TABSTACK_BASE_URL}/extract/json" \
        -H "Authorization: Bearer ${API_KEY}" \
        -H "Content-Type: application/json" \
        -d "{\"url\": \"$url\", \"json_schema\": $schema}" \
        --max-time 30
}

Technical Analysis

The script interpolates the user-supplied url directly into a JSON string without applying JSON encoding. A URL containing quotation marks, backslashes, or control characters can terminate the intended string and alter or invalidate the request body.

For example, an argument shaped like:

text
https://example.com", "additional_field": "attacker-controlled

would be inserted verbatim into the body rather than represented as a single safely encoded JSON string. Depending on the crafted input and the API's duplicate-key and validation behavior, this can add fields, change request semantics, or reliably cause malformed requests.

This is not shell command injection in the current implementation because the expansion occurs inside a ...[truncated 1390 chars]

Remediation
View remediation

Remediation Suggestions

  1. Construct request bodies with a JSON-aware tool rather than string interpolation. For example:
    bash
    payload=$(jq -n --arg url "$url" '{url: $url}')
    curl --fail-with-body --silent --show-error \
      -X POST "${TABSTACK_BASE_URL}/extract/markdown" \
      -H "Authorization: Bearer ${API_KEY}" \
      -H "Content-Type: application/json" \
      --data-binary "$payload"
    
  2. For schema extraction, validate and safely merge the schema:
    bash
    jq -e . "$schema_file" >/dev/null
    payload=$(jq -n \
      --arg url "$url" \
      --slurpfile schema "$schema_file" \
      '{url: $url, schema: $schema[0]}')
    
  3. Use the documented schema property consistently instead of the shell wrapper's json_schema property unless the API explicitly requires otherwise.
  4. Validate that target URLs use an approved scheme such as https.
  5. Use curl --fail-with-body --silent --show-error and check the HTTP status so authentication or validation failures cannot be reported as successful extraction.
  6. Add tests covering quotes, backslashes, Unicode, newlines, and control characters in URL arguments.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (19)

Tainted flow: 'headers' from os.environ.get (line 82, 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 · scripts/tabstack_api.py (reported line 62)May include surrounding context.

python
"schema": schema
    }
    
    response = requests.post(f"{TABSTACK_BASE_URL}/extract/json", 
                           headers=headers, json=payload, timeout=30)
    response.raise_for_status()
    return response.json()

Tainted flow: 'headers' from os.environ.get (line 82, 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 · scripts/tabstack_api.py (reported line 91)May include surrounding context.

python
"url": url
    }
    
    response = requests.post(f"{TABSTACK_BASE_URL}/extract/markdown", 
                           headers=headers, json=payload, timeout=30)
    response.raise_for_status()
    return response.text

Tainted flow: 'headers' from os.environ.get (line 111, credential/environment) → requests.get (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/tabstack_api.py (reported line 117)May include surrounding context.

python
}
        
        # Try a simple request to check authentication
        response = requests.get(f"{TABSTACK_BASE_URL}/", headers=headers, timeout=10)
        return response.status_code == 200
    except Exception:
        return False

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

Piping curl output directly into bash creates an immediate code-execution path from a remote server to the local shell. If the remote content, transport, or repository is compromised, arbitrary commands run with the user's privileges without review.

Content

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

1. Install Babashka (if needed)

bash
# Option A: From GitHub (recommended for sharing)
curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash

# Option B: From Nix
nix-shell -p babashka

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises commands that read environment variables, write/read local files, invoke shell commands, and make network requests, but it does not declare any explicit tool scope or permission boundaries. That increases the chance an agent will invoke it with broader privileges than intended and makes review/auditing harder.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill clearly routes webpage URLs and extracted page content to the external Tabstack service, but it does not prominently disclose that user-supplied targets and possibly sensitive page contents are sent to a third party. This creates privacy and compliance risk, especially if used on private URLs, authenticated content, internal sites, or regulated data.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill recommends storing the API key persistently in ~/.config/tabstack/config.edn, which leaves long-lived credentials on disk. If the host is multi-user, backed up insecurely, or later compromised, the saved token can be recovered and abused for unauthorized API access.

Content

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

Option B: Configuration file

bash
mkdir -p ~/.config/tabstack
echo '{:api-key "your_api_key_here"}' > ~/.config/tabstack/config.edn

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The trigger phrases are broad enough to match many generic scraping or content-extraction requests, so the skill may activate in situations where the user did not intend third-party scraping or external API use. Over-broad activation can cause unanticipated data transfer, unnecessary API calls, or use of this skill in higher-risk contexts without clear consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The reference documents URL fetching, browser automation, and research endpoints that transmit user-supplied targets and possibly page content to an external SaaS, but it does not warn about data egress, privacy, or trust boundaries. In an agent skill, this omission can lead developers to pass sensitive URLs, internal resources, or confidential content to a third party without informed consent or filtering.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This code transmits the caller-provided URL and schema to a third-party API. External transmission is inherent to the feature, but in this skill context it is security-relevant because arbitrary caller data may leave the local trust boundary and be processed by an external provider.

Content

Scanner excerpt · scripts/tabstack_api.py (reported line 62)May include surrounding context.

python
"schema": schema
    }
    
    response = requests.post(f"{TABSTACK_BASE_URL}/extract/json", 
                           headers=headers, json=payload, timeout=30)
    response.raise_for_status()
    return response.json()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The function forwards user-supplied URLs and extraction schemas to a third-party service without any explicit disclosure at the call site. In an agent/skill context, this can cause sensitive internal URLs, tokens embedded in URLs, or proprietary extraction instructions to be transmitted off-platform unexpectedly, creating privacy and data-governance risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The markdown extraction function sends user-controlled URL data to Tabstack over the network. That is expected for the product behavior, but it still represents a real data-transfer risk if users are not aware that requested targets are shared with a third party.

Content

Scanner excerpt · scripts/tabstack_api.py (reported line 91)May include surrounding context.

python
"url": url
    }
    
    response = requests.post(f"{TABSTACK_BASE_URL}/extract/markdown", 
                           headers=headers, json=payload, timeout=30)
    response.raise_for_status()
    return response.text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Markdown extraction sends a user-provided URL to an external service with no point-of-use warning. In a skill environment this can unintentionally disclose browsing targets, internal endpoints, or sensitive query strings to the vendor, which is more dangerous because users may assume the content is fetched locally.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/tabstack_curl.sh (reported line 2)May include surrounding context.

sh
#!/usr/bin/env bash
# Tabstack API wrapper using curl (no Python dependencies)
# Usage: ./tabstack_curl.sh <command> [args]

set -euo pipefail

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 · references/api_reference.md (reported line 5)May include surrounding context.

md
set -euo pipefail

TABSTACK_BASE_URL="https://api.tabstack.ai/v1"
API_KEY="${TABSTACK_API_KEY:-}"

if [[ -z "$API_KEY" ]]; then

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

python
set -euo pipefail

TABSTACK_BASE_URL="https://api.tabstack.ai/v1"
API_KEY="${TABSTACK_API_KEY:-}"

if [[ -z "$API_KEY" ]]; then

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/tabstack_curl.sh (reported line 7)May include surrounding context.

sh
set -euo pipefail

TABSTACK_BASE_URL="https://api.tabstack.ai/v1"
API_KEY="${TABSTACK_API_KEY:-}"

if [[ -z "$API_KEY" ]]; then

External Script Fetching

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The installation instructions fetch a remote script directly from GitHub and execute it locally. Even if the upstream project is legitimate, this pattern exposes users to supply-chain compromise, tampering, or unexpected script changes at install time.

Content

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

1. Install Babashka (if needed)

bash
# Option A: From GitHub (recommended for sharing)
curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash

# Option B: From Nix
nix-shell -p babashka

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring describes endpoints including '/generate/json', '/automate', and '/research', which suggests broader research and browser automation functionality. However, the actual code only implements JSON extraction, markdown extraction, and a connection test, so the documented scope does not match the code's real behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.