Back to skill

Security audit

Qa Patrol

Security checks for vulnerabilities and agentic risk

Overview

QA Patrol is a local web testing skill, but its templates can submit credentials to any configured app and delete app data while the docs understate those risks.

Install only if you will run it against staging or disposable test environments. Use unique low-privilege test accounts, never production passwords or DATABASE_URL values, verify the target origin before auth/payment tests, and avoid or redact screenshots and reports from authenticated, payment, or admin screens. Review and disable delete, storage-clearing, and payment-completion tests unless you explicitly want those actions performed on test data.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
assets/templates/full-saas.yaml:13
Finding

Credentials May Be Submitted to an Unrestricted Target Origin

Content
View full analysis

Vulnerability Details

File Location: assets/templates/full-saas.yaml:13, assets/templates/full-saas.yaml:23-37, and assets/templates/full-saas.yaml:99-109
Vulnerability Type: Unrestricted destination for sensitive authentication data
Risk Level: Medium

Vulnerable Code

yaml
app:
  url: ${APP_URL}
  name: ${APP_NAME:-My SaaS App}
  stack: auto
  repo_path: ${REPO_PATH:-./}
yaml
auth:
  provider: ${AUTH_PROVIDER:-supabase}
  login_path: /auth
  signup_path: /auth/signup
  dashboard_path: /dashboard
  profile_path: /profile
  accounts:
    admin:
      email: ${ADMIN_EMAIL}
      password: ${ADMIN_PASSWORD}
      role: admin
    pro:
      email: ${PRO_EMAIL}
      password: ${PRO_PASSWORD}
      role: pro_user
      has_subscription: true
    free:
      email: ${FREE_EMAIL}
      password: ${FREE_PASSWORD}
      role: free_user
    guest: true
yaml
- name: Sign in flow (free user)
  account: free
  steps:
    - navigate: ${auth.login_path}
    - clear_auth: true
    - type: { ref: email_input, text: ${auth.accounts.free.email} }
    - type: { ref: password_input, text: ${auth.accounts.free.password} }
    - click: { ref: sign_in_button }
    - wait: { url_contains: ${auth.dashboard_path}, timeout: 10000 }
  assert:
    - url_contains: ${auth.dashboard_path}
    - element_exists: user_indicator

The same behavior is documented directly in references/test-patterns.md:152-169:

python
# Navigate to auth page
browser(action="navigate", targetUrl="https://app.com/auth")
browser(action="snapshot")

# Fill credentials
browser(action="act", request={
    "kind": "type",
    "ref": "email_input",
    "text": "user@test.com"
})
browser(action="act", request={
    "kind": "type",
    "ref": "password_input",
    "text": "password123"
})

