Back to skill

Security audit

TapAuth

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real OAuth and secret broker, but it has credential-handling and documentation risks that warrant review before installation.

Review this before installing in environments with valuable OAuth access or shared workspaces. Prefer narrow scopes, avoid the README-style direct token shell examples, keep TAPAUTH_BASE_URL unset outside tests, place TAPAUTH_HOME in a private directory, and revoke grants if the cache or process environment may have been exposed.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tapauth.sh:4
Finding

Configurable API Base URL Can Exfiltrate Cached Grant Credentials

Content
View full analysis
``` to `https://attacker.example/api/v1/grants/`. 6. The attacker uses the captured gr ...[truncated 720 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/tapauth.sh:121
Finding

Unsanitized Provider Name Permits Cache-Path Traversal and File Clobbering

Content
View full analysis
"$env_file" <.env` suffix, but this still allows an attacker to overwrite selected `.env`-style files or create files in writable directories outside the intended cache. The response fields written into the file can also originate from a configurable remote endpoint, increasing the risk when this flaw is combined with endpoint redirection. ### Attack Path 1. An attacker influences the provider argument supplied by an agent, wrapper, automation job, or user-facing workflow. 2. The attacker supplies a traversal value, for ex ...[truncated 1115 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:47
Finding

Documentation Places OAuth Tokens in Process Command-Line Arguments

Content
View full analysis
/cmdline`. Debugging modes such as `set -x` can also record the expanded command. These examples directly contradict `SKILL.md:22` and `SKILL.md:110`, which state that `tapauth.sh --token` must never be used in shell substitutions or piped into `curl`. Because the package presents both instruction sets, agents or users may follow the unsafe examples instead of the OpenClaw secrets-manager flow. ### Attack Path 1. A user or agent follows an example from `README.md` or a provider reference. 2. `tapauth.sh --token` returns a valid OAuth token. 3. The shell expands the token into the `curl` argume ...[truncated 840 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Warning
Location
scripts/check-tapauth-cli.sh:4
Finding

Mutable Remote CLI Is Recommended as an Unsigned Replacement for the Audited Script

Content
View full analysis
&2 echo " curl -fsSL $CLI_URL -o scripts/tapauth.sh && chmod +x scripts/tapauth.sh" >&2 ``` ### Technical Analysis The checker treats the current response from a mutable web URL as the canonical CLI. If the downloaded file differs, it recommends replacing the locally audited `scripts/tapauth.sh` directly and marking the replacement executable. No pinned digest, release signature, transparency-log proof, or version-specific immutable URL is checked. TLS protects transport to the selected host but does not protect against a compromised TapAuth server, compromised release pipeline, malicious DNS/TLS termination environment, or a hostile `TAPAUTH_CLI_URL` override. The checker does not itself execute the downloaded file, but the explicitly recommended update process creates a clear remote-payload execution path: the operator replaces the local script and OpenClaw subsequently executes it as a secrets provider. ### Attack Path 1. An attacker compromises the remote CLI endpoint, its publishing pipeline, or the environment variable used as `TAPAUTH_CLI_URL`. 2. The attacker serves a modified shell script. 3. A maintainer runs `check-tapauth-cli.sh` and receives the suggested replacement command. 4. The maintainer follows the recommendation: ```bash curl -fsSL -o scripts/tapauth.sh && chmod +x scripts/tapauth.sh ``` 5. The modified script is published or installed. 6. OpenClaw executes it during startup or `openclaw secrets reload`. 7. The payload c ...[truncated 764 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/publish-clawhub.sh:43
Finding

Publishing Script Automatically Executes an Unpinned Latest CLI Package

Content
View full analysis
/dev/null; then CLAWHUB_CMD=(clawhub) elif command -v npx &>/dev/null; then CLAWHUB_CMD=(npx -y clawhub@latest) elif [[ "$DRY_RUN" != "true" ]]; then echo "FATAL: clawhub CLI not found and npx is unavailable." exit 1 fi ``` The selected command is later executed: ```bash "${PUBLISH_ARGS[@]}" ``` ### Technical Analysis When a local `clawhub` binary is unavailable, the release script invokes `npx -y clawhub@latest`. The `latest` tag is mutable, and `-y` suppresses the interactive installation confirmation. This means the code executed by the publishing workflow is selected at run time rather than being pinned to a reviewed package version and integrity record. A compromised registry account, malicious release, or package takeover could cause arbitrary JavaScript lifecycle or CLI code to execute in a maintainer or CI environment. This path is developer-facing rather than an automatic package installation lifecycle; `package.json` does not invoke it during normal installation. Nevertheless, release environments commonly hold high-value registry credentials. ### Attack Path 1. An attacker publishes or causes a compromised version of `clawhub` to receive the `latest` tag. 2. A maintainer or CI worker without a preinstalled `clawhub` binary runs `scripts/publish-clawhub.sh`. 3. The script automatically downloads and executes `clawhub@latest` without confirmation. 4. Malicious package or CLI code runs with the publishing process's privileges. 5. The payload steals registry credentials, alters staged Skill content, publishes a backdoored release, or modifies files accessible to the worker. ### Impact Assessment Potential impact includes: - Theft of ClawHub publishing credentials or other CI secrets. - P ...[truncated 283 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:119
Finding

