flawopen.com/bola-idor/Javascript

● CWE-639 · 严重
安全研究 · FlawOpen

漏洞深度剖析:Broken Object Level Authorization (BOLA / IDOR) in Node.js & Express

Eliminate BOLA (CWE-639) / IDOR vulnerabilities in Node.js, Express, and Prisma by binding database lookups directly to authenticated tenant session context.

💡 通俗易懂的原理解析 (ELI5)

Imagine checking into Room 204 at a hotel and receiving a valid keycard. But you discover that if you scratch out '204' on the door handle and write '205', the lock clicks open and allows you to rummage through another guest's luggage. The hotel confirmed you were a registered guest (authentication), but never checked whether your key matched Room 205 (object authorization). In BOLA/IDOR, an attacker changes an ID in an API request and accesses another user's private records.

核心概念与专有名词

Authentication vs. Authorization
Authentication confirms who the user is. Authorization verifies if that user has permission to access that specific object.
BOLA (OWASP API #1)
Broken Object Level Authorization: accessing unauthorized records by manipulating object IDs.
Tenant Binding
Ensuring queries filter by both resource ID and the authenticated user's organization.

攻击执行流程分解

Step 1

Session Authentication

User logs in and receives a valid session or JWT.

Step 2

ID Manipulation

User changes URL parameter from /api/documents/100 to /api/documents/101.

Step 3

Unscoped Query

Express handler queries Prisma with only the document ID.

Step 4

Cross-Account Leakage

Server returns document belonging to another organization.

源代码对比:漏洞与安全实现

✕ 存在漏洞的实现
// VULNERABLE: Queries document by user-supplied ID alone
app.get('/api/documents/:id', authenticateJWT, async (req, res) => {
  // Vulnerable: trusts req.params.id without verifying organization ownership
  const document = await prisma.document.findUnique({
    where: { id: req.params.id }
  });
  
  if (!document) {
    return res.status(404).json({ error: 'Document not found' });
  }
  
  // Attacker accesses documents belonging to any tenant!
  res.json(document);
});
✓ 加固后的安全修复
// HARDENED: Scopes query strictly to authenticated user's tenant organization
app.get('/api/documents/:id', authenticateJWT, async (req, res) => {
  // Defense-in-depth: findFirst filters by BOTH document ID and authenticated tenant
  const document = await prisma.document.findFirst({
    where: {
      id: req.params.id,
      organizationId: req.user.organizationId
    }
  });
  
  if (!document) {
    // Return 404 rather than 403 to prevent object enumeration
    return res.status(404).json({ error: 'Document not found' });
  }
  
  res.json(document);
});

工程与系统安全加固清单

References