Skip to content

CVE-2026-1774: Verified Repro With Script Download

CVE-2026-1774: CASL Ability: Prototype Pollution via Condition Handling

CVE-2026-1774 is verified against @casl/ability · npm. Affected versions: >= 2.4.0, <= 6.7.4. Fixed in 6.7.5. Vulnerability class: Prototype Pollution. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00097.

REPRO-2026-00097 @casl/ability · npm Prototype Pollution Feb 19, 2026 CVE entry ↗ .txt
Severity
CRITICAL
CVSS
9.8
Reproduced in
6m 19s
Tool calls
78
Spend
$0.23
01 · Overview

What Is CVE-2026-1774?

CVE-2026-1774 is a critical (CVSS 9.8 per the advisory) prototype pollution vulnerability (CWE-1321) in @casl/ability, versions 2.4.0 through 6.7.4, reachable through the rulesToFields function when it processes user-controlled ability rule conditions. Pruva reproduced it (reproduction REPRO-2026-00097).

02 · Severity & CVSS

CVE-2026-1774 Severity & CVSS Score

CVE-2026-1774 is rated critical severity, with a CVSS base score of 9.8 out of 10.

CRITICAL threat level
9.8 / 10 CVSS base

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

03 · Affected Versions

Affected @casl/ability Versions

@casl/ability · npm versions >= 2.4.0, <= 6.7.4 are affected.

How to Reproduce CVE-2026-1774

$ pruva-verify REPRO-2026-00097
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00097/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-1774

Reproduced by Pruva's autonomous agents — 78 tool calls over 6 min. Full root-cause analysis and the complete transcript are below.

How the agent worked 227 events · 78 tool calls · 6 min
6 minDuration
78Tool calls
48Reasoning steps
227Events
1Dead-ends
Agent activity over 6 min
Support
17
Repro
88
Variant
118
0:0006:19

Root Cause and Exploit Chain for CVE-2026-1774

Summary

The CASL Ability library (versions 2.4.0 through 6.7.4) contains a prototype pollution vulnerability in the setByPath utility function. When the rulesToFields function processes ability rules containing malicious condition keys like __proto__.polluted, it passes these paths to setByPath, which unsafely traverses and modifies object properties without validating against dangerous property names. This allows attackers to pollute Object.prototype, potentially leading to privilege escalation, denial of service, or unauthorized access across the entire application.

Impact

  • Package: @casl/ability (npm)
  • Affected Versions: >= 2.4.0, <= 6.7.4
  • Fixed in Version: 6.7.5
  • CVE: CVE-2026-1774
  • CVSS: 9.8 (CRITICAL)
  • CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
  • CWE: CWE-1321 (Prototype Pollution)
Risk Level and Consequences

This is a critical severity vulnerability with the following potential impacts:

  • Confidentiality: High - Attackers may bypass authorization checks by manipulating object properties
  • Integrity: High - Modified prototypes can alter application behavior globally
  • Availability: High - Polluted prototypes can cause application crashes or infinite loops

The vulnerability affects any application using the rulesToFields function from @casl/ability/extra with user-controlled rule conditions.

Root Cause

The vulnerability exists in the setByPath function in packages/casl-ability/src/utils.ts. This function sets nested properties on an object using a dot-notation path string. Prior to the fix, setByPath did not validate the property names within the path, allowing dangerous properties like __proto__, constructor, and prototype to be used in paths.

Vulnerable Code Pattern
// Vulnerable version (before 6.7.5)
export function setByPath(object: AnyObject, path: string, value: unknown): void {
  let ref = object;
  let lastKey = path;

  if (path.indexOf('.') !== -1) {
    const keys = path.split('.');
    lastKey = keys.pop()!;
    ref = keys.reduce((res, prop) => {
      // NO VALIDATION - dangerous properties allowed
      res[prop] = res[prop] || {};
      return res[prop] as AnyObject;
    }, object);
  }

  ref[lastKey] = value; // Direct assignment without validation
}
Attack Vector

The rulesToFields function is part of the public API and is commonly used to extract rule conditions into field objects. When an attacker can control the conditions of rules passed to rulesToFields, they can craft a malicious path:

can('read', 'Post', { '__proto__.__pollutedValue__': 1 })

When rulesToFields processes this rule, it calls:

setByPath(fields, '__proto__.__pollutedValue__', 1)

This traverses fields.__proto__ (which is Object.prototype) and sets __pollutedValue__ = 1, polluting the global object prototype.

Fix

The patch introduces a FORBIDDEN_PROPERTIES set and validates each property in the path:

const FORBIDDEN_PROPERTIES = new Set(['__proto__', 'constructor', 'prototype']);

export function setByPath(object: AnyObject, path: string, value: unknown): void {
  // ... path splitting ...
  
  ref = keys.reduce((res, prop) => {
    if (FORBIDDEN_PROPERTIES.has(prop)) return res; // BLOCKED
    res[prop] = res[prop] || {};
    return res[prop] as AnyObject;
  }, object);

  if (!FORBIDDEN_PROPERTIES.has(lastKey)) {
    ref[lastKey] = value; // Only set if not forbidden
  }
}

Fix Commit: https://github.com/stalniy/casl/commit/39da920ec1dfadf3655e28bd0389e960ac6871f4

Reproduction Steps

The reproduction script is located at repro/reproduction_steps.sh.

