Broken Object Property Level Authorization

Broken Object Property Level Authorization and Node.js (Express) [CVE-2026-34215]

[Updated Mar 2026] Updated CVE-2026-34215

Overview

The CVE-2026-34215 case highlights an information disclosure risk where a verify-password endpoint in a Parse Server deployment returns unsanitized authentication data, including MFA secrets, recovery codes, and OAuth tokens. An attacker who already knows a user’s password could extract sensitive MFA configuration data and reuse it to generate valid MFA codes, effectively bypassing MFA protections. This kind of flaw is representative of broken object property level authorization, where API responses leak internal object properties that should be restricted. In Node.js (Express) ecosystems, failure to explicitly filter sensitive properties from response payloads can enable attackers to access tokens, secrets, and codes simply by querying user objects or authentication endpoints that were not properly sanitized. The impact can be severe: attackers maintain access to accounts, exfiltrate secrets, or pivot to other services that rely on those tokens. This vulnerability is cataloged under CWE-200 (Information Exposure) and is a classic manifestation of missing or misapplied object-level or property-level access controls in API design. Proper remediation requires enforcing a principle of least privilege at the data-transport layer: do not serialize or send sensitive fields unless the requesting context explicitly requires them and is authorized to receive them. The CVE notes that Parse Server versions prior to 8.6.63 and 9.7.0-alpha.7 were affected, and patches have been released in those respective lines. For Node.js/Express apps, this translates to consistently filtering object properties before sending JSON responses, and centralizing serialization logic so sensitive fields cannot be surfaced by accident.

Affected Versions

Parse Server < 8.6.63 and < 9.7.0-alpha.7

Code Fix Example

Node.js (Express) API Security Remediation
// Vulnerable pattern (exposes sensitive object properties)
const express = require('express');
const app = express();
const bcrypt = require('bcrypt');
// Assume a Mongoose-like User model with fields: _id, username, password, mfaSecret, recoveryCodes, oauthAccessTokens
app.use(express.json());

app.post('/verify-password', async (req, res) => {
  const { username, password } = req.body;
  const user = await User.findOne({ username });
  if (!user) return res.status(401).json({ error: 'Invalid credentials' });
  const ok = await bcrypt.compare(password, user.password);
  if (!ok) return res.status(401).json({ error: 'Invalid credentials' });

  // Vulnerable: returning sensitive fields along with non-sensitive data
  res.json({
    id: user._id,
    username: user.username,
    mfaSecret: user.mfaSecret,
    recoveryCodes: user.recoveryCodes,
    oauthAccessTokens: user.oauthAccessTokens
  });
});

// Fixed: explicitly exclude sensitive fields from API responses
app.post('/verify-password-fixed', async (req, res) => {
  const { username, password } = req.body;
  const user = await User.findOne({ username });
  if (!user) return res.status(401).json({ error: 'Invalid credentials' });
  const ok = await bcrypt.compare(password, user.password);
  if (!ok) return res.status(401).json({ error: 'Invalid credentials' });

  // Safe response: only non-sensitive fields are returned
  const safeUser = {
    id: user._id,
    username: user.username
  };
  res.json({ user: safeUser });
});

// Note: In a real app, ensure the server is started and User model is defined.
// app.listen(3000, () => console.log('Server listening on port 3000'));

CVE References

Choose which optional cookies to allow. You can change this any time.