Back to skill

Security audit

Airtap: Every claw now has a phone

Security checks for vulnerabilities and agentic risk

Overview

The Airtap skill mostly matches its stated purpose, but it needs review because it handles an Airtap access token, can send authenticated task and location data to a configurable endpoint, and logs sensitive details locally.

Review this before installing. Use it only if you trust the Airtap account integration, keep scripts/.env private, avoid setting AIRTAP_BASE_URL away from the official Airtap endpoint unless using separate test credentials, and be aware that task text, routing data, and precise location may be written to /tmp/log. Prefer a locked virtual environment with pinned dependencies and provide location only when the task truly needs it.

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/airtap_common.py:57
Finding

Bearer Token and Sensitive API Payloads Can Be Redirected to an Arbitrary Endpoint

Content
View full analysis
str: return os.environ.get("AIRTAP_BASE_URL", DEFAULT_BASE_URL) ``` ```python def get_auth_headers() -> Dict[str, str]: token = os.environ.get(TOKEN_ENV_VAR) if not token: raise ValueError( f"Missing auth token. Run --add-token or add {TOKEN_ENV_VAR} to .env before running this command." ) return { "Authorization": f"Bearer {token}", "Content-Type": "application/json", PILOT_CLIENT_TYPE_HEADER_NAME: SKILL_CLIENT_TYPE, PILOT_CLIENT_NAME_HEADER_NAME: get_skill_client_name(), } ``` ```python def request_api( logger: logging.Logger, method: str, path: str, *, payload: Optional[Dict[str, Any]] = None, ) -> Dict[str, Any]: logger.info( "Airtap API request method=%s path=%s payload=%s", method, path, json.dumps(summarize_payload(payload), sort_keys=True), ) start_time = time.monotonic() try: response = requests.request( method, f"{get_base_url()}{path}", headers=get_auth_headers(), json=payload, timeout=DEFAULT_TIMEOUT_SECS, ) ``` ### Technical Analysis The API base URL is taken directly from `AIRTAP_BASE_URL` without validating its scheme, hostname, port, or origin. Every API request then attaches the Airtap personal access token as a bearer credential. The Skill loads `scripts/.env` with `override=True`, meaning a value in that file can override an otherwise safe shell environment value. An attacker who can influence the local Skill configuration can therefore redirect authenticated requests from `airtap.ai` to an attacker-controlled serv ...[truncated 1322 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/airtap.py:18
Finding

Sensitive Location and Task Content Is Written to a Predictable Shared Temporary File

Content
View full analysis
logging.Logger: logger = logging.getLogger(name) if logger.handlers: return logger logger.setLevel(logging.INFO) logger.propagate = False log_path.parent.mkdir(parents=True, exist_ok=True) handler = logging.FileHandler(log_path) handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s")) logger.addHandler(handler) return logger ``` ### Technical Analysis The CLI writes logs to the fixed path `/tmp/log`. This name is predictable and resides in a commonly shared temporary directory. The logging implementation does not explicitly enforce owner-only permissions, reject symbolic links, or create the file atomically with safe flags. The log content includes exact latitude and longitude values. It also includes up ...[truncated 1578 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Third-Party Python Dependencies Are Unpinned and Not Hash-Verified

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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (18)

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 32)May include surrounding context.

md
Run commands from the skill directory.

First, sign in to `https://airtap.ai/app`, open Settings, create a personal access token, and copy
it.

Create or update `scripts/.env` with:

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The example command places the personal access token directly on the command line. Command-line secrets can be exposed through shell history, process listings, telemetry, logs, or screenshots, making credential compromise significantly more likely.

Content

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

python3 scripts/airtap.py --add-token "your-personal-access-token"

text

Or copy the template and fill in the personal access token:

