Back to skill

Security audit

GraphQL

Security checks for vulnerabilities and agentic risk

Overview

This GraphQL skill is a coherent documentation and guidance package with disclosed local preference memory and optional user-run commands, with no evidence of hidden execution, exfiltration, or destructive behavior.

Installers should be aware that the skill keeps GraphQL preferences and remembered context in ~/Clawic/data/graphql/. Review that directory if you do not want prior project details reused, and pin or locally install the example GraphQL CLI tools before running any npx commands from the docs.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (1)

T08 · Insecure Dependencies

Warning
Location
commands.md:36
Finding
Unpinned Third-Party Packages Executed Through npx## Vulnerability Details **File Location**: `commands.md`, lines 36, 46, and 55 **Vulnerability Type**: Supply-chain exposure through unpinned executable dependencies **Risk Level**: Medium ### Complete Code Snippet ```bash # commands.md:36 npx get-graphql-schema https://api.example.com/graphql > schema.graphql # commands.md:46 npx graphql-inspector diff old.graphql new.graphql # commands.md:55 npx graphql-inspector validate './src/**/*.graphql' schema.graphql ``` ### Technical Analysis The documentation recommends invoking third-party npm command-line packages with `npx` without specifying reviewed versions or requiring locally installed, lockfile-controlled copies. If a requested package is not already available locally, `npx` may retrieve and execute it from the configured npm registry. Consequently, the code that runs can change after this Skill has been reviewed. A compromised package release, transitive dependency, package-registry account, registry configuration, or package-resolution path could cause arbitrary package code to execute under the user's account. This behavior is not inherently malicious, and the examples are optional commands that users run themselves. Nevertheless, directly executing unpinned remote dependencies is unnecessary for the Skill's core documentation functionality and does not provide reproducible or integrity-controlled execution. ### Attack Path 1. A developer follows one of the documented `npx` examples. 2. The requested package is not available as a trusted local dependency. 3. `npx` resolves and downloads the package and its dependency tree from the configured registry. 4. An attacker has compromised the selected package release, a dependency, a maintainer account, or the registry-resolution path. 5. Malicious package lifecycle or CLI code executes with the developer's operating-system privileges. 6. That code can access resources available to the invoking account, subject to host-level sandboxing and permissions ...[truncated 869 chars]
Remediation
## Remediation Suggestions 1. Add the reviewed tools as development dependencies with exact or tightly constrained versions, and commit the package-manager lockfile. 2. Invoke only the lockfile-resolved local binaries, such as through package scripts. 3. If retaining `npx`, use `npx --no-install` so execution fails rather than downloading an absent package. 4. Document the expected official package names and registry source to reduce dependency-confusion and registry-substitution risks. 5. Use lockfile integrity verification and reproducible installation commands such as `npm ci` in CI. 6. Apply dependency scanning and update review to the tools and their transitive dependencies. 7. Run schema-inspection tools in a restricted environment with minimal filesystem access, network access, and credentials. 8. Separate the examples by package where practical and identify a verified version for each command rather than presenting mutable registry resolution as the default.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (18)

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
## Cache Keys

- Default key: `__typename` plus `id` (or `_id`). Missing either one means no normalization, with no warning.
- Always select `id` and `__typename` in every query, on every object you will later mutate. Most clients add `__typename` automatically; none can add `id` for you.
- Types with a different identity field (`code`, `sku`, `slug`) need explicit key configuration per type. Types with no identity at all (value objects, aggregates, connection payloads) should be declared keyless so the client stores them inline instead of colliding them.
- The collision to fear: two different types configured to key on the same field, or a type keyed on a field that is unique only per parent. `Address:1` under two different users is one cache entry and the second write wins.
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.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
## Cache Keys

- Default key: `__typename` plus `id` (or `_id`). Missing either one means no normalization, with no warning.
- Always select `id` and `__typename` in every query, on every object you will later mutate. Most clients add `__typename` automatically; none can add `id` for you.
- Types with a different identity field (`code`, `sku`, `slug`) need explicit key configuration per type. Types with no identity at all (value objects, aggregates, connection payloads) should be declared keyless so the client stores them inline instead of colliding them.
- The collision to fear: two different types configured to key on the same field, or a type keyed on a field that is unique only per parent. `Address:1` under two different users is one cache entry and the second write wins.
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.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
- `keyArgs` decides what makes a *different list* versus a *different page*: filters and sort belong in `keyArgs`; `after`, `before`, `first`, `last` must not. Getting this backwards is the "filters bleed between tabs" bug.
- Apollo ships `relayStylePagination()` for the standard connection shape; anything custom needs a hand-written `merge` and `read`.
- Relay handles this natively through its pagination container, at the price of adopting the full Relay contract (global ids, a `node` field, the compiler).
- Refetching a paginated list resets it to one page unless the policy handles it — a "pull to refresh" that discards the user's scroll position without warning is this bug.