# Submit
browser(action="act", request={
    "kind":
...[truncated 2573 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require the effective target URL to use HTTPS before entering credentials, except for explicitly approved localhost development targets.
  2. Bind each credential set to an expected origin, for example:
    yaml
    accounts:
      free:
        allowed_origin: https://staging.example.com
        email: ${FREE_EMAIL}
        password: ${FREE_PASSWORD}
    
  3. Immediately before typing or submitting credentials, verify that the browser's current origin exactly matches the approved origin.
  4. Reject cross-origin redirects during authentication unless the destination is separately allowlisted for the configured identity provider.
  5. Require explicit user confirmation before sending credentials to a non-local or previously unapproved host.
  6. Add an enforceable test-environment check rather than relying only on documentation. For example, require QA_PATROL_ALLOW_AUTH_TESTS=true.
  7. Use isolated, minimally privileged test accounts with unique passwords and no access to production data.
  8. Avoid capturing screenshots, snapshots, console output, or reports while password values may be visible.
  9. Revise the privacy statement to disclose accurately that credentials are transmitted to the configured application and its approved authentication provider, while clarifying that the Skill itself has no separate telemetry or exfiltration service.
  10. Abort the test if the target changes origin between navigation, credential entry, and form submission.

T09 · Insecure Skill Coding Practices

Warning
Location
assets/templates/full-saas.yaml:220
Finding

Destructive Application Tests Lack Enforced Environment and Opt-In Guards

Content
View full analysis

Vulnerability Details

File Location: assets/templates/full-saas.yaml:220-260 and assets/examples/rewardly.yaml:343-361
Vulnerability Type: Unsafe destructive operations in a generic test plan
Risk Level: Medium

Vulnerable Code

The generic SaaS template creates, modifies, and deletes application records. The deletion operation is defined as follows:

yaml
- name: Delete item
  requires: signed_in
  requires: has_item
  account: free
  steps:
    - navigate: ${auth.dashboard_path}
    - click: { ref: first_item }
    - click: { ref: delete_button }
    - click: { ref: confirm_delete }
    - wait: 2000
  assert:
    - element_not_exists: deleted_item
    - text_contains: "deleted"

The supplied example also clears browser storage:

yaml
- name: App works after clearing cache
  requires: signed_in
  account: free
  steps:
    - execute: "localStorage.clear(); sessionStorage.clear();"
    - refresh: true
    - wait: 3000
  assert:
    - no_console_errors: true
    - no_blank_screen: true

Technical Analysis

CRUD testing is within the declared QA functionality, but the generic template confirms deletion of the first available item rather than restricting the operation to a uniquely created test fixture. The plan does not enforce any of the following controls:

  • A test or staging environment marker
  • A denylist for production hosts
  • Explicit opt-in for destructive tests
  • Interactive confirmation
  • Ownership verification for the selected record
  • Transactional rollback or guaranteed cleanup
  • An isolated browser profile

Consequently, pointing the template at a live application could cause the automation to select and delete an existing user record or other application object. The broad selector first_item is particularly risky because it does not demonstrate that the selected object was created by the current test run.

Clearing `loca ...[truncated 1709 chars]

Remediation
View remediation

Remediation Suggestions

  1. Disable all create, update, delete, payment-completion, and storage-clearing tests by default.
  2. Require a dedicated opt-in flag such as:
    yaml
    settings:
      allow_destructive_tests: false
    
  3. Require interactive confirmation that identifies the target origin, account, and destructive operations before execution.
  4. Deny destructive testing against known production hostnames and require a verifiable staging marker, such as an expected response header or environment endpoint.
  5. Create uniquely named fixtures for each run, record their identifiers, and only edit or delete those exact identifiers.
  6. Replace first_item with a selector tied to the unique test fixture.
  7. Implement cleanup in a guaranteed finalization block and report cleanup failures prominently.
  8. Use a dedicated, minimally privileged test account and a database containing disposable test data.
  9. Run browser tests in a separate temporary browser profile or isolated context so storage clearing cannot affect the operator's normal session.
  10. Before deletion, verify fixture ownership and require the item name or identifier to contain a run-specific test prefix.
  11. Where supported, wrap data mutations in a transaction that is rolled back after assertions.
  12. Document clearly that Level 3 feature tests may mutate application state and that they must not be run against production.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · references/bug-patterns.md (reported line 3)May include surrounding context.

md
# Bug Patterns

<!--
SECURITY NOTE: This file contains patterns for DETECTING security issues in codebases.
These are NOT exploitation patterns — they help developers FIND and FIX bugs.
This is the same approach used by:

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · references/bug-patterns.md (reported line 472)May include surrounding context.

md
## Static Analysis Patterns

<!--
DEFENSIVE SECURITY SCANNING: These patterns help YOU find bugs in YOUR OWN code.
This is the same approach as ESLint, Semgrep, and other security linters.
The secret detection patterns (sk_live_, sk_test_, etc.) help identify

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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.

Content

Scanner excerpt · assets/templates/auth-supabase.yaml (reported line 207)May include surrounding context.

yaml
#       - wait: 5000
  #     assert:
  #       - element_exists: verify_email_message
  #     # OR for auto-confirm:
  #     # assert:
  #     #   - url_contains: ${auth.dashboard_path}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The authentication examples hard-code credential entry patterns and normalize testing sign-in flows without any guidance on using non-production accounts, masking secrets, or avoiding capture of authenticated pages. In this skill’s context, snapshots and screenshots are explicitly used as evidence, so users may inadvertently record credentials, session state, or user data to local artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The screenshot guidance instructs users to save page captures to files but omits any warning that those files may contain sensitive information such as credentials, PII, payment data, session state, or internal application content. Because this QA skill targets auth, payments, and local app testing, screenshot artifacts are especially likely to contain sensitive data and persist on disk beyond the test session.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This manifest is a reusable template and the app.url field accepts any replacement app URL, which leaves the invocation target scope broad and unspecified. Because the file does not constrain what kind of app or environment this test plan should run against beyond a generic placeholder, it could be applied more broadly than intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This manifest defines a delete flow that clicks a delete button and confirms deletion, but the surrounding template text does not warn users that the skill performs destructive operations against application data. Under the markdown/manifest safety guidance for code-adjacent files, destructive or irreversible actions should be disclosed somewhere visible to the user.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.