Broad Default Scope Examples Do Not Enforce Least Privilege

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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (84)

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

md
- Consolidated API under /api/v1/ prefix
- Collapsed grant endpoints: GET /api/v1/grants/{id} handles status polling and token retrieval
- .env response format via Accept: text/plain (zero JSON parsing in bash)
- Removed API key requirement — grant_secret is the only credential
- Scopes optional for integration providers (Vercel, Slack, Notion, etc.)
- agent_name optional

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is described as a simple exec secrets provider integration, but the documented workflow actually has the agent create grants, poll for approval, maintain local grant state, and orchestrate secret resolution. That gap matters because users may not realize they are authorizing a broader stateful workflow with browser approval and local cache management.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as a simple exec secrets provider integration, but the documented workflow actually has the agent create grants, poll for approval, maintain local grant state, and orchestrate secret resolution. That gap matters because users may not realize they are authorizing a broader stateful workflow with browser approval and local cache management.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill is described as a simple exec secrets provider integration, but the documented workflow actually has the agent create grants, poll for approval, maintain local grant state, and orchestrate secret resolution. That gap matters because users may not realize they are authorizing a broader stateful workflow with browser approval and local cache management.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill is described as a simple exec secrets provider integration, but the documented workflow actually has the agent create grants, poll for approval, maintain local grant state, and orchestrate secret resolution. That gap matters because users may not realize they are authorizing a broader stateful workflow with browser approval and local cache management.

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

md
- **`command`**: Absolute path to `scripts/tapauth.sh` in this skill directory

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **`command`**: Absolute path to `scripts/tapauth.sh` in this skill directory

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **`command`**: Absolute path to `scripts/tapauth.sh` in this skill directory

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **`command`**: Absolute path to `scripts/tapauth.sh` in this skill directory

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **`command`**: Absolute path to `scripts/tapauth.sh` in this skill directory

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Discord | `["--token", "discord", "identify"]` | `references/discord.md` |

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

