GuardAPI Logo
GuardAPI

Fix BFLA (Broken Function Level Authorization) in Sails

BFLA in Sails.js is a classic failure of the 'secure by default' mantra. Developers frequently assume that hiding a button in the UI or relying on session-based authentication is enough. It's not. If your backend doesn't explicitly verify that the current user has the right to execute a specific function (like /user/delete-all) regardless of their identity, you're wide open. In Sails, this usually manifests as exposed Blueprint actions or custom controllers that lack granular policy enforcement.

The Vulnerable Pattern

// api/controllers/UserController.js
// VULNERABLE: Only checks if the user is logged in via a global 'isLoggedIn' policy
module.exports = {
  deleteAccount: async function (req, res) {
    const idToToDelete = req.param('id');
    await User.destroyOne({ id: idToToDelete });
    return res.ok({ message: 'User deleted' });
  }
};

// config/policies.js module.exports.policies = { ‘UserController’: { ‘deleteAccount’: ‘isLoggedIn’ } // FAIL: Any logged-in user can delete any other user by guessing the ID. };

The Secure Implementation

To kill BFLA, you must implement Function-Level Access Control (FLAC). In Sails, use Policies as your primary defensive layer. Instead of a generic 'isLoggedIn' check, create specific policies that validate the 'Actor' against the 'Action' and the 'Target Resource'. The secure example ensures that even if an attacker knows a target ID, the policy intercepts the request and verifies ownership or administrative privileges before the controller logic ever executes. Always disable or strictly protect default Blueprint routes in production to prevent unauthorized access to sensitive CRUD operations.

// api/policies/canManageUser.js
module.exports = async function (req, res, proceed) {
  const targetId = req.param('id');
  const actorId = req.session.userId;

// Check if the actor is the owner or an admin const actor = await User.findOne({ id: actorId }); if (!actor) return res.forbidden();

if (actor.id === targetId || actor.role === ‘admin’) { return proceed(); }

return res.forbidden(‘You do not have permission to perform this action.’); };

// config/policies.js module.exports.policies = { ‘UserController’: { ‘deleteAccount’: ‘canManageUser’ // SUCCESS: Function-level authorization enforced. } };

System Alert • ID: 4500
Target: Sails API
Potential Vulnerability

Your Sails API might be exposed to BFLA (Broken Function Level Authorization)

74% of Sails apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

Free Tier • No Credit Card • Instant Report

Verified by Ghost Labs Security Team

This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.