Back to skill

Security audit

PrepSPSC PYQ API

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for SPSC exam prep, but it directs agents to store and retrieve persistent user study activity through a third-party API without clear consent, retention, or per-user access controls.

Review this carefully before installing. Basic PYQ search and mock tests look purpose-aligned, but do not enable progress tracking, bookmarks, analytics, or leaderboards unless users knowingly agree to send study activity to PrepSPSC's Supabase API. Avoid personally identifying user IDs or sensitive note text, and verify the service's privacy, retention, deletion, and per-user authorization model.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

other

Warning
Location
SKILL.md:211
Finding

Unnecessary Transmission of Persistent User Activity to a Third-Party Service

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 211–222; related workflows at lines 289–308
Vulnerability Type: Privacy-sensitive data transmission
Risk Level: Medium

Vulnerable code:

markdown
### 5. Record Progress

**`POST /pyq-api/progress`** — Record a user's answer to a question.

```bash
curl -X POST "https://qqqditxzghqzodvauxth.supabase.co/functions/v1/pyq-api/progress" \
  -H "Authorization: Bearer $PREPSPSC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_user_id": "user123",
    "question_id": "uuid-here",
    "selected_option": "c",
    "is_correct": true,
    "time_spent_seconds": 45
  }'
text

The documented workflows further direct the agent to record individual or complete answer histories:

```markdown
4. `POST /pyq-api/progress` — Record each answer
5. `GET /pyq-api/analytics?user_id=xxx` — Show performance summary
markdown
5. Record all answers via `POST /pyq-api/progress`
6. Show analytics via `GET /pyq-api/analytics`

Technical Analysis

The Skill instructs an agent to send a persistent external user identifier, question identifier, selected answer, correctness result, and time spent to a third-party Supabase endpoint. Bookmark functionality also permits user-authored notes to be sent to the same service.

This network behavior is declared rather than concealed. However, it exceeds the minimum privileges needed for the Skill's core question-search and mock-test functionality. The documentation does not require the agent to obtain informed user consent, disclose the transmitted fields, use anonymous identifiers, avoid personally identifying values, or offer local-only progress tracking.

A stable or reused external_user_id allows answer activity to be linked across sessions. If it contains an email address, account name, or another identifying value, educational performance data could become directly at ...[truncated 1157 chars]

Remediation
View remediation

Remediation Suggestions

  1. Make progress tracking, analytics, and bookmarks explicitly opt-in rather than part of the default practice workflow.
  2. Before transmission, disclose the destination, purpose, exact fields, expected retention, and applicable deletion mechanism.
  3. Keep answer history and timing data local or session-only unless the user affirmatively enables synchronization.
  4. Generate a random, opaque, service-specific identifier instead of accepting email addresses, usernames, account IDs, or other identifying values.
  5. Minimize collected fields. Do not transmit timing, correctness, or notes unless they are required for a feature the user requested.
  6. Document retention limits and provide mechanisms to export and delete stored progress.
  7. Avoid recording free-form bookmark notes by default because they may contain personal or sensitive information.
  8. Add explicit Skill instructions prohibiting silent transmission and requiring user confirmation before persistent tracking begins.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:227
Finding

Caller-Controlled User Identifiers May Permit Cross-User Record Access

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 227–243; related bookmark retrieval at lines 273–278
Vulnerability Type: Potential insecure direct object reference and missing object-level authorization
Risk Level: High

Vulnerable code:

markdown
### 6. Get User Progress

**`GET /pyq-api/progress?user_id=user123`** — Retrieve a user's complete answer history.

