Overview
CVE-2026-33981 describes a scenario in changedetection.io where pre-update logic allowed attacker-controlled expressions to access environment data via the jq env builtin, leaking sensitive variables such as SALTED_PASS, PLAYWRIGHT_DRIVER_URL, and HTTP_PROXY. This is categorized under CWE-200 (Exposure of Sensitive Information). The root risk is that an unauthenticated user (or an authenticated user if a password is not configured) could exfiltrate server environment details by manipulating the input that selects what data to read. The patch for changedetection.io was applied in version 0.54.7 to close this exposure. The real-world impact is data leakage and potential follow-on attacks that rely on exposed secrets or infrastructure endpoints.
Affected Versions
0.54.6 and earlier (CVE-2026-33981)
Code Fix Example
Node.js (Express) API Security Remediation
Vulnerable pattern (Node.js/Express):
const express = require('express');
const app = express();
const data = {
user: { id: 1, name: 'Alice' },
// Mimics an environment-like snapshot that should not be exposed
envSnapshot: process.env
};
// User-supplied path selects a property to return
app.get('/watch', (req, res) => {
const fieldPath = req.query.field; // e.g., 'envSnapshot.HTTP_PROXY' or 'user.name'
const value = fieldPath
? fieldPath.split('.').reduce((acc, key) => (acc && acc[key] !== undefined) ? acc[key] : undefined, data)
: data;
res.json({ value });
});
app.listen(3000, () => console.log('Server running'));
---
Fixed pattern (Node.js/Express):
const express = require('express');
const app = express();
const data = {
user: { id: 1, name: 'Alice' }
};
// Define a strict allowlist of accessible paths
const ALLOWED_PATHS = new Set(['user.id', 'user.name']);
function resolvePathSafe(obj, path) {
if (!path || !ALLOWED_PATHS.has(path)) return undefined;
return path.split('.').reduce((acc, key) => acc && acc[key], obj);
}
app.get('/watch', (req, res) => {
const fieldPath = req.query.field;
const value = resolvePathSafe(data, fieldPath);
res.json({ value });
});
app.listen(3000, () => console.log('Server running'));