Every example below is a comment PullLight would generate from a publicly disclosed CVE. No prompts, no manual triggers — just clean code merged faster.
[CRITICAL] Unsafe eval() on attacker-controlled auth metadata — src/auth-transport.js:62
AuthTransport.process() passes auth metadata through eval() without sanitization. Any log entry whose metadata.auth.evalExpr field contains a valid JavaScript expression will execute arbitrary code.
Exploit: attacker sends a crafted log entry with evalExpr: 'require("child_process").execSync("id")' — receives shell on the logging server.
This is CWE-94 (Code Injection), CVSS 9.8. Pre-auth RCE on any server running winston-auth < 1.2.3.
RCE·CWE-94·CVE-2025-31488CVSS 9.8
// suggested fixAdd safe-flag guard before eval. Whitelist allowed expressions. Remove eval entirely if possible. — View merged fix →
PL
PullLight reviewed this·#19284
CVSS 9.3 CRITICAL
📄db/models/sql/query.pyL318Python
315
def set_values(self, fields):
316
self.has_select_fields = True
317
if fields:
-318
# <- MISSING: no check_alias() call here
+319
for field in fields:
+320
self.check_alias(field) # <- THE FIX: 2 lines
321
field_names = []
322
extra_names = []
🔴PullLightCVSS 9.3
[HIGH] Unvalidated SQL column alias in set_values() — db/models/sql/query.py:318
QuerySet.values() accepts positional string arguments that become SQL column aliases. On JSONField models, JSON object keys are used to derive these aliases — but no validation was applied.
check_alias() exists in this file and blocks quotes, semicolons, and SQL comments. But it was never called on the args passed to set_values().
Exploit path: Model.objects.values('data__"injected" FROM "users"; --') -> SQL: SELECT "data__"injected" FROM "users"; --" -> attacker controls column selection. This is CWE-89 (SQL Injection), CVSS 9.3.
SQL Injection·CWE-89·CVE-2024-42005CVSS 9.3
// suggested fixAdd for field in fields: self.check_alias(field) to set_values(). The validator already exists in the same file. — View merged fix →
[CRITICAL] Sandbox Escape via Prototype Pollution — lib/bridge.js:89
Proxy bridge forwards sandbox writes directly to shared host Object.prototype. Sandbox code uses __lookupGetter__ + Buffer.apply() trick to reach host Object.prototype via otherReflectSet().
Once Object.prototype is polluted from inside the sandbox, every JavaScript code in the host process is affected. This is CWE-1321 -> CWE-94, CVSS 10.0.
vm2 has 1.3M+ weekly npm downloads. Used by AI agent platforms, online code editors, CI tools — all compromised if running vm2 < 3.11.0.
// suggested fixUpgrade to vm2 3.11.0+. Or migrate to V8 Isolate-based isolation (isolated-vm) — Proxy-based sandboxes are architecturally unsafe for untrusted code. — View merged fix →
PL
PullLight reviewed this·#3421
CVSS 9.2 CRITICAL
📄src/output/file_writer.jsL45JavaScript
42
function writePDF(filename, content) {
43
const sanitized = path.basename(filename);
-44
const dest = path.join(outputDir, filename); // <- No traversal check
+45
// Fix: only allow alphanumeric + dash/underscore
+46
if (!/^[a-zA-Z0-9_-]+\.pdf$/.test(filename)) {
+47
throw new Error('Invalid filename');
+48
}
+49
const dest = path.join(outputDir, path.basename(filename));
🔴PullLightCVSS 9.2
[CRITICAL] Path Traversal via Unvalidated Filename — src/output/file_writer.js:45
filename parameter passed directly to path.join() without traversal check. Attacker can write arbitrary files on the server by passing ../../etc/cron.d/malicious as the filename.
jsPDF has millions of weekly downloads. A path traversal in the PDF generation pipeline means an attacker who controls the filename parameter can overwrite system files on the server running the PDF generation service.
This is CWE-22 (Path Traversal), CVSS 9.2.
Path Traversal·CWE-22·CVE-2025-68428CVSS 9.2
// suggested fixValidate filename against a strict allowlist: /^[a-zA-Z0-9_-]+\.pdf$/. Use only basename, never the raw user-provided string in path.join(). — View merged fix →
34
function evaluateConditions(ability, conditions, subject) {
35
for (const [field, value] of Object.entries(conditions)) {
-36
if (!ability.can('read', subject)) return false;
-37
// <- MISSING: prototype chain traversal check on field
+38
for (const [field, value] of Object.entries(conditions)) {
+39
if (Object.prototype.hasOwnProperty.call(conditions, field)) {
+40
if (!ability.can('read', subject)) return false;
+41
}
🔴PullLightCVSS 9.8
[CRITICAL] Auth Bypass via Prototype Pollution — packages/casl-ability/src/evaluate-conditions.js:37
Object.entries(conditions) iterates inherited prototype properties. An attacker can add __proto__ or constructor to the conditions object, bypassing the ability check entirely.
CASL has 350K+ weekly downloads. Many apps use it for authorization. Prototype pollution bypasses the entire authorization layer — any action the user should not be able to take becomes available.
This is CWE-1321 (Prototype Pollution) -> Authorization Bypass, CVSS 9.8.
Auth Bypass·CWE-1321·CVE-2026-1774CVSS 9.8
// suggested fixGuard Object.entries with hasOwnProperty check. Reject fields named __proto__, constructor, or prototype. — View merged fix →
PL
PullLight reviewed this·#6281
CVSS 8.7 HIGH
📄lib/adapters/http.jsL204JavaScript
201
function shouldProxy(hostname) {
-202
// axios < 1.7.4 does not correctly honor NO_PROXY
-203
// Crafted hostnames bypass NO_PROXY and reach the proxy
[HIGH] SSRF via NO_PROXY Bypass — lib/adapters/http.js:204
axios < 1.7.4 does not correctly honor the NO_PROXY environment variable. A crafted hostname can bypass NO_PROXY rules, causing the request to be routed through an attacker-controlled proxy instead of connecting directly.
Impact: SSRF to internal cloud metadata services (169.254.169.254), private network resources, internal APIs. On shared hosting environments, requests can be intercepted by other tenants.
This is CWE-918 (SSRF), CVSS 8.7. All axios versions before 1.7.4 affected.
SSRF·CWE-918·CVE-2024-39338CVSS 8.7
// suggested fixUpgrade to axios 1.7.4+. Implement proper NO_PROXY parsing with hostname suffix matching. — View merged fix →
PL
PullLight reviewed this·#412
CVSS 10.0 CRITICAL
📄src/BladeRenderer.phpL28PHP
25
public function render($view, $data = []) {
26
$content = view($view, $data)->render();
-27
// User input reaches Blade::render() unescaped
[CRITICAL] Pre-Auth RCE via SSTI — src/BladeRenderer.php:28
LaRecipe passes unsanitized user content to Blade::render() without sandboxing. Attacker crafts a Blade template with {{ system('id') }} and achieves pre-auth RCE on any server running LaRecipe < 2.6.
CVSS 10.0. No authentication required. The vulnerability is in the Blade template rendering path — any user-supplied markdown or documentation content that reaches the renderer is exploitable.
This is CWE-1336 (Server-Side Template Injection), CVSS 10.0.
SSTI·CWE-1336·CVE-2025-53833CVSS 10.0
// suggested fixSandbox Blade rendering. Never pass unsanitized user input to Blade::render(). Use allowlist-based rendering for user-supplied content. — View merged fix →
The _from parameter is passed directly to unserialize() without type validation. Authenticated attacker injects a crafted serialized PHP object — PHAR gadget chain triggers RCE on the webmail server.
Roundcube has 2.4M+ exposed instances. Post-auth RCE on a webmail server = full compromise of all email accounts, session cookies, and anything else on that host.
This is CWE-502 (Deserialization of Untrusted Data), CVSS 9.9.
Deserialization·CWE-502·CVE-2025-49113CVSS 9.9
// suggested fixAdd rcube_utils::is_simple_string() validation with regex /^[\w.-]+$/i on _from parameter before unserialize(). — View merged fix →
PL
PullLight reviewed this·#156
CVSS 8.1 HIGH
📄lib/ip.jsL118JavaScript
115
function CIDR.contains(addr) {
116
const ip = isV4Format(addr) ? toBufferV4(addr) : toBufferV6(addr);
-117
// IPv6 loopback and IPv4-mapped IPv6 can bypass checks
[HIGH] SSRF via IPv4/IPv6 Canonicalization Bypass — lib/ip.js:118
The ip package's CIDR check fails to normalize IPv4-mapped IPv6 addresses (::ffff:127.0.0.1) and IPv6 loopback variants (::1). An attacker can bypass SSRF protections by encoding internal IPs in these alternate forms.
Exploit: request to ::ffff:127.0.0.1 bypasses 127.0.0.1 blocklist and connects to the local machine. Request to ::1 bypasses IPv4-only checks.
This is CWE-918 (SSRF), CVSS 8.1. All apps using the ip package for address validation are affected.
SSRF·CWE-918·CVE-2024-29415CVSS 8.1
// suggested fixNormalize all addresses to a canonical form before checking. Explicitly reject IPv4-mapped IPv6 addresses and IPv6 loopback when targeting internal resources. — View merged fix →
Next.js WebSocket upgrade handler does not validate the Host header against the configured allowed hosts. Attacker sends a WebSocket upgrade request with a crafted Host header pointing to an internal service — SSRF to cloud metadata endpoints, internal APIs, or other pods.
This is a new attack surface in Next.js — the WebSocket upgrade path bypasses normal HTTP routing checks. CVSS 8.6.
This is CWE-918 (SSRF), CVSS 8.6. Affects Next.js deployments with WebSocket routes.
SSRF·CWE-918·CVE-2026-44578CVSS 8.6
// suggested fixAdd Host header validation in WebSocket upgrade handler. Apply the same allowedHosts allowlist check used for HTTP routing. — View merged fix →
Want this on every pull request?
PullLight reviews every PR automatically — catching CVEs before they reach production. No prompts, no manual triggers, no subscriptions.
AuthTransport.process() passes auth metadata through eval() without sanitization. Any log entry whose metadata.auth.evalExpr field contains a valid JavaScript expression will execute arbitrary code.
Exploit: attacker sends a crafted log entry with
evalExpr: 'require("child_process").execSync("id")'— receives shell on the logging server.This is CWE-94 (Code Injection), CVSS 9.8. Pre-auth RCE on any server running winston-auth < 1.2.3.