Back to skill

Security audit

skill-hub-query

Security checks for vulnerabilities and agentic risk

Overview

This skill is a legitimate Skill Hub manager, but it needs review because it can install remote skills into auto-loaded agent directories and has credential and path-handling weaknesses.

Install only if you trust the configured Hub and understand that installed packages can affect future agent sessions. Prefer least-privilege Hub tokens, avoid storing broad tokens in shell startup files, and review downloaded skills before enabling them. Treat edit and team commands as administrative actions requiring explicit human approval.

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

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install.sh:158
Finding

Unverified Remote Skill Packages Are Installed into Agent Auto-Load Directories

Content
View full analysis
&2 exit 6 elif [[ "$zip_status" -ne 0 ]]; then echo "[error] extraction failed (corrupt or truncated zip); existing install untouched." >&2 exit 1 fi ``` ```bash # scripts/install.sh:249-266 if [[ -n "$actual_version" && "$actual_version" != "$VERSION" ]]; then echo "[warn] version mismatch: requested v${VERSION}, but the package's SKILL.md says v${actual_version}" >&2 echo " The Hub's download endpoint may have served a different version than requested." >&2 echo " Recording the actual version v${actual_version}." >&2 echo " If you need an exact version, pin it: bash install.sh ${SLUG} (then re-check)." >&2 VERSION="$actual_version" fi echo "[install] installing to $INSTALL_DIR" backup_dir="" if [[ -d "$INSTALL_DIR" ]]; then backup_dir="${INSTALL_DIR}.bak.$$" mv "$INSTALL_DIR" "$backup_dir" fi if ! mv "$src_dir" "$INSTALL_DIR"; then ``` ```bash # scripts/install.sh:290-296 if [[ -d "$INSTALL_DIR/references" ]]; then echo " - references/ ($(find "$INSTALL_DIR/references" -type f | wc -l) files)" fi echo "" echo " The skill will be loaded on the next agent ...[truncated 2514 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_lib.sh:688
Finding

Authentication Header Can Be Forwarded to a Cross-Origin Download Redirect

Content
View full analysis
/dev/null)"; then local hdr scheme hdr="$(load_auth_header)" scheme="$(load_auth_scheme)" curl_opts+=(-H "${hdr}: ${scheme}${token}") else show_legacy_notice fi local http_code if ! http_code="$(curl "${curl_opts[@]}" "$url" 2>/dev/null)"; then echo "[error] Download failed: ${slug} (network error, check connectivity)" >&2 rm -f "$out" exit 3 fi ``` ### Technical Analysis The download request combines `curl -L`, which follows redirects, with an authentication header supplied through `-H`. The implementation does not inspect redirect targets, enforce a same-origin policy, or remove the custom authentication header when the destination host changes. Custom headers may be applied to redirected requests. Therefore, a Hub-controlled redirect can cause the token to be sent to an origin other than the configured Hub. This is especially significant because the authentication header name and scheme are configurable, preventing reliance on special handling for one standard authentication mechanism. TLS does not mitigate this issue when the redirect destination is an attacker-controlled HTTPS server: TLS protects delivery to that server but does not prevent the server from reading the credential. ### Attack Path 1. A user has a valid `SKILL_HUB_TOKEN` in the environment or credentials file. 2. The installer requests an authenticated package download from the configured Hub. 3. A malicious or compromised Hub responds with a redirect to an attacker-controlled HTTPS or ...[truncated 790 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/edit.sh:178
Finding

Unvalidated Skill Slug Is Used in Authenticated Metadata-Edit URLs

