Back to skill

Security audit

Tool Connector

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly coherent with its tool-connection purpose, but it handles powerful user credentials in ways users should review carefully before installing.

Install only if you are comfortable giving the agent user-equivalent access to the listed tools. Prefer narrowly scoped tokens, avoid copying browser-session JWTs where possible, remove insecure TLS bypasses before use, protect or replace plaintext credential files with a secret store, and rotate any tokens whose prefixes may have appeared in logs.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/shared_utils/playwright_sso.py:87
Finding

Credential Transmission with TLS Certificate Verification Disabled

Content
View full analysis
int: """Make a GET request and return the HTTP status code.""" try: import ssl req = urllib.request.Request(url, headers=headers) ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE with urllib.request.urlopen(req, context=ctx, timeout=8) as resp: return resp.status ``` From `scripts/shared_utils/playwright_sso.py:157-168`: ```python req = urllib.request.Request( "https://slack.com/api/auth.test", headers={"Authorization": f"Bearer {slack_xoxc}"}, ) ctx2 = ssl.create_default_context() ctx2.check_hostname = False ctx2.verify_mode = ssl.CERT_NONE with urllib.request.urlopen(req, context=ctx2, timeout=8) as resp: body = _json.loads(resp.read()) result["slack_xoxc"] = body.get("ok") is True ``` From `scripts/shared_utils/browser.py:104-116`: ```python def http_get(url: str, headers: dict) -> int: """Make a GET request and return the HTTP status code.""" import ssl try: req = urllib.request.Request(url, headers=headers) ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE with urllib.request.urlopen(req, context=ctx, timeout=8) as resp: return resp.status ``` The same behavior appears in documented executable examples, including: - `references/tool_connections/jira/connection-api-token.md:46-47, 65-66` - `references/too ...[truncated 3288 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/openclaw_sync.py:102
Finding

Bearer Tokens and Session Credentials Are Partially Disclosed Through Standard Output

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/shared_utils/playwright_sso.py:397
Finding

Plaintext Session Credentials Are Written Without Enforcing Restrictive File Permissions

Content
View full analysis
None: """Write / update token values in .env file.""" if not env_path.exists(): env_path.write_text("") content = env_path.read_text() def _upsert(text: str, key: str, value: str, section_hint: str) -> str: pattern = rf"^({re.escape(key)}=).*$" new_line = f"{key}={value}" if re.search(pattern, text, flags=re.MULTILINE): return re.sub(pattern, new_line, text, flags=re.MULTILINE) if section_hint and section_hint in text: return re.sub( rf"({re.escape(section_hint)}[^\n]*\n)", r"\1" + new_line + "\n", text, ) return text + f"\n{new_line}\n" # Token upsert operations omitted for brevity. env_path.write_text(content) print(f" Updated {env_path}") ``` From `scripts/openclaw_sync.py:72-75`: ```python def write_openclaw_config(path: Path, config: dict) -> None: """Write config back as JSON (pretty-printed).""" path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(config, indent=2) + "\n") ``` ### Technical Analysis The Skill stores captured credentials in several plaintext locations: - `~/.openclaw/tool-connector.env` - `~/.openclaw/openclaw.json` - `~/.browser_automation/gdriv ...[truncated 1670 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/shared_utils/playwright_sso.py:44
Finding

Importing Utility Modules Automatically Installs Unpinned Remote Dependencies

Content
View full analysis
Remediation
View remediation
--hash=sha256: ``` 5. Pin and review the corresponding Chromium revision. 6. Use a trusted package index configured over verified TLS, and prohibit fallback to untrusted mirrors. 7. Perform installation in an isolated virtual environment with minimum filesystem privileges. 8. Generate a software bill of materials and run dependency vulnerability checks during release. 9. If programmatic installation is unavoidable, use `subprocess.run([...], check=True)` without a shell and only after explicit user confirmation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (213)

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The setup flow prepares a .env file specifically to hold credentials for multiple external tools, which is credential collection and local secret persistence by design. In the context of an agent skill, this is especially sensitive because the same instructions also encourage broad connection setup across Slack, Jira, GitHub, email, and observability tools, concentrating high-value secrets in one location.

Content

Scanner excerpt · references/setup.md (reported line 53)May include surrounding context.

python3 -m venv .venv && source .venv/bin/activate pip install playwright && playwright install chromium

Create .env (empty — fill from each tool's setup.md as you connect)

touch .env

text

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The touch .env step operationalizes creation of a plaintext secrets file, making credential capture a concrete part of the setup process rather than an incidental mention. Because this skill is intended for an agent to execute, it normalizes creating a reusable local secret cache that could be leaked via logs, backups, repo commits, or compromise of the working directory.

Content

Scanner excerpt · references/setup.md (reported line 54)May include surrounding context.

pip install playwright && playwright install chromium

Create .env (empty — fill from each tool's setup.md as you connect)

touch .env

text

---

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
60% 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 · references/tool_connections/artifactory/connection-api-token.md (reported line 99)May include surrounding context.

md
# → {"results_count": 2, "sample": ["https://.../{artifact-name}-1.1.0.whl", ...]}

# Download an artifact
curl -s -H "Authorization: Basic $AUTH" \
  "$BASE/artifactory/{repo-key}/{package-name}/1.1.0/my_package-1.1.0.tar.gz" \
  -o my_package.tar.gz
# → downloads to my_package.tar.gz

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/tool_connections/artifactory/connection-api-token.md (reported line 109)May include surrounding context.

md
## Notes

- **API key vs access token:** Older instances expose a per-user API key under Edit Profile. Artifactory 7.21+ also has scoped Access Tokens (Administration → Identity and Access → Access Tokens). Either works with Basic auth as `user:key`. API keys generated under Edit Profile are non-expiring. Access tokens can have a TTL — check the expiry field when generating.
- **`sort -V`:** Version sort (`sort -V`) handles semver correctly — `1.9.0` before `1.10.0`. Plain `sort` will mis-order.
- **packageType values:** `Generic`, `Maven`, `Gradle`, `Npm`, `PyPI`, `Docker`, `Helm`, `YUM`, `Debian`, etc.
- **SSL:** Enterprise instances often use internal CAs — add `-k` to curl if you see SSL errors.

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/tool_connections/artifactory/connection-api-token.md (reported line 109)May include surrounding context.

md
## Notes

- **API key vs access token:** Older instances expose a per-user API key under Edit Profile. Artifactory 7.21+ also has scoped Access Tokens (Administration → Identity and Access → Access Tokens). Either works with Basic auth as `user:key`. API keys generated under Edit Profile are non-expiring. Access tokens can have a TTL — check the expiry field when generating.
- **`sort -V`:** Version sort (`sort -V`) handles semver correctly — `1.9.0` before `1.10.0`. Plain `sort` will mis-order.
- **packageType values:** `Generic`, `Maven`, `Gradle`, `Npm`, `PyPI`, `Docker`, `Helm`, `YUM`, `Debian`, etc.
- **SSL:** Enterprise instances often use internal CAs — add `-k` to curl if you see SSL errors.

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/tool_connections/artifactory/connection-api-token.md (reported line 109)May include surrounding context.

md
## Notes

- **API key vs access token:** Older instances expose a per-user API key under Edit Profile. Artifactory 7.21+ also has scoped Access Tokens (Administration → Identity and Access → Access Tokens). Either works with Basic auth as `user:key`. API keys generated under Edit Profile are non-expiring. Access tokens can have a TTL — check the expiry field when generating.
- **`sort -V`:** Version sort (`sort -V`) handles semver correctly — `1.9.0` before `1.10.0`. Plain `sort` will mis-order.
- **packageType values:** `Generic`, `Maven`, `Gradle`, `Npm`, `PyPI`, `Docker`, `Helm`, `YUM`, `Debian`, etc.
- **SSL:** Enterprise instances often use internal CAs — add `-k` to curl if you see SSL errors.

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/tool_connections/artifactory/setup.md (reported line 3)May include surrounding context.

md
---
name: artifactory-setup
description: Set up Artifactory connection. API key or access token + Basic auth. Ask for Artifactory URL and credentials.
---

# Artifactory — Setup

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/tool_connections/artifactory/setup.md (reported line 20)May include surrounding context.

md
---
name: artifactory-setup
description: Set up Artifactory connection. API key or access token + Basic auth. Ask for Artifactory URL and credentials.
---

# Artifactory — Setup

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/tool_connections/artifactory/connection-api-token.md (reported line 30)May include surrounding context.

md
- "Your Artifactory username"
- "Your Artifactory API key or access token":
  - API key: Artifactory UI → top-right user icon → Edit Profile → Authentication Settings → Generate API Key
  - Access token (7.21+): Administration → Identity and Access → Access Tokens → Generate Token

---

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/tool_connections/artifactory/setup.md (reported line 22)May include surrounding context.

md
- "Your Artifactory username"
- "Your Artifactory API key or access token":
  - API key: Artifactory UI → top-right user icon → Edit Profile → Authentication Settings → Generate API Key
  - Access token (7.21+): Administration → Identity and Access → Access Tokens → Generate Token

---

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/tool_connections/artifactory/setup.md (reported line 59)May include surrounding context.

md
- "Your Artifactory username"
- "Your Artifactory API key or access token":
  - API key: Artifactory UI → top-right user icon → Edit Profile → Authentication Settings → Generate API Key
  - Access token (7.21+): Administration → Identity and Access → Access Tokens → Generate Token

---

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/tool_connections/artifactory/setup.md (reported line 22)May include surrounding context.

md
- "Your Artifactory username"
- "Your Artifactory API key or access token":
  - API key: Artifactory UI → top-right user icon → Edit Profile → Authentication Settings → Generate API Key
  - Access token (7.21+): Administration → Identity and Access → Access Tokens → Generate Token

---

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The use of curl with the -k flag disables TLS certificate verification, allowing a man-in-the-middle attacker on the network path to impersonate the Backstage server and capture the Bearer token or modify responses. Because this is shown as a normal verification command, it can train users to bypass transport security for authenticated requests.

Content

Scanner excerpt · references/tool_connections/backstage/connection-api-token.md (reported line 62)May include surrounding context.

bash
source .env

curl -s -k "$BACKSTAGE_BASE_URL/api/catalog/entity-facets?facet=kind" \
  -H "Authorization: Bearer $BACKSTAGE_TOKEN" \
  | jq '.facets.kind'
# → [{"value": "Component", "count": 1154}, {"value": "Group", "count": 4373}, {"value": "User", "count": 28244}, ...]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

This authenticated request also disables TLS verification with -k, which undermines the confidentiality and integrity of the Bearer token and returned catalog data. In an enterprise environment, Backstage often contains sensitive ownership and infrastructure metadata, so interception risk is meaningful.

Content

Scanner excerpt · references/tool_connections/backstage/connection-api-token.md (reported line 78)May include surrounding context.

md
BASE="$BACKSTAGE_BASE_URL"

# Entity kinds and counts — good sanity check
curl -s -k "$BASE/api/catalog/entity-facets?facet=kind" \
  -H "Authorization: Bearer $BACKSTAGE_TOKEN" \
  | jq '.facets.kind'
# → [{"value": "Component", "count": 1154}, {"value": "Domain", "count": 15}, {"value": "Group", "count": 4373}, {"value": "System", "count": 65}, ...]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The -k flag on a query that enumerates services encourages insecure authenticated access and exposes the token to interception if DNS, proxy, or network paths are compromised. It also weakens trust in returned catalog data that may drive later operational decisions.

Content

Scanner excerpt · references/tool_connections/backstage/connection-api-token.md (reported line 84)May include surrounding context.

md
# → [{"value": "Component", "count": 1154}, {"value": "Domain", "count": 15}, {"value": "Group", "count": 4373}, {"value": "System", "count": 65}, ...]

# List services (first 3, sparse fieldset — faster for large catalogs)
curl -s -k "$BASE/api/catalog/entities/by-query?filter=kind=component,spec.type=service&limit=3&fields=metadata.name,spec.owner,spec.lifecycle" \
  -H "Authorization: Bearer $BACKSTAGE_TOKEN" \
  | jq '{totalItems, items: [.items[] | {name: .metadata.name, owner: .spec.owner, lifecycle: .spec.lifecycle}]}'
# → {"totalItems": 850, "items": [{"name": "my-service", "owner": "group:platform-team", "lifecycle": "production"}, ...]}

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

Disabling certificate verification while retrieving exact entity data permits token theft and response tampering by an active network attacker. Because the endpoint may expose linked annotations to other systems, tampered data could also misdirect users to malicious downstream resources.

Content

Scanner excerpt · references/tool_connections/backstage/connection-api-token.md (reported line 90)May include surrounding context.

md
# → {"totalItems": 850, "items": [{"name": "my-service", "owner": "group:platform-team", "lifecycle": "production"}, ...]}

# Get a single component by exact name
curl -s -k "$BASE/api/catalog/entities/by-name/component/default/{service-name}" \
  -H "Authorization: Bearer $BACKSTAGE_TOKEN" \
  | jq '{name: .metadata.name, type: .spec.type, owner: .spec.owner, lifecycle: .spec.lifecycle, annotations: .metadata.annotations}'
# → {"name": "my-service", "type": "service", "owner": "group:platform-team", "lifecycle": "production", "annotations": {...}}

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

Using -k on user lookup requests exposes both the Bearer token and potentially sensitive user profile information to interception or manipulation. In an internal developer portal context, user and group metadata can materially aid reconnaissance and social engineering.

Content

Scanner excerpt · references/tool_connections/backstage/connection-api-token.md (reported line 96)May include surrounding context.

md
# → {"name": "my-service", "type": "service", "owner": "group:platform-team", "lifecycle": "production", "annotations": {...}}

# User lookup by username
curl -s -k "$BASE/api/catalog/entities/by-name/user/default/{username}" \
  -H "Authorization: Bearer $BACKSTAGE_TOKEN" \
  | jq '{name: .metadata.name, email: .spec.profile.email, displayName: .spec.profile.displayName, memberOf: .spec.memberOf}'
# → {"name": "alice", "email": "alice@example.com", "displayName": "Alice Smith", "memberOf": ["group:platform-team"]}

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The example disables certificate validation while querying group membership data, which can leak sensitive organizational information and the access token to a man-in-the-middle. Group membership and ownership mappings are valuable internal reconnaissance targets.

Content

Scanner excerpt · references/tool_connections/backstage/connection-api-token.md (reported line 102)May include surrounding context.

md
# → {"name": "alice", "email": "alice@example.com", "displayName": "Alice Smith", "memberOf": ["group:platform-team"]}

# Group lookup by name
curl -s -k "$BASE/api/catalog/entities/by-name/group/default/{group-name}" \
  -H "Authorization: Bearer $BACKSTAGE_TOKEN" \
  | jq '{name: .metadata.name, members: .spec.members[:5]}'
# → {"name": "platform-team", "members": ["alice", "bob", "carol"]}

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

This facet query still sends an Authorization header while TLS verification is disabled, leaving the token and response vulnerable to interception and tampering. Even aggregate metadata can help an attacker map the internal environment.

Content

Scanner excerpt · references/tool_connections/backstage/connection-api-token.md (reported line 108)May include surrounding context.

md
# → {"name": "platform-team", "members": ["alice", "bob", "carol"]}

# Component type breakdown (facet)
curl -s -k "$BASE/api/catalog/entity-facets?facet=spec.type&filter=kind=component" \
  -H "Authorization: Bearer $BACKSTAGE_TOKEN" \
  | jq '{"spec.type": .facets["spec.type"]}'
# → {"spec.type": [{"value": "service", "count": 850}, {"value": "resource", "count": 200}, {"value": "library", "count": 104}, ...]}

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The annotation enumeration request combines authenticated access with disabled TLS verification, risking token compromise and exposure of integration metadata such as GitHub, PagerDuty, or source-location links. Those annotations can materially increase attack surface by revealing connected systems.

Content

Scanner excerpt · references/tool_connections/backstage/connection-api-token.md (reported line 129)May include surrounding context.

Check what annotations your instance uses:

bash
curl -s -k "$BACKSTAGE_BASE_URL/api/catalog/entities/by-query?filter=kind=component&limit=3" \
  -H "Authorization: Bearer $BACKSTAGE_TOKEN" \
  | jq '.items[].metadata.annotations | keys'

Ssd 3

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Directing the user to obtain an SSO JWT from browser local storage and paste it into the workflow is a credential-harvesting pattern. In this skill context, the token is a live bearer credential that may allow API access equivalent to the user's Backstage session, making the guidance especially dangerous.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The setup asks the user to paste a Backstage token and save it in .env, which encourages disclosure of bearer credentials to the agent and storage in a commonly mishandled file. This is particularly risky because .env files are often left readable on disk, loaded into subprocesses, or accidentally committed to repositories.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The verification command uses curl with -k, which disables TLS certificate validation. That permits man-in-the-middle interception of the HTTPS connection and exposure of the Authorization bearer token, making this more dangerous in a setup flow that already relies on highly sensitive credentials.

Content

Scanner excerpt · references/tool_connections/backstage/setup.md (reported line 44)May include surrounding context.

bash
source .env
curl -s -k "$BACKSTAGE_BASE_URL/api/catalog/entity-facets?facet=kind" \
  -H "Authorization: Bearer $BACKSTAGE_TOKEN" \
  | jq '.facets.kind'
# → [{"value": "Component", "count": 1154}, {"value": "Group", "count": 4373}, ...]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

The curl -k option disables certificate validation for an authenticated request carrying a bearer token. In a corporate/internal deployment context, this is especially dangerous because users may routinely run it against internal networks where TLS interception, misconfiguration, or spoofed services could capture the token and feed back falsified repository data.

Content

Scanner excerpt · references/tool_connections/bitbucket-server/connection-api-token.md (reported line 52)May include surrounding context.

md
source .env
BASE="$BITBUCKET_BASE_URL/rest/api/1.0"

curl -s -k -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/profile/recent/repos?limit=3" \
  | jq '.values[] | {slug, name, project: .project.key}'
# → [{"slug": "my-repo", "name": "My Repo", "project": "MYPROJ"}, ...]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

This authenticated repo-history request uses curl -k, allowing a spoofed endpoint to impersonate the Bitbucket server and harvest the bearer token. Because it accesses personal recent-repo history, it also exposes sensitive metadata about internal projects even if content is not fetched.

Content

Scanner excerpt · references/tool_connections/bitbucket-server/connection-api-token.md (reported line 68)May include surrounding context.

md
BASE="$BITBUCKET_BASE_URL/rest/api/1.0"

# Recently accessed repos (personal history — good starting point)
curl -s -k -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/profile/recent/repos?limit=5" \
  | jq '.values[] | {slug, name, project: .project.key}'
# → [{"slug": "my-repo", "name": "My Repo", "project": "MYPROJ"}, ...]

Static analysis

Detected: suspicious.generated_source_template_injection, suspicious.insecure_tls_verification

User-controlled placeholder is embedded directly into generated source code.

Critical
Code
suspicious.generated_source_template_injection
Location
references/tool_connections/grafana/connection-sso.md:81

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
scripts/shared_utils/browser.py:111

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
scripts/shared_utils/playwright_sso.py:94