What the Script Does
  1. Installs vulnerable version (6.7.3): Sets up a test environment with the vulnerable @casl/ability package
  2. Tests prototype pollution: Creates an ability with a malicious condition containing __proto__.__pollutedValue__ and calls rulesToFields. Verifies that Object.prototype is polluted.
  3. Installs patched version (6.7.5): Upgrades to the fixed version
  4. Verifies the fix: Repeats the test and confirms that Object.prototype is NOT polluted in the fixed version
Expected Evidence

The script produces the following evidence in logs/:

  • npm_install_vuln.log - Installation of vulnerable version
  • test_vulnerable.log - Demonstrates prototype pollution
  • npm_install_fixed.log - Installation of fixed version
  • test_fixed.log - Confirms fix works

Key Evidence from Vulnerable Version:

Before test: ({}).__pollutedValue__ = undefined
After rulesToFields: ({}).__pollutedValue__ = 1
Returned fields: {}
[FAIL] Prototype pollution confirmed! Object.prototype was polluted.

Key Evidence from Fixed Version:

Before test: ({}).__pollutedValue__ = undefined
After rulesToFields: ({}).__pollutedValue__ = undefined
Returned fields: {"__pollutedValue__":1}
[PASS] Fix confirmed! Object.prototype was NOT polluted.

Note: In the fixed version, the value is stored in the returned fields object (as expected) but does NOT pollute the global Object.prototype.

Evidence

All evidence is captured in the logs/ directory:

  • /root/.pruva/runs/ghsa-x9vf-53q3-cvx6_20260219-193039/logs/npm_install_vuln.log
  • /root/.pruva/runs/ghsa-x9vf-53q3-cvx6_20260219-193039/logs/test_vulnerable.log
  • /root/.pruva/runs/ghsa-x9vf-53q3-cvx6_20260219-193039/logs/npm_install_fixed.log
  • /root/.pruva/runs/ghsa-x9vf-53q3-cvx6_20260219-193039/logs/test_fixed.log
Environment Details
  • Node.js: Available via npm
  • Tested Versions:
    • Vulnerable: 6.7.3 (also affected 2.4.0 through 6.7.4)
    • Fixed: 6.7.5
  • Test Environment: Linux, npm package manager

Recommendations / Next Steps

Immediate Actions
  1. Upgrade: Update @casl/ability to version 6.7.5 or later immediately

    npm install @casl/ability@^6.7.5
    
  2. Audit: Check if your application uses rulesToFields with user-controlled rule conditions

  3. Input Validation: Until patched, sanitize any user input that might be used in ability rule conditions

Testing Recommendations
  1. Run npm audit to identify vulnerable dependencies
  2. Review code that constructs ability rules from user input
  3. Add regression tests using the reproduction approach in this report
  4. Monitor for suspicious rule conditions containing __proto__, constructor, or prototype keys
Long-term Prevention
  1. Implement automated security scanning in CI/CD pipelines
  2. Use lockfiles and audit checks in pre-commit hooks
  3. Subscribe to security advisories for @casl/ability

Additional Notes

Idempotency Confirmation

The reproduction script was executed twice consecutively with identical results:

  • Run 1: Exit code 0 (vulnerability confirmed)
  • Run 2: Exit code 0 (vulnerability confirmed)

Both runs successfully demonstrated:

  1. Vulnerable version (6.7.3) allows prototype pollution
  2. Fixed version (6.7.5) prevents prototype pollution
Edge Cases and Limitations
  • The vulnerability requires the use of rulesToFields function with user-controlled conditions
  • Applications that only use basic ability checks without rulesToFields may not be directly exploitable
  • The fix properly handles both dot-notation paths (__proto__.polluted) and direct property assignments
  • The fix also protects against constructor.prototype attack variants

CVE-2026-1774 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:002:11
0:00
session startedaccounts/fireworks/models/kimi-k2p5 · ghsa-x9vf-53q3-cvx6 · ghsa-x9v
0:08
0:25
0:28
web search
0:32
0:43
1:00
1:00
extract_facts
no facts extracted
1:05
1:05
1:05
supportrepro
1:36
1:36
1:36
1:38
1:42
1:47
web search
1:56
2:02
2:03
$mkdir -p /root/.pruva/runs/ghsa-x9vf-53q3-cvx6_20260219-193039/repro/logs && cd /root/.pruva/runs/ghsa-x9vf-53q3-cvx6_20260219-193039/repro && git clone --depth 1 https://github.com/stalniy/casl.git
0.9s
Cloning into 'casl'...
2:11

Artifacts and Evidence for CVE-2026-1774

Scripts, logs, diffs, and output captured during the reproduction.

No artifacts available

08 · How to Fix

How to Fix CVE-2026-1774

Upgrade @casl/ability · npm to 6.7.5 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-1774 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-1774

How does the CVE-2026-1774 exploit work?

An attacker supplies an ability rule condition with a key such as __proto__.polluted to code that calls rulesToFields from @casl/ability/extra. setByPath walks the path and writes onto Object.prototype instead of a plain object, potentially letting the attacker bypass authorization checks, crash the application, or alter its behavior globally.

Which versions of @casl/ability are affected by CVE-2026-1774, and where is it fixed?

@casl/ability >= 2.4.0 and <= 6.7.4 is affected. It is fixed in 6.7.5.

How severe is CVE-2026-1774?

Critical, CVSS 9.8 (vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) per the advisory.

How can I reproduce CVE-2026-1774?

Download the verified script from this page and run it in an isolated environment against @casl/ability <= 6.7.4. Call rulesToFields with a rule condition containing a __proto__.polluted key and confirm Object.prototype is polluted; confirm 6.7.5 rejects the dangerous path.
11 · References

References for CVE-2026-1774

Authoritative sources for CVE-2026-1774 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.