HIGH bola idorsailsbasic auth

Bola Idor in Sails with Basic Auth

Bola Idor in Sails with Basic Auth — how this specific combination creates or exposes the vulnerability

BOLA (Broken Level of Authorization) / IDOR occurs when an API exposes one user’s resource through an identifier that should be restricted. In Sails, this commonly arises from trusting a client-supplied ID (e.g., :id in a route) and fetching a record without verifying ownership or tenant context. Combining this with HTTP Basic Auth can inadvertently reinforce the issue: Basic Auth typically provides authentication (who you are) but does not enforce authorization (what you are allowed to do). If your Sails policy or controller uses req.user (populated by Basic Auth) only to confirm a user exists, but then retrieves an object by a raw ID without scoping to that user, an attacker can iterate predictable IDs and access other users’ data.

For example, consider a Sails endpoint GET /user/:id/profile protected by Basic Auth. A request with valid credentials for alice might still succeed when an attacker sends GET /user/12345/profile with alice’s credentials if the controller does not ensure that the profile’s owner matches the authenticated user’s ID. Sails Waterline ORM will fetch the record if an id exists, regardless of who is making the request, unless you explicitly scope the query. This mismatch—authentication via Basic Auth present, but authorization checks missing or incomplete—is what enables BOLA/IDOR.

Real-world attack patterns include iterating integer or UUID identifiers, enumerating email addresses via predictable endpoints, or exploiting relationships (e.g., changing a foreign key that should be immutable). These map to OWASP API Top 10 A01:2023 (Broken Object Level Authorization) and can lead to unauthorized data exposure, account takeover, or privacy violations. Because Basic Auth transmits credentials in an Authorization header (base64-encoded, not encrypted without TLS), ensure you always use HTTPS to prevent credential interception; otherwise, attackers may capture the credentials and abuse them to probe IDs.

OpenAPI/Swagger analysis helps surface these risks by cross-referencing spec definitions with runtime behavior. If your spec defines a path with a parameter like {id} but does not encode ownership constraints, and runtime tests show that different users can retrieve each other’s resources, the scanner flags a BOLA/IDOR finding. Proper modeling in the spec—using securitySchemes for Basic Auth and path-level descriptions indicating scope—helps both humans and tools understand intended authorization boundaries.

Basic Auth-Specific Remediation in Sails — concrete code fixes

Remediation focuses on ensuring that every data access is scoped to the authenticated subject. With Basic Auth, Sails typically populates req.user via an authentication hook or policy. Use that authenticated subject to filter queries so users cannot access records belonging to others.

Example secure controller action in Sails (v1.x) using Waterline ORM:

// api/controllers/ProfileController.js
module.exports = {
  async showMe(req, res) {
    // req.user should be set by a policy that validates Basic Auth credentials
    if (!req.user || !req.user.id) {
      return res.unauthorized('Authentication required.');
    }

    // Explicitly scope to the authenticated user; do not trust req.params.id
    const profile = await UserProfile.findOne({
      user: req.user.id,
      // If using a different model name, adjust the attribute accordingly
    });

    if (!profile) {
      return res.notFound('Profile not found.');
    }

    return res.ok(profile);
  }
};

Example policy to enforce authentication via Basic Auth and attach user to req.user:

// api/policies/basic-auth-policy.js
const bcrypt = require('bcrypt');

module.exports = async function (req, res, proceed) {
  const authHeader = req.headers('authorization');
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    return res.unauthorized('Authorization header required.');
  }

  const base64 = authHeader.split(' ')[1];
  const decoded = Buffer.from(base64, 'base64').toString('utf-8');
  const [username, password] = decoded.split(':');

  if (!username || !password) {
    return res.unauthorized('Invalid authorization header format.');
  }

  const user = await User.findOne({ username });
  if (!user) {
    return res.unauthorized('Invalid credentials.');
  }

  const passwordMatch = await bcrypt.compare(password, user.passwordHash);
  if (!passwordMatch) {
    return res.unauthorized('Invalid credentials.');
  }

  req.user = user;
  return proceed();
};

In routes configuration, ensure the policy is applied to relevant endpoints and that parameters are validated:

// config/routes.js
module.exports.routes = {
  'GET /user/:id/profile': {
    handler: 'ProfileController.showMe',
    policies: ['basic-auth-policy'],
    // No reliance on req.params.id for ownership; controller uses req.user.id
  }
};

Additional guidance:

  • Never use Basic Auth over HTTP; always enforce HTTPS to protect credentials in transit.
  • Avoid exposing user IDs directly in URLs when possible; consider using opaque identifiers or tokens that do not leak enumeration information.
  • Combine the authenticated subject with model-level ownership checks. Even with Basic Auth, ensure every query that accesses user-specific data includes a filter on the user identifier (e.g., user: req.user.id).
  • Use Sails policies to centralize authentication logic and keep controllers focused on coordination and response formatting.
  • If you rely on middleBrick, you can validate these patterns by scanning your endpoints; its OpenAPI/Swagger analysis will cross-reference spec definitions with runtime findings to highlight missing authorization constraints.

Related CWEs: bolaAuthorization

CWE IDNameSeverity
CWE-250Execution with Unnecessary Privileges HIGH
CWE-639Insecure Direct Object Reference CRITICAL
CWE-732Incorrect Permission Assignment HIGH

Frequently Asked Questions

Can Basic Auth alone prevent BOLA/IDOR in Sails?
No. Basic Auth provides authentication (verifying identity) but does not enforce authorization (verifying access rights). You must explicitly scope queries to the authenticated subject to prevent IDOR.
How does middleBrick help detect BOLA/IDOR in Sails APIs using Basic Auth?
middleBrick scans unauthenticated attack surfaces and, when an OpenAPI/Swagger spec is available, cross-references spec definitions with runtime findings. It can flag endpoints where authorization checks are missing or not properly scoped, even when Basic Auth is used for authentication.