```bash
curl "https://qqqditxzghqzodvauxth.supabase.co/functions/v1/pyq-api/progress?user_id=user123" \
  -H "Authorization: Bearer $PREPSPSC_API_KEY"

7. Performance Analytics

GET /pyq-api/analytics?user_id=user123 — Get accuracy by subject, difficulty breakdown, and recent activity.

bash
curl "https://qqqditxzghqzodvauxth.supabase.co/functions/v1/pyq-api/analytics?user_id=user123" \
  -H "Authorization: Bearer $PREPSPSC_API_KEY"
text

The same access pattern is documented for bookmarks:

```markdown
**List bookmarks:**
```bash
curl "https://qqqditxzghqzodvauxth.supabase.co/functions/v1/pyq-api/bookmarks?user_id=user123" \
  -H "Authorization: Bearer $PREPSPSC_API_KEY"
text

### Technical Analysis

The target user's identity is supplied through a caller-controlled `user_id` query parameter, while authentication is demonstrated using only a general API key. The documentation does not state that the requested identifier is cryptographically bound to the authenticated user or that the server performs per-record object-level authorization.

If the server treats the bearer API key as authorization to access any supplied identifier, a valid API client could alter `user_id` and request another user's complete answer history, analytics, or bookmarks. The predictable example `user123` also encourages identifiers that can be guessed or enumerated.

Static review of `SKILL.md` cannot confirm the live server's authorization implementation. Therefore, this finding identifies a high-risk documented 
...[truncated 1484 chars]
Remediation
View remediation

Remediation Suggestions

  1. Derive the user identity from a user-scoped, signed authentication token rather than accepting the authoritative identity through a query parameter.
  2. Enforce object-level authorization on every progress, analytics, and bookmark operation.
  3. Verify that the authenticated principal owns or is explicitly authorized to access each requested record.
  4. Separate application-level API authentication from end-user authorization; a valid service API key must not grant access to every user's records.
  5. Use opaque, high-entropy identifiers to reduce enumeration risk, while recognizing that unguessable identifiers do not replace authorization.
  6. Apply rate limits, anomaly detection, access logging, and alerts for sequential or high-volume identifier probing.
  7. Return uniform error responses so attackers cannot distinguish nonexistent identifiers from unauthorized records.
  8. Add automated negative authorization tests proving that one user cannot read, modify, or delete another user's progress or bookmarks.
  9. Update the Skill documentation to explain the user authentication model and avoid examples that imply arbitrary caller-selected users are accessible.
  10. Perform a dynamic authorization assessment of the hosted API before treating the endpoints as safe for sensitive records.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger list includes broad phrases such as 'mock test', 'exam preparation', and 'question bank', which can cause the skill to activate outside the intended SPSC-specific context. Over-broad invocation increases the chance of unintended third-party data transmission and user confusion about which service is being used.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

Making Requests

bash
curl -X POST "https://qqqditxzghqzodvauxth.supabase.co/functions/v1/pyq-api" \
  -H "Authorization: Bearer $PREPSPSC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "fundamental rights", "subject": "Indian Polity", "limit": 5}'

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

POST /pyq-api/mock-test — Generate a complete mock test following real SPSC exam patterns with difficulty balancing.

bash
curl -X POST "https://qqqditxzghqzodvauxth.supabase.co/functions/v1/pyq-api/mock-test" \
  -H "Authorization: Bearer $PREPSPSC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

GET /pyq-api/patterns — Returns all 64 exam patterns with subject distribution, question counts, duration, and marking scheme.

bash
curl "https://qqqditxzghqzodvauxth.supabase.co/functions/v1/pyq-api/patterns" \
  -H "Authorization: Bearer $PREPSPSC_API_KEY"

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documented capabilities extend from simple exam-question retrieval into persistent user tracking, analytics, bookmarks, and leaderboard features that collect and expose user activity. This broadens the data-handling surface beyond the skill’s stated purpose and increases privacy and misuse risk, especially if users are not clearly informed that identifiers and study behavior are transmitted to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill documents sending external_user_id, answer history, correctness, and time-spent data to an external API without a clear privacy warning or consent flow. This creates a meaningful privacy risk because study behavior and persistent identifiers can be linked and retained by a third party without transparent notice.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The bookmark API transmits a persistent external_user_id, question_id, and free-form note text to a third-party service. Because notes can contain personal or sensitive study information and are linked to a durable identifier, this creates a privacy and data-minimization issue beyond the core search/mock-test purpose.

Content

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

Add bookmark:

bash
curl -X POST "https://qqqditxzghqzodvauxth.supabase.co/functions/v1/pyq-api/bookmarks" \
  -H "Authorization: Bearer $PREPSPSC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_user_id": "user123", "question_id": "uuid-here", "note": "Review later"}'

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

Leaderboard functionality is not necessary for question search or mock-test generation and introduces avoidable exposure of user performance metadata. Even if limited, ranking systems can leak participation patterns or encourage collection of persistent identifiers without a clear need tied to the core skill purpose.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.