Content
View full analysis
" >&2 usage 1 fi # Fail-fast if Hub URL is not configured (before any user-facing step output). require_hub_url || exit $? # ---------- Step 1: GET current snapshot ---------- echo "" echo "[edit] target slug: $SLUG" echo "[edit] Hub URL : $(load_endpoint)" echo "" echo "[1/5] fetching current state (GET)..." SNAPSHOT=$(fetch_skill_snapshot "$SLUG") || exit 1 ``` ```bash # scripts/_edit_lib.sh:61-69 fetch_skill_snapshot() { local slug="$1" local -a auth_args mapfile -t auth_args < <(_auth_curl_args) local resp resp=$(curl -sS --max-time 30 -X PUT "$(_edit_endpoint_tmpl)/${slug}" \ -H "Content-Type: application/json" \ "${auth_args[@]}" \ -d '{}' 2>&1) || { ``` ```bash # scripts/_edit_lib.sh:220-231 apply_patch() { local slug="$1" local patch_json="$2" local -a auth_args mapfile -t auth_args < <(_auth_curl_args) local resp resp=$(curl -sS --max-time 30 -X PUT "$(_edit_endpoint_tmpl)/${slug}" \ -H "Content-Type: application/json" \ "${auth_args[@]}" \ -d "$patch_json" 2>&1) || { echo "[error] PUT call failed: network error" >&2 return 1 } ``` ### Technical Analysis `install.sh` validates Skill slugs with `validate_slug`, but `edit.sh` does not perform the same validation before using the slug as a URL path component. Shell quoting prevents command injection, but it does not make an untrusted value safe as part of a URL. Characters such as `/`, `..`, `?`, and `#` can change path interpretation, add query parameters, or alter the effective request target. The affected requests are authenticated when a token is configured and use `PUT`. Exploitability against a spec ...[truncated 1754 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_zip_safe.py:148
Finding

ZIP Extraction Lacks Entry Count and Uncompressed-Size Limits

Content
View full analysis
/dev/null || stat -f %z "$tmp_zip")" echo "[install] zip size: $zip_size bytes" echo "[install] verifying zip paths and extracting..." staging="$(shq_mktemp -d shq-install-staging)" set +e python3 "${SELF_DIR}/_zip_safe.py" extract "$tmp_zip" "$staging" zip_status=$? set -e if [[ "$zip_status" -eq 6 ]]; then echo "[error] zip contains unsafe paths; refusing to extract (existing install untouched)." >&2 exit 6 elif [[ "$zip_status" -ne 0 ]]; then echo "[error] extraction failed (corrupt or truncated zip); existing install untouched." >&2 exit 1 fi ``` ```python # scripts/_zip_safe.py:148-190 infos = zf.infolist() names = [_decoded_name(i) for i in infos] bad = _unsafe(names) if bad: print("[error] zip contains unsafe paths; refusing to extract:", file=sys.stderr) for b in bad: print(b, file=sys.stderr) return 6 for n in names: target = (dest / n).resolve() if target != dest and dest not in target.parents: print(f"[error] extraction target escapes dest: {n}", file=sys.stderr) return 6 written: list[Path] = [] for info, name in zip(infos, names): target = dest / name if info.is_dir() or name.endswith('/'): target.mkdir(parents=True, exist_ok=True) continue target.parent.mkdir(parents=True, exist_ok=True) try: with zf.open(info) as src, open(target, 'wb') as out: written.append(target) while True: chunk = src.read(65536) if not chunk: break out.write(chunk) ``` ### Technical Analysis The extractor correctly checks path traversal and resolves destinations befo ...[truncated 1947 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (64)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · CHANGELOG.md (reported line 84)May include surrounding context.

md
Taking `max()` of the two makes the computed age collapse to ~0 whenever the
  hub has recent activity — so "local cache 67 days stale + hub updated
  yesterday" produced **no warning at all**, exactly the case the warning exists
  for. Age is now derived from `lastFullSync` only, falling back to the cache
  file's `mtime` when it is absent or `0` (i.e. only incremental syncs have run);
  `mtime` is also a local clock, so it is semantically safe.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · scripts/query.sh (reported line 208)May include surrounding context.

