T09 · Insecure Skill Coding Practices
- 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, andassets/templates/full-saas.yaml:99-109
Vulnerability Type: Unrestricted destination for sensitive authentication data
Risk Level: MediumVulnerable 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: trueyaml - 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_indicatorThe 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
- Require the effective target URL to use HTTPS before entering credentials, except for explicitly approved localhost development targets.
- 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} - Immediately before typing or submitting credentials, verify that the browser's current origin exactly matches the approved origin.
- Reject cross-origin redirects during authentication unless the destination is separately allowlisted for the configured identity provider.
- Require explicit user confirmation before sending credentials to a non-local or previously unapproved host.
- Add an enforceable test-environment check rather than relying only on documentation. For example, require
QA_PATROL_ALLOW_AUTH_TESTS=true. - Use isolated, minimally privileged test accounts with unique passwords and no access to production data.
- Avoid capturing screenshots, snapshots, console output, or reports while password values may be visible.
- 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.
- Abort the test if the target changes origin between navigation, credential entry, and form submission.