## Error Handling
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.

Hidden Instructions

High
Category
Prompt Injection
Content
last: YYYY-MM-DD

## Context
<!-- Their graph: server library, schema size, schema-first or code-first -->
<!-- Datastore and ORM, deployment target, federated or single schema -->
<!-- Client surfaces and how fast each one can be redeployed -->
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Send A Query Without A Client

```bash
curl -s https://api.example.com/graphql \
  -H 'content-type: application/json' \
  -H "authorization: Bearer $TOKEN" \
  -d '{"query":"query U($id:ID!){ user(id:$id){ id name } }","variables":{"id":"42"},"operationName":"U"}'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Send A Query Without A Client

```bash
curl -s https://api.example.com/graphql \
  -H 'content-type: application/json' \
  -H "authorization: Bearer $TOKEN" \
  -d '{"query":"query U($id:ID!){ user(id:$id){ id name } }","variables":{"id":"42"},"operationName":"U"}'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Send A Query Without A Client

```bash
curl -s https://api.example.com/graphql \
  -H 'content-type: application/json' \
  -H "authorization: Bearer $TOKEN" \
  -d '{"query":"query U($id:ID!){ user(id:$id){ id name } }","variables":{"id":"42"},"operationName":"U"}'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Send A Query Without A Client

```bash
curl -s https://api.example.com/graphql \
  -H 'content-type: application/json' \
  -H "authorization: Bearer $TOKEN" \
  -d '{"query":"query U($id:ID!){ user(id:$id){ id name } }","variables":{"id":"42"},"operationName":"U"}'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Send A Query Without A Client

```bash
curl -s https://api.example.com/graphql \
  -H 'content-type: application/json' \
  -H "authorization: Bearer $TOKEN" \
  -d '{"query":"query U($id:ID!){ user(id:$id){ id name } }","variables":{"id":"42"},"operationName":"U"}'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Send A Query Without A Client

```bash
curl -s https://api.example.com/graphql \
  -H 'content-type: application/json' \
  -H "authorization: Bearer $TOKEN" \
  -d '{"query":"query U($id:ID!){ user(id:$id){ id name } }","variables":{"id":"42"},"operationName":"U"}'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Send A Query Without A Client

```bash
curl -s https://api.example.com/graphql \
  -H 'content-type: application/json' \
  -H "authorization: Bearer $TOKEN" \
  -d '{"query":"query U($id:ID!){ user(id:$id){ id name } }","variables":{"id":"42"},"operationName":"U"}'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# must be rejected: a simple request that skips preflight
curl -s -X POST https://api.example.com/graphql -H 'content-type: text/plain' -d '{"query":"{__typename}"}'
# must be rejected: a mutation over GET
curl -s -G https://api.example.com/graphql --data-urlencode 'query=mutation{deleteThing(id:"1"){ok}}'
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Measure The Payload

```bash
curl -s -o /dev/null -w '%{size_download} bytes in %{time_total}s\n' -X POST https://api.example.com/graphql -H 'content-type: application/json' -d "$BODY"
```

- Measure uncompressed size: compression flatters repetitive JSON while parse and memory on the client stay uncompressed (`performance.md`).
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
# Mutations — Writes That Clients Can Actually Consume

A mutation is judged by what the caller can do with the response without asking again. The payload rule is SKILL.md rule 5; ordering is rule 6.

Contents: The Standard Shape · Naming And Granularity · Idempotency · Partial Failure · Concurrency · Cache Consequences · File Uploads · Deletes · Bulk Writes · Transactions · Traps
Confidence
75% 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.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill explicitly instructs the agent to read from and write to user-local files containing preferences and prior context without any user-facing disclosure or consent step. This creates a privacy and integrity risk because the agent may access or persist sensitive local data outside the immediate task, and the 'do not ask' language reduces transparency and user control.

Static analysis

No suspicious patterns detected.