```bash
cp scripts/env.example.txt scripts/.env

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The skill instructs storing a personal access token in a local scripts/.env file, and the same document says that file overrides shell environment values. Local plaintext token storage increases the chance of accidental disclosure through repository inclusion, filesystem exposure, logs, backups, or other tooling that reads workspace files.

Content

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

Or copy the template and fill in the personal access token:

bash
cp scripts/env.example.txt scripts/.env

The script loads scripts/.env on startup and values from that file override same-named shell

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

python
SCRIPT_DIR = Path(__file__).resolve().parent
DOTENV_PATH = SCRIPT_DIR / ".env"
LOG_PATH = Path("/tmp/log")
common.load_skill_env(DOTENV_PATH)

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

python
token = os.environ.get(TOKEN_ENV_VAR)
    if not token:
        raise ValueError(
            f"Missing auth token. Run --add-token or add {TOKEN_ENV_VAR} to .env before running this command."
        )

    return {

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

python
token = os.environ.get(TOKEN_ENV_VAR)
    if not token:
        raise ValueError(
            f"Missing auth token. Run --add-token or add {TOKEN_ENV_VAR} to .env before running this command."
        )

    return {

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/airtap_common.py (reported line 127)May include surrounding context.

python
if explicit_client_name:
        return explicit_client_name.lower()

    if any(env_name.startswith("CODEX_") for env_name in os.environ):
        return "codex"

    if any(env_name.startswith("OPENCLAW_") for env_name in os.environ):

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/airtap_common.py (reported line 130)May include surrounding context.

python
if explicit_client_name:
        return explicit_client_name.lower()

    if any(env_name.startswith("CODEX_") for env_name in os.environ):
        return "codex"

    if any(env_name.startswith("OPENCLAW_") for env_name in os.environ):

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares capabilities that imply shell, network, file-read, and environment access but does not explicitly scope or constrain what tools are permitted. That makes misuse or overbroad execution more likely, especially because the skill handles authentication material and can interact with external services.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation description is broad enough to match many generic mobile-app or task-completion requests, which can cause the skill to trigger outside its intended context. Over-activation is risky here because the skill can create tasks, relay messages, and use stored credentials against an external service.

Content

No source excerpt is available for this finding.

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 24)May include surrounding context.

md
for that device.
- `task poll` is local-only by default. Use OpenClaw delivery only when the host explicitly wants
  mirrored updates.
- Do not ask the user to paste tokens into chat. Use preconfigured environment variables or the
  local `scripts/.env` file.
- Never invent OpenClaw targets, thread IDs, reply IDs, or account scopes.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill enables implicit invocation without defining trigger constraints or exclusion conditions, which can cause the agent to activate Airtap operations unexpectedly based on ambiguous user input. In this skill's context, activation can lead to creating, monitoring, cancelling, or updating mobile-app-backed tasks, so an unintended invocation could perform real-world actions or expose task state without a clear, explicit user request.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/airtap.py (reported line 174)May include surrounding context.

python
)

    try:
        subprocess.run(
            command,
            check=True,
            capture_output=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function sends a payload to the /user/v1/userUpdateLocation endpoint, and nearby code shows location fields such as latitude and longitude are recognized and logged in payload summaries. This is a privacy-impacting network operation, but this file provides no confirmation prompt, print/log disclosure to the user, or inline warning explaining that location data will be sent off-device.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency 'requests' is declared without a version pin, which makes builds non-reproducible and can result in installation of a vulnerable or incompatible release. In a skill that interacts with external services and likely handles tokens, network data, or task updates, dependency drift increases supply-chain risk and makes it harder to verify whether known fixes are present.

Content

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

text
requests
python-dotenv

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

The manifest does not pin a version of 'requests', and the package has multiple published advisories, so the deployed environment could resolve to an affected version without visibility. In this Airtap skill context, HTTP client behavior is security-relevant because the skill likely communicates with remote APIs and may expose credentials, request metadata, or task data if an affected release is used.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency 'python-dotenv' is also unpinned, so the installed version may vary across environments and could include vulnerable behavior or breaking changes. Because this package influences environment-variable loading, an unsafe or unexpected version can affect secrets handling and configuration security.

Content

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

text
requests
python-dotenv

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The manifest leaves 'python-dotenv' unpinned despite known advisories affecting some releases, so it is impossible to verify from this file whether the installed version is safe. Since dotenv libraries can read and write configuration files and influence secret loading, a vulnerable version could contribute to configuration tampering, secret exposure, or unsafe file operations depending on usage.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.