md
### Granular Scopes Require Pre-Registration
All scopes must be registered in the [Asana Developer Console](https://app.asana.com/0/developer-console) before use. Requesting an unregistered scope causes an authorization error.

### Short-Lived Access Tokens
Access tokens expire in **1 hour**. TapAuth automatically handles refresh using long-lived refresh tokens.

### API Response Envelope

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

md
### Granular Scopes Require Pre-Registration
All scopes must be registered in the [Asana Developer Console](https://app.asana.com/0/developer-console) before use. Requesting an unregistered scope causes an authorization error.

### Short-Lived Access Tokens
Access tokens expire in **1 hour**. TapAuth automatically handles refresh using long-lived refresh tokens.

### API Response Envelope

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

md
All scopes must be registered in the [Asana Developer Console](https://app.asana.com/0/developer-console) before use. Requesting an unregistered scope causes an authorization error.

### Short-Lived Access Tokens
Access tokens expire in **1 hour**. TapAuth automatically handles refresh using long-lived refresh tokens.

### API Response Envelope
All Asana API responses are wrapped in a `{ data: ... }` envelope:

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

md
All scopes must be registered in the [Asana Developer Console](https://app.asana.com/0/developer-console) before use. Requesting an unregistered scope causes an authorization error.

### Short-Lived Access Tokens
Access tokens expire in **1 hour**. TapAuth automatically handles refresh using long-lived refresh tokens.

### API Response Envelope
All Asana API responses are wrapped in a `{ data: ... }` envelope:

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

md
All scopes must be registered in the [Asana Developer Console](https://app.asana.com/0/developer-console) before use. Requesting an unregistered scope causes an authorization error.

### Short-Lived Access Tokens
Access tokens expire in **1 hour**. TapAuth automatically handles refresh using long-lived refresh tokens.

### API Response Envelope
All Asana API responses are wrapped in a `{ data: ... }` envelope:

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

md
The `guilds` scope returns the user's server (guild) list only — names, icons, and IDs. It does NOT grant access to channels, messages, or members within those servers.

### Token Expiry (~7 Days)
Discord access tokens expire after approximately 7 days. TapAuth handles automatic refresh using the refresh token, so subsequent calls to `$(scripts/tapauth.sh --token discord identify)` return a fresh token without user interaction.

### No Granular Permissions
Discord OAuth scopes are coarse — you can't request "read messages in one channel." The scopes control what user data you can read, not what actions you can take in servers.

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

md
The `guilds` scope returns the user's server (guild) list only — names, icons, and IDs. It does NOT grant access to channels, messages, or members within those servers.

### Token Expiry (~7 Days)
Discord access tokens expire after approximately 7 days. TapAuth handles automatic refresh using the refresh token, so subsequent calls to `$(scripts/tapauth.sh --token discord identify)` return a fresh token without user interaction.

### No Granular Permissions
Discord OAuth scopes are coarse — you can't request "read messages in one channel." The scopes control what user data you can read, not what actions you can take in servers.

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

md
The `guilds` scope returns the user's server (guild) list only — names, icons, and IDs. It does NOT grant access to channels, messages, or members within those servers.

### Token Expiry (~7 Days)
Discord access tokens expire after approximately 7 days. TapAuth handles automatic refresh using the refresh token, so subsequent calls to `$(scripts/tapauth.sh --token discord identify)` return a fresh token without user interaction.

### No Granular Permissions
Discord OAuth scopes are coarse — you can't request "read messages in one channel." The scopes control what user data you can read, not what actions you can take in servers.

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

md
The `guilds` scope returns the user's server (guild) list only — names, icons, and IDs. It does NOT grant access to channels, messages, or members within those servers.

### Token Expiry (~7 Days)
Discord access tokens expire after approximately 7 days. TapAuth handles automatic refresh using the refresh token, so subsequent calls to `$(scripts/tapauth.sh --token discord identify)` return a fresh token without user interaction.

### No Granular Permissions
Discord OAuth scopes are coarse — you can't request "read messages in one channel." The scopes control what user data you can read, not what actions you can take in servers.

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

}

text

TapAuth extracts `authed_user.access_token` as the grant's access token.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/publish-clawhub.sh (reported line 70)May include surrounding context.

sh
# Swap SKILL-OPENCLAW.md → SKILL.md
cp "$TMP_DIR/SKILL-OPENCLAW.md" "$TMP_DIR/SKILL.md"
rm "$TMP_DIR/SKILL-OPENCLAW.md"

echo "  Swapped SKILL-OPENCLAW.md → SKILL.md"

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The script persists TAPAUTH_GRANT_SECRET and grant metadata in a local .env file, then later reads it back to authenticate to the TapAuth service. Even with mode 600 file permissions and a 700 parent directory, storing long-lived bearer-style secrets on disk increases exposure to local compromise, accidental backup/log inclusion, workspace sharing, or reuse by other processes running as the same user; in this skill's context, that is especially sensitive because the tool brokers access to OAuth tokens and user-supplied secrets for many external services.

Content

Scanner excerpt · scripts/tapauth.sh (reported line 141)May include surrounding context.

sh
sorted_scopes=$(echo "$scopes" | tr "," "\n" | sort | tr "\n" "," | sed "s/,$//")
  safe_scopes=$(echo "$sorted_scopes" | tr '/:' '__')
fi
env_file="${TAPAUTH_DIR}/${provider}-${safe_scopes}.env"

TAPAUTH_GRANT_ID="" TAPAUTH_GRANT_SECRET="" TAPAUTH_EXPIRES="" TAPAUTH_APPROVE_URL="" TAPAUTH_STATUS="" TAPAUTH_TOKEN_B64=""
[ -f "$env_file" ] && parse_env_response "$(cat "$env_file")"

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 · tests/mocks/curl (reported line 47)May include surrounding context.

text
printf '%s %s\n' "$method" "$url" >> "${CURL_MOCK_STATE}/calls.log"
printf '%s\n' "${original_args[@]}" > "${CURL_MOCK_STATE}/call-${count}.args"

response="${CURL_MOCK_RESPONSE}/${count}.env"
http_status=200
if [ -f "$response" ]; then
  first_line="$(sed -n '1p' "$response")"

Rp1

Medium
Category
MCP Rug Pull
Confidence
85% confidence
Finding

The README instructs users to run npx skills add tapauth/skill without pinning a specific package version or immutable source. That creates a supply-chain risk because users may fetch whatever package is current at execution time, and if the upstream package or resolution path is compromised, arbitrary code could be installed or run.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.secret_argv_exposure

Instructions pass high-value credentials through process argv.

Critical
Code
suspicious.secret_argv_exposure
Location
SKILL.md:103