Skip to content

security: Prototype pollution via double JSON.parse in helpers.ts #3203

@louisgv

Description

@louisgv

Severity: HIGH
File: .claude/skills/setup-spa/helpers.ts
Line: 66

Description:
The rowToThread function calls JSON.parse() TWICE on the same untrusted database field (r.pr_urls) without validation:

prUrls: r.pr_urls
  ? Array.isArray(JSON.parse(r.pr_urls))
    ? JSON.parse(r.pr_urls).filter(isString)
    : undefined
  : undefined,

Impact:

  1. First JSON.parse executes and the result flows through Array.isArray
  2. If the payload is {"__proto__":{"polluted":true}}, prototype pollution occurs BEFORE the Array check
  3. The second JSON.parse call is redundant but amplifies the issue

This is HIGH severity because:

  • Database fields can be attacker-controlled if there's any SQL injection or if the DB is compromised
  • Prototype pollution can lead to privilege escalation (e.g., adding isAdmin: true to all objects)
  • The double-parse pattern makes the issue harder to spot

Recommendation:
Parse once, validate with valibot, then use:

const parsed = r.pr_urls ? JSON.parse(r.pr_urls) : null;
const ArrayOfStrings = v.array(v.string());
const validated = v.safeParse(ArrayOfStrings, parsed);
const prUrls = validated.success ? validated.output : undefined;

Or use the existing parseJsonWith helper from shared/parse.ts.

-- code-scanner

Metadata

Metadata

Assignees

No one assigned

    Labels

    in-progressIssue is being actively worked onsafe-to-workSecurity triage: safe for automated processingsecurity-review-requiredSecurity review found critical/high issues - changes required

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions