# Broken Function Level Authorization (BFLA)

## O que é?

**Broken Function Level Authorization (BFLA)** ocorre quando uma API não valida adequadamente se o usuário autenticado tem permissão para executar determinadas funções ou acessar recursos administrativos. Mesmo que o usuário esteja autenticado, ele pode conseguir executar operações que deveriam ser restritas apenas a usuários com privilégios elevados.

## Diferença entre BFLA e BOLA

* **BOLA (Broken Object Level Authorization)**: Foco em acessar *objetos específicos* de outros usuários (ex: ver o pedido #123 de outro usuário)
* **BFLA (Broken Function Level Authorization)**: Foco em executar *funções privilegiadas* sem ter a autorização necessária (ex: um usuário comum executar funções de administrador)

## Como funciona o ataque?

### Cenário vulnerável típico

```bash
API Endpoint: DELETE /api/users/{userId}
Função: Deletar usuário (deveria ser admin-only)

Usuário comum autenticado:
- Tem token JWT válido
- NÃO é administrador
- API não verifica o nível de privilégio
```

### Exemplo de exploração

```bash
# Usuário comum tenta deletar outro usuário
DELETE /api/users/456
Authorization: Bearer <token_usuario_comum>

# API vulnerável: aceita e executa
HTTP/1.1 200 OK
{
  "message": "User deleted successfully"
}
```

## Exemplos práticos de vulnerabilidades

### 1. Funções administrativas sem validação

```javascript
// ❌ VULNERÁVEL
app.delete('/api/users/:id', authenticateUser, async (req, res) => {
  // Apenas verifica se está autenticado, não se é admin
  const userId = req.params.id;
  await User.delete(userId);
  res.json({ message: 'User deleted' });
});
```

```javascript
// ✅ SEGURO
app.delete('/api/users/:id', authenticateUser, requireAdmin, async (req, res) => {
  // Verifica autenticação E autorização de admin
  const userId = req.params.id;
  await User.delete(userId);
  res.json({ message: 'User deleted' });
});

// Middleware de autorização
function requireAdmin(req, res, next) {
  if (req.user.role !== 'admin') {
    return res.status(403).json({ error: 'Forbidden: Admin access required' });
  }
  next();
}
```

### 2. Endpoints administrativos "escondidos"

```bash
# Endpoints que deveriam ser admin-only
GET  /api/admin/users          # Listar todos os usuários
POST /api/admin/users          # Criar usuário com qualquer role
PUT  /api/users/:id/role       # Alterar role de usuário
GET  /api/admin/logs           # Ver logs do sistema
POST /api/admin/settings       # Alterar configurações
```

Muitas vezes, desenvolvedores assumem que:

* "Ninguém vai descobrir este endpoint"
* "Está no painel admin, então está seguro"
* **ERRO**: Atacantes podem descobrir via:
  * Fuzzing de URLs
  * Código fonte exposto
  * Documentação Swagger/OpenAPI
  * Engenharia reversa de apps mobile

### 3. Mudança de role sem validação

```javascript
// ❌ VULNERÁVEL - Usuário pode se promover a admin
app.put('/api/users/:id', authenticateUser, async (req, res) => {
  const userId = req.params.id;
  const updates = req.body; // { name, email, role }
  
  // Aceita qualquer campo do body, inclusive 'role'
  await User.update(userId, updates);
  res.json({ message: 'User updated' });
});

// Ataque:
// PUT /api/users/123
// { "role": "admin" }
```

```javascript
// ✅ SEGURO - Separa campos permitidos por nível de acesso
app.put('/api/users/:id', authenticateUser, async (req, res) => {
  const userId = req.params.id;
  
  // Campos que qualquer usuário autenticado pode alterar
  const allowedFields = ['name', 'email', 'phone'];
  const updates = {};
  
  allowedFields.forEach(field => {
    if (req.body[field] !== undefined) {
      updates[field] = req.body[field];
    }
  });
  
  // Apenas admins podem alterar role
  if (req.body.role && req.user.role === 'admin') {
    updates.role = req.body.role;
  }
  
  await User.update(userId, updates);
  res.json({ message: 'User updated' });
});
```

## Técnicas de exploração

### 1. Manipulação de HTTP Methods

```bash
# Endpoint normal (GET permitido)
GET /api/products/123  # ✅ Funciona

# Testar outros métodos
DELETE /api/products/123  # Pode funcionar sem verificação
PUT /api/products/123     # Pode funcionar sem verificação
```

### 2. Descoberta de endpoints administrativos

```bash
# Padrões comuns a testar
/api/admin/*
/api/v1/admin/*
/api/internal/*
/api/staff/*
/api/superuser/*
/api/manager/*

# Funções administrativas comuns
/api/users (POST, DELETE)
/api/roles
/api/permissions
/api/settings
/api/config
/api/backup
/api/export
```

### 3. Manipulação de parâmetros

```bash
# Adicionar parâmetros admin
GET /api/products?admin=true
GET /api/products?role=admin
GET /api/products?isAdmin=1

# Cabeçalhos customizados
X-Admin: true
X-Role: admin
X-Privilege-Level: 99
```

## Impacto do BFLA

### Gravidade: ALTA

**Consequências:**

1. **Escalação de privilégios**: Usuário comum se torna admin
2. **Acesso a dados sensíveis**: Logs, relatórios, dados de todos usuários
3. **Modificações não autorizadas**: Deletar usuários, alterar configurações
4. **Bypass completo de controles**: Executar qualquer função administrativa
5. **Comprometimento total**: Sistema pode ser completamente controlado

### Exemplos reais de impacto

```
Cenário 1: E-commerce
- Usuário comum acessa /api/admin/orders
- Consegue ver todos os pedidos de todos os clientes
- Pode cancelar pedidos de outros usuários

Cenário 2: Sistema bancário
- Usuário acessa /api/admin/transactions
- Consegue aprovar transações pendentes
- Pode modificar limites de conta

Cenário 3: Plataforma SaaS
- Usuário free acessa /api/admin/features
- Ativa recursos premium para sua conta
- Modifica configurações de billing
```

## Como prevenir BFLA

{% stepper %}
{% step %}

### Implementar controle de acesso baseado em roles (RBAC)

```javascript
// Sistema de roles
const ROLES = {
  USER: 'user',
  MODERATOR: 'moderator',
  ADMIN: 'admin'
};

const PERMISSIONS = {
  'user': ['read:own', 'write:own'],
  'moderator': ['read:own', 'write:own', 'read:all', 'delete:flagged'],
  'admin': ['*'] // Todas as permissões
};

// Middleware de autorização
function requirePermission(permission) {
  return (req, res, next) => {
    const userRole = req.user.role;
    const userPermissions = PERMISSIONS[userRole] || [];
    
    if (!userPermissions.includes(permission) && !userPermissions.includes('*')) {
      return res.status(403).json({ 
        error: 'Forbidden: Insufficient permissions' 
      });
    }
    
    next();
  };
}

// Uso
app.delete('/api/users/:id', 
  authenticateUser, 
  requirePermission('delete:users'), 
  deleteUser
);
```

{% endstep %}

{% step %}

### Validar autorizações em CADA endpoint

```javascript
// ❌ NUNCA confiar apenas na autenticação
if (req.user) { // Apenas verifica se está logado
  // Executar ação privilegiada
}

// ✅ SEMPRE verificar autorização específica
if (req.user && req.user.role === 'admin') {
  // Executar ação privilegiada
}

// ✅ MELHOR: Usar middleware reutilizável
app.delete('/api/users/:id', [
  authenticate,        // Verifica se está logado
  authorizeAdmin,      // Verifica se é admin
  validateInput,       // Valida entrada
  deleteUser           // Executa ação
]);
```

{% endstep %}

{% step %}

### Negar por padrão (Whitelist approach)

```javascript
// ❌ Abordagem blacklist (insegura)
const blockedActions = ['deleteAllUsers', 'resetDatabase'];
if (!blockedActions.includes(action)) {
  executeAction(action); // Permite tudo que não está na lista
}

// ✅ Abordagem whitelist (segura)
const allowedActions = {
  'user': ['viewProfile', 'editProfile'],
  'admin': ['viewProfile', 'editProfile', 'deleteUser', 'viewAllUsers']
};

if (allowedActions[userRole].includes(action)) {
  executeAction(action); // Apenas permite o que está explicitamente autorizado
}
```

{% endstep %}

{% step %}

### Segregação de rotas por nível de acesso

```javascript
// Rotas públicas
app.use('/api/public', publicRoutes);

// Rotas autenticadas
app.use('/api/user', authenticate, userRoutes);

// Rotas administrativas
app.use('/api/admin', [authenticate, requireAdmin], adminRoutes);

// Cada grupo tem suas próprias regras de autorização
```

{% endstep %}

{% step %}

### Implementar logging e auditoria

```javascript
function auditLog(req, action) {
  const log = {
    timestamp: new Date(),
    userId: req.user.id,
    userRole: req.user.role,
    action: action,
    endpoint: req.originalUrl,
    method: req.method,
    ip: req.ip,
    success: true
  };
  
  // Salvar log para auditoria
  AuditLog.create(log);
}

// Logar tentativas de acesso negadas
function unauthorizedAttemptLog(req, reason) {
  const log = {
    timestamp: new Date(),
    userId: req.user?.id || 'anonymous',
    userRole: req.user?.role || 'none',
    attemptedAction: req.originalUrl,
    method: req.method,
    reason: reason,
    ip: req.ip,
    success: false
  };
  
  SecurityLog.create(log); // Log de segurança separado
  
  // Alertar após X tentativas
  checkForSuspiciousActivity(req.user?.id, req.ip);
}
```

{% endstep %}

{% step %}

### Testes de autorização

```javascript
// Testes unitários para verificar autorização
describe('User Management API', () => {
  
  it('should allow admin to delete users', async () => {
    const response = await request(app)
      .delete('/api/users/123')
      .set('Authorization', `Bearer ${adminToken}`);
    
    expect(response.status).toBe(200);
  });
  
  it('should deny regular user from deleting users', async () => {
    const response = await request(app)
      .delete('/api/users/123')
      .set('Authorization', `Bearer ${userToken}`);
    
    expect(response.status).toBe(403);
    expect(response.body.error).toContain('Forbidden');
  });
  
  it('should deny unauthenticated requests', async () => {
    const response = await request(app)
      .delete('/api/users/123');
    
    expect(response.status).toBe(401);
  });
});
```

{% endstep %}
{% endstepper %}

## Checklist de segurança

**Para cada endpoint da API, verificar:**

* [ ] Autenticação é obrigatória?
* [ ] Autorização específica está implementada?
* [ ] Role/permissão necessária está documentada?
* [ ] Validação de autorização ocorre no backend (não apenas frontend)?
* [ ] Campos sensíveis (como 'role') não podem ser modificados por usuários comuns?
* [ ] Endpoints administrativos estão em rotas protegidas?
* [ ] Logs de auditoria estão sendo gerados?
* [ ] Testes de autorização estão implementados?
* [ ] Documentação API lista as permissões necessárias?

## Exemplo completo de implementação segura

```javascript
// auth.middleware.js
const jwt = require('jsonwebtoken');

// Autenticação
function authenticate(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  
  if (!token) {
    return res.status(401).json({ error: 'Authentication required' });
  }
  
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    return res.status(401).json({ error: 'Invalid token' });
  }
}

// Autorização por role
function requireRole(...allowedRoles) {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({ error: 'Authentication required' });
    }
    
    if (!allowedRoles.includes(req.user.role)) {
      auditLog(req, 'UNAUTHORIZED_ACCESS_ATTEMPT');
      return res.status(403).json({ 
        error: 'Forbidden: Insufficient privileges',
        required: allowedRoles,
        current: req.user.role
      });
    }
    
    next();
  };
}

// Autorização por permissão específica
function requirePermission(permission) {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({ error: 'Authentication required' });
    }
    
    const userPermissions = getUserPermissions(req.user.role);
    
    if (!userPermissions.includes(permission) && !userPermissions.includes('*')) {
      auditLog(req, 'UNAUTHORIZED_ACCESS_ATTEMPT');
      return res.status(403).json({ 
        error: 'Forbidden: Missing required permission',
        required: permission,
        available: userPermissions
      });
    }
    
    next();
  };
}

module.exports = { authenticate, requireRole, requirePermission };

// routes/users.js
const express = require('express');
const router = express.Router();
const { authenticate, requireRole, requirePermission } = require('../middleware/auth');

// Usuário ver seu próprio perfil
router.get('/me', authenticate, getUserProfile);

// Usuário editar seu próprio perfil
router.put('/me', authenticate, updateOwnProfile);

// Admin listar todos os usuários
router.get('/', 
  authenticate, 
  requireRole('admin', 'moderator'),
  listAllUsers
);

// Apenas admin pode deletar usuários
router.delete('/:id', 
  authenticate, 
  requireRole('admin'),
  deleteUser
);

// Apenas admin pode alterar roles
router.put('/:id/role', 
  authenticate, 
  requirePermission('manage:roles'),
  updateUserRole
);

module.exports = router;
```

## Conclusão

**BFLA** é uma vulnerabilidade crítica que permite usuários comuns executarem funções privilegiadas. A prevenção requer:

1. **Autenticação** (quem você é) + **Autorização** (o que você pode fazer)
2. Validação de permissões em **TODOS** os endpoints
3. Abordagem de **whitelist** (negar por padrão)
4. Segregação clara de funções por nível de acesso
5. Auditoria e monitoramento contínuos

**Lembre-se**: Nunca confie apenas na autenticação. Sempre valide se o usuário tem autorização específica para executar a ação solicitada.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/web/back-end/apis/broken-function-level-authorization-bfla.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
