Back to skill

Security audit

Teable

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Teable API management skill, but it grants broad live data-changing authority with weak safety guardrails around deletion, tokens, and custom endpoints.

Install only if you are comfortable giving the skill a Teable token with the exact permissions it can use. Prefer a least-privilege token, avoid storing it in shell startup files, use only trusted HTTPS Teable URLs, and treat delete, trash reset, collaborator, invitation, and plugin commands as live administrative actions that should be reviewed before execution.

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

Error
Location
scripts/teable_base.py:18
Finding

Bearer Token Disclosure and SSRF Through Insufficient Endpoint Validation

Content
View full analysis
str: """ Validate URL to prevent SSRF and credential exfiltration. Args: url: URL to validate Returns: Validated URL Raises: ValueError: If URL is invalid or potentially malicious """ if not url: return url try: parsed = urlparse(url) if parsed.scheme.lower() not in ALLOWED_SCHEMES: raise ValueError( f"Invalid URL scheme: '{parsed.scheme}'. " f"Only {ALLOWED_SCHEMES} are allowed." ) if not parsed.netloc: raise ValueError(f"Invalid URL: missing domain in '{url}'") if parsed.scheme.lower() == "http": print( "WARNING: Using HTTP instead of HTTPS. " "Your API key will be transmitted in plaintext!", file=sys.stderr ) return url.rstrip("/") except Exception as e: raise ValueError(f"Invalid TEABLE_URL '{url}': {e}") ``` The validated URL is then combined with the API path and used in a session that always contains the bearer token: ```python raw_url = base_url or os.getenv("TEABLE_URL") or DEFAULT_BASE_URL self.base_url = validate_url(raw_url) self.api_key = api_key or ...[truncated 3791 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/teable_base.py:62
Finding

Output Directory Restriction Can Be Bypassed Through Prefix Confusion and Symlinks

Content
View full analysis
str: """ Validate output file path to prevent path traversal attacks. Args: path: Output file path base_dir: Base directory (defaults to current working directory) Returns: Absolute path if valid Raises: ValueError: If path attempts directory traversal """ if not path: raise ValueError("Output path cannot be empty") if base_dir is None: base_dir = os.getcwd() abs_base = os.path.abspath(base_dir) abs_path = os.path.abspath(path) if not abs_path.startswith(abs_base): raise ValueError( f"Security error: Output path '{path}' is outside allowed directory. " f"Files can only be written to '{abs_base}' or its subdirectories." ) return abs_path ``` The validated path is opened in write mode during base export: ```python elif args.command == "export": data = client.export_base(args.base_id, include_data=not args.no_data) # Validate output path for security safe_path = validate_output_path(args.output) with open(safe_path, "wb") as f: f.write(data) print(f"Exported to {safe_path}") ``` The same flawed validation is used for record output in `scripts/teable_record.py`: ```python if args.output: # Validate output path for security safe_path = validate_output_path(args.output) with open(safe_path, "w", encoding="utf-8") as f: f.write(output) print(f"Saved to {safe_path}") ``` ### Technical Analysis The code uses a string-prefi ...[truncated 2591 chars]
Remediation
View remediation
str: if not path: raise ValueError("Output path cannot be empty") base = Path(base_dir or os.getcwd()).resolve(strict=True) target = Path(path).resolve(strict=False) try: target.relative_to(base) except ValueError: raise ValueError( f"Output path '{path}' is outside the allowed directory '{base}'" ) return str(target) ``` 2. Alternatively, use `os.path.commonpath()` rather than `startswith()`: ```python if os.path.commonpath([abs_base, abs_path]) != abs_base: raise ValueError("Output path is outside the allowed directory") ``` 3. Resolve and reject symlink components before opening the destination. Where supported, use directory file descriptors and `O_NOFOLLOW` to reduce time-of-check/time-of-use and symlink races. 4. If overwriting is unnecessary, create output files exclusively with mode `"x"` or `O_EXCL`. 5. Restrict output to a dedicated export directory with controlled permissions rather than the caller's current working directory. 6. Add tests for sibling directories with common prefixes, `..` traversal, absolute paths, symlinked files, symlinked directories, and paths changed between validation and opening. ]]>
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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
Findings (29)

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

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

Installation

Prerequisites

Install the required Python package:

bash
pipx install requests
# or globally
pip3 install requests

Environment Variables

Required: Set the TEABLE_API_KEY environment variable before using any scripts:

bash
# Temporary (current shell session)
export TEABLE_API_KEY="your_personal_access_token_here"

# Permanent (add to ~/.bashrc or ~/.zshrc)
echo 'export TEABLE_API_KEY="your_personal_access_token_here"' >> ~/.bashrc
source ~/.bashrc

Getting Your Teable API Token:

  1. Log in to your Teable instance
  2. Go to Settings → Access Token
  3. Create a new Personal Access Token
  4. Copy and save the token (shown only once)

Optional: For self-hosted Teable instances, set TEABLE_URL:

bash
export TEABLE_URL="https://your-teable-instance.com"
# Default: https://app.teable.ai

Usage

Command-Line Scripts

All scripts are located in the scripts/ directory:

bash
# Record operations
python3 scripts/teable_record.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 68)May include surrounding context.

md
**Getting Your Teable API Token**:
1. Log in to your Teable instance
2. Go to Settings → Access Token
3. Create a new Personal Access Token
4. Copy and save the token (shown only once)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
**Getting Your Teable API Token**:
1. Log in to your Teable instance
2. Go to Settings → Access Token
3. Create a new Personal Access Token
4. Copy and save the token (shown only once)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
**Getting Your Teable API Token**:
1. Log in to your Teable instance
2. Go to Settings → Access Token
3. Create a new Personal Access Token
4. Copy and save the token (shown only once)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/teable_base.py list --space-id <spaceId>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/teable_base.py list --space-id <spaceId>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/teable_base.py list --space-id <spaceId>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/teable_base.py list --space-id <spaceId>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/teable_base.py list --space-id <spaceId>

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README advertises full CRUD operations across many resource types, including destructive actions, but does not warn users that commands may modify or delete live Teable data. In an agent skill context, this increases the chance of accidental execution of state-changing operations without adequate user awareness or confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Listing "permanent delete" as supported functionality without an explicit irreversibility warning can lead users or downstream agents to perform data-destroying actions without understanding the consequences. In an automation setting, this is especially risky because destructive capabilities may be invoked programmatically and at scale.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
95% confidence
Finding

Persisting an API key via ~/.bashrc creates session persistence for a secret, causing the credential to be reloaded automatically in every shell. While not malware persistence, it still increases exposure of a sensitive token and can broaden the blast radius if the account or workstation is compromised.

Content

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

Temporary (current shell session)

export TEABLE_API_KEY="your_personal_access_token_here"

Permanent (add to ~/.bashrc or ~/.zshrc)

echo 'export TEABLE_API_KEY="your_personal_access_token_here"' >> ~/.bashrc source ~/.bashrc

text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instructions tell users to persist a personal access token in shell startup files, which can leave long-lived credentials stored in plaintext on disk and automatically loaded into future sessions. This raises the risk of token disclosure through local compromise, shell history mistakes, backups, dotfile syncing, or accidental sharing of configuration files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill documents destructive operations such as delete, reset, and permanent delete with no explicit warning, confirmation step, or note about irreversible data loss. In an automation context, this increases the chance of accidental or scripted mass deletion of records, bases, dashboards, or trash contents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file includes restore, trash reset, and permanent deletion examples, including a 'Permanently delete' command, but does not provide a user warning about the impact on user data or irreversibility. For markdown files, examples that affect data integrity should clearly disclose destructive behavior so users are less likely to run them casually.

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 · references/data-types-and-typecast.md (reported line 440)May include surrounding context.

Method 3: Direct API Call

bash
curl -X POST 'https://app.teable.ai/api/table/tblXXX/record' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The delete_base method performs a DELETE request, including a permanent deletion mode, but the code provides no confirmation step or pre-action warning before carrying out this destructive operation. The later success message is post-action only, so users are not warned before data may be irreversibly removed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code exposes a delete operation that irreversibly removes a dashboard, but the deletion path has no confirmation prompt, warning comment, or other user disclosure near the operation itself. Although the CLI later prints success/failure, that happens only after execution and does not warn the user beforehand.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Removing an installed plugin is a potentially destructive action, yet this function issues the DELETE request without any confirmation prompt or pre-action disclosure. The later success message is not sufficient because it appears only after the removal has already occurred.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The CLI delete path immediately parses record IDs and calls the deletion API, then only prints a success/failure message after the destructive action has already occurred. Although the command name implies deletion, there is no confirmation prompt or explicit user-facing warning before the irreversible operation executes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code claims to validate the URL to prevent SSRF and credential exfiltration, but it only checks that the scheme is HTTP/HTTPS and that a host is present. An attacker who can influence TEABLE_URL or the base_url argument can direct authenticated requests, including the Bearer API key, to an arbitrary external or internal host, causing credential leakage or SSRF against reachable services.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script advertises 'security validations', but its URL validation still allows arbitrary user-controlled HTTP and HTTPS endpoints via TEABLE_URL. Because the client always attaches a bearer token, an attacker who can influence that environment variable can redirect requests to an attacker-controlled server or cause plaintext transmission over HTTP, leading to credential disclosure and misuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The document instructs users to export a personal access token and later suggests echoing the API key for troubleshooting, but it does not warn that the token is sensitive and should not be shared, logged, or exposed in shell history/screenshots. Markdown guidance that involves credentials should disclose privacy and security implications.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The FAQ entry contains the Chinese word "权衡" inside otherwise English documentation. This creates an inconsistent language experience and effectively forces a locale-specific term on readers without offering any language choice or documenting that the content is region-specific.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency is specified as requests>=2.28.0, which allows any future release to be installed and makes builds non-reproducible. This increases supply-chain risk because a vulnerable or breaking upstream version could be pulled in later without review, and it also makes it impossible to reliably verify which version is deployed.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.28.0