sh
Taking `max()` of the two makes the computed age collapse to ~0 whenever the
  hub has recent activity — so "local cache 67 days stale + hub updated
  yesterday" produced **no warning at all**, exactly the case the warning exists
  for. Age is now derived from `lastFullSync` only, falling back to the cache
  file's `mtime` when it is absent or `0` (i.e. only incremental syncs have run);
  `mtime` is also a local clock, so it is semantically safe.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The supplied code chunk only implements the edit subsystem, not the full hub-management feature set described. It does support metadata editing with diffing, backup retention, post-write verification, owner pre-checks, and rollback, so part of the description is accurate. However, the declared purpose claims substantial additional capabilities—querying/searching/new listings, install/update, version history, and team member management—that are absent from this code. Also, the detailed edit-flow description does not precisely match the code: the authoritative pre-edit snapshot is fetched using PUT /edit/ with an empty body rather than GET, and writes are performed with PUT, despite comments mentioning PATCH in places. Because the description materially overstates what this code chunk does, this chunk is a mismatch relative to the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a comprehensive Skill Hub client/manager. The actual code chunk does not implement hub communication or management features at all. Instead, it is a helper script for ZIP archive handling: correcting filename encoding issues, listing entries, extracting files safely, preventing directory traversal, and preserving executable bits. While ZIP extraction could be a supporting implementation detail for installing skills, this chunk by itself is materially different from the declared primary purpose and exposes a distinct file-archive utility capability not represented in the description. Therefore this is a clear description/behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The supplied code chunk is specifically a doctor.sh diagnostic script. Its primary function is to assess whether the environment is correctly configured: required tools are installed, endpoints and tokens are set, OpenAPI/legacy connectivity works, the edit endpoint is mounted, ZIP filename handling works, and cache files exist. While these checks support the broader skill ecosystem, they do not themselves carry out the declared end-user capabilities such as searching hubs, installing/updating skills, editing metadata with rollback, or team member management. The declared description portrays the skill as a full operational Skill Hub manager, but this code chunk is a health-check utility. That is a material purpose mismatch, not merely an implementation detail.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The supplied code does accurately implement the declared editing flow portion of the description, including GET -> diff -> backup -> PUT -> verify -> rollback behavior and safety checks around visibility changes and ownership. However, the declared purpose describes a much broader multi-function skill covering query/search, listing newly published skills, version history inspection, install/update operations, and team member management. None of those capabilities are present in this code chunk. Since the task is to compare the description against the supplied code chunk itself, the description materially overstates what this specific code does. There are no obvious unrelated or dangerous undeclared behaviors beyond the stated editing functionality, but there is still a mismatch because the actual behavior is only one subset of the declared skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description describes a broad Skill Hub administration/query skill with search, listing, metadata editing, version-history viewing, and team membership management. The supplied code chunk only implements an install/update script for one skill. It validates a slug, resolves a version, downloads a package, performs ZIP safety checks, stages and swaps directories, and records the installed version locally. While this does align with one subset of the declaration (install/upgrade a skill), the vast majority of the described capabilities are absent from this code chunk. There is no evidence here of hub querying, search by keyword/author/time/source, card editing, version-history display, or team member management. Therefore the description materially overstates what this code actually does, making it a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description substantially overstates the code’s functionality. This script is a query utility only: it validates arguments, warns about stale local cache, parses time ranges, filters cached JSON with jq, and for one provider performs live read-only search/detail/version requests. There are no write paths, no install/update logic, no metadata editing flow, no team-management operations, and no token-based authenticated channel shown. While some declared query-related features are present (keyword/author/time/slug/combo search, limited recent browsing, provider-specific version inspection), the primary declared purpose is a broad hub management skill, whereas the supplied code chunk is narrowly read-only and mostly local-cache based. That is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a broad Skill Hub client/manager with user-facing operations for search, installation, metadata editing, version history, and team membership management. The actual code chunk is narrowly focused on maintaining a local cache of hub search results via full or incremental sync. Its primary purpose is operational cache refresh, not user-requested hub management. While syncing could be a supporting detail for a query feature, the supplied code does not implement most of the declared capabilities, and its trigger/comment 'skill-hub-query: cache sync' is much narrower than the declared trigger set. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

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

| Path prefix for team endpoints (team.sh only) | | SKILL_HUB_DISABLE_TEAM | 0 | Set to 1 to disable team.sh when your Hub does not implement the team endpoints |

Skills install directory

Resolved in order: SKILL_HUB_SKILLS_DIR -> ~/.claude/skills/ -> ~/.openclaw/workspace/skills/ -> ~/.config/skills/ (first existing wins).

Setting up Hub URL + token (one-time)

bash
echo 'export SKILL_HUB_URL="https://hub.your-company.com"' >> ~/.bashrc
echo 'export SKILL_HUB_TOKEN="<your-token>"' >> ~/.bashrc
source ~/.bashrc

Or — for richer per-Hub profiles — use the credentials file:

bash
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/skill-hub-query"
cat > "${XDG_CONFIG_HOME:-$HOME/.config}/skill-hub-query/credentials.json" <<EOF
{
  "endpoint":   "https://hub.your-company.com",
  "token":      "<your-token>",
  "authHeader": "Authorization",
  "authScheme": "Bearer "
}
EOF
chmod 600 "${XDG_CONFIG_HOME:-$HOME/.config}/skill-hub-query/credentials.json"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| "Version history of html-go-live" | `source scripts/_lib.sh && api_get "${HUB_API_PREFIX}/versions/html-go-live?limit=20" \| jq` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| "Version history of html-go-live" | `source scripts/_lib.sh && api_get "${HUB_API_PREFIX}/versions/html-go-live?limit=20" \| jq` |

Self-Modification

High
Category
Rogue Agent
Confidence
90% confidence
Finding

The skill includes a documented flow to modify remote skill metadata (edit.sh) and therefore can change the operational behavior or presentation of skills on a hub. Even though it is limited to owned skills and includes confirmation language, self-modification or ecosystem modification is sensitive because a compromised or over-eager agent could alter discovery metadata, visibility, or downstream trust signals.

Content

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

md
### Scenario 5: edit a skill's card metadata

Use `edit.sh` to modify the Hub card for a skill you own. **You can only edit
skills you own**; non-owners get 403 from the Hub.

> **Hub compatibility**: This requires your Hub to implement

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
eplacing anything, `install.sh` compares the version declared in the package's `SKILL.md` and records the actual value with a warning. It warns rather than fail

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Currently **v1.2.0**. Full history: [CHANGELOG.md](./CHANGELOG.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 · SKILL.md (reported line 96)May include surrounding context.

md
{
  "_comment": "skill-hub-query credentials template. Copy to ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json and chmod 600.",
  "endpoint": "https://hub.your-company.com",
  "token": "<put-your-token-here>",
  "authHeader": "Authorization",

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

md
{
  "_comment": "skill-hub-query credentials template. Copy to ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json and chmod 600.",
  "endpoint": "https://hub.your-company.com",
  "token": "<put-your-token-here>",
  "authHeader": "Authorization",

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

md
{
  "_comment": "skill-hub-query credentials template. Copy to ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json and chmod 600.",
  "endpoint": "https://hub.your-company.com",
  "token": "<put-your-token-here>",
  "authHeader": "Authorization",

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

md
{
  "_comment": "skill-hub-query credentials template. Copy to ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json and chmod 600.",
  "endpoint": "https://hub.your-company.com",
  "token": "<put-your-token-here>",
  "authHeader": "Authorization",

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

md
{
  "_comment": "skill-hub-query credentials template. Copy to ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json and chmod 600.",
  "endpoint": "https://hub.your-company.com",
  "token": "<put-your-token-here>",
  "authHeader": "Authorization",

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

md
{
  "_comment": "skill-hub-query credentials template. Copy to ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json and chmod 600.",
  "endpoint": "https://hub.your-company.com",
  "token": "<put-your-token-here>",
  "authHeader": "Authorization",

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 · credentials.example.json (reported line 2)May include surrounding context.

json
{
  "_comment": "skill-hub-query credentials template. Copy to ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json and chmod 600.",
  "endpoint": "https://hub.your-company.com",
  "token": "<put-your-token-here>",
  "authHeader": "Authorization",

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 · scripts/_lib.sh (reported line 336)May include surrounding context.

sh
{
  "_comment": "skill-hub-query credentials template. Copy to ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json and chmod 600.",
  "endpoint": "https://hub.your-company.com",
  "token": "<put-your-token-here>",
  "authHeader": "Authorization",

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 · scripts/doctor.sh (reported line 161)May include surrounding context.

sh
{
  "_comment": "skill-hub-query credentials template. Copy to ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json and chmod 600.",
  "endpoint": "https://hub.your-company.com",
  "token": "<put-your-token-here>",
  "authHeader": "Authorization",

Chaining Abuse

High
Category
Tool Misuse
Confidence
87% confidence
Finding

The retention cleanup pipes potentially untrusted pathnames through xargs rm -f. If a crafted slug or filename introduces whitespace, newlines, or leading-dash semantics, the cleanup may delete unintended files within or beyond the backup set, especially because filenames are derived partly from slug input and expanded via globbing.

Content

Scanner excerpt · scripts/_edit_lib.sh (reported line 125)May include surrounding context.

sh
local to_delete
    to_delete=$(echo "$backups" | tail -n +"$((EDIT_BACKUP_RETENTION + 1))")
    if [[ -n "$to_delete" ]]; then
      echo "$to_delete" | xargs -r rm -f
    fi
  fi