Knowledge

Endurecimento de segurança de API em 2026: guia de implementação OWASP Top 10

APIs são a superfície de ataque de 2026. Implementar o OWASP API Security Top 10 não é mais opcional—é higiene de negócio.

20/03/202610 min de leituraKnowledge
Endurecimento de segurança de API em 2026: guia de implementação OWASP Top 10

Resumo executivo

APIs são a superfície de ataque de 2026. Implementar o OWASP API Security Top 10 não é mais opcional—é higiene de negócio.

Ultima atualizacao: 20/03/2026

Resumo executivo

Em 2026, APIs representam a maior superfície de ataque para a maioria das organizações. À medida que aplicações se decompõem em microsserviços, adotam arquiteturas event-driven e expõem funcionalidade através de APIs, o perímetro de segurança tradicional se dissolveu. Segurança de API não é mais um complemento—é um requisito fundamental para sistemas de produção.

O OWASP API Security Top 10 fornece um framework para proteger APIs contra as vulnerabilidades mais críticas. Este guia traduz esses riscos em padrões de implementação acionáveis, exemplos de código e práticas operacionais para APIs de produção.

API1:2023 – Quebra de autorização em nível de objeto

A vulnerabilidade

APIs tendem a expor endpoints que manipulam identificadores de objeto (UUIDs, IDs auto-incrementais). Sem verificações de autorização adequadas, atacantes podem manipular esses identificadores para acessar recursos pertencentes a outros usuários.

Padrão de implementação

typescript// RUIM: Sem verificação de autorização
app.get('/api/users/:id', async (req, res) => {
  const user = await db.users.findById(req.params.id);
  res.json(user);
});

// BOM: Verificação de autorização explícita
app.get('/api/users/:id', async (req, res) => {
  const requestingUserId = req.user.id; // Do JWT/sessão
  const requestedUserId = req.params.id;

  // Verificação de autorização: usuários só podem acessar seus próprios dados
  if (requestingUserId !== requestedUserId) {
    return res.status(403).json({
      error: 'Forbidden',
      message: 'Você não tem permissão para acessar este recurso'
    });
  }

  const user = await db.users.findById(requestedUserId);
  res.json(user);
});

// MELHOR: Abstração de autorização
interface AuthorizationPolicy {
  canAccess(userId: string, resource: any): boolean;
}

class OwnResourceOnlyPolicy implements AuthorizationPolicy {
  canAccess(userId: string, resource: any): boolean {
    return resource.userId === userId;
  }
}

class AdminOrOwnResourcePolicy implements AuthorizationPolicy {
  canAccess(userId: string, resource: any): boolean {
    const user = resource;
    return user.isAdmin || user.userId === userId;
  }
}

// Uso com middleware
function authorizeResource(policy: AuthorizationPolicy) {
  return async (req: Request, res: Response, next: NextFunction) => {
    const userId = req.user.id;
    const resource = await getResourceFromRequest(req);

    if (!policy.canAccess(userId, resource)) {
      return res.status(403).json({
        error: 'Forbidden',
        message: 'Você não tem permissão para acessar este recurso'
      });
    }

    req.resource = resource;
    next();
  };
}

app.get('/api/users/:id',
  authenticate,
  authorizeResource(new OwnResourceOnlyPolicy()),
  (req, res) => {
    res.json(req.resource);
  }
);

Melhores práticas para prevenir BOLA

PráticaImplementação
Usar UUIDs em vez de IDs sequenciaisPrevine ataques de enumeração
Implementar verificações de controle de acessoVerificar cada requisição contra permissões
Escopar tokens de APILimitar tokens a recursos/operações específicas
Auditar padrões de acessoMonitorar padrões de acesso incomuns

API2:2023 – Quebra de autenticação

A vulnerabilidade

Mecanismos de autenticação frequentemente têm falhas de implementação que permitem que atacantes comprometam tokens de autenticação, senhas ou identificadores de sessão.

Padrão de implementação

typescript// Autenticação baseada em JWT com melhores práticas de segurança
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import crypto from 'crypto';

interface AuthConfig {
  jwtSecret: string;
  jwtExpiresIn: string;
  refreshTokenExpiresIn: number; // dias
  bcryptRounds: number;
  maxFailedAttempts: number;
  lockoutDuration: number; // minutos
}

class AuthenticationService {
  private failedAttempts: Map<string, { count: number; lockUntil: Date }> = new Map();

  constructor(private config: AuthConfig) {}

  async hashPassword(password: string): Promise<string> {
    return bcrypt.hash(password, this.config.bcryptRounds);
  }

  async verifyPassword(password: string, hash: string): Promise<boolean> {
    // Verificar se conta está bloqueada
    const attempt = this.failedAttempts.get(password);
    if (attempt && attempt.lockUntil > new Date()) {
      throw new Error('Conta temporariamente bloqueada');
    }

    const isValid = await bcrypt.compare(password, hash);

    if (!isValid) {
      await this.recordFailedAttempt(password);
      throw new Error('Credenciais inválidas');
    }

    // Resetar tentativas falhadas no login bem-sucedido
    this.failedAttempts.delete(password);
    return true;
  }

  private async recordFailedAttempt(identifier: string): Promise<void> {
    const attempt = this.failedAttempts.get(identifier) || { count: 0, lockUntil: new Date(0) };
    attempt.count++;

    if (attempt.count >= this.config.maxFailedAttempts) {
      attempt.lockUntil = new Date(Date.now() + this.config.lockoutDuration * 60 * 1000);
    }

    this.failedAttempts.set(identifier, attempt);
  }

  generateTokens(userId: string, userRole: string): { accessToken: string; refreshToken: string } {
    const accessToken = jwt.sign(
      { userId, role: userRole },
      this.config.jwtSecret,
      { expiresIn: this.config.jwtExpiresIn }
    );

    const refreshToken = crypto.randomBytes(32).toString('hex');

    return { accessToken, refreshToken };
  }

  verifyAccessToken(token: string): any {
    try {
      return jwt.verify(token, this.config.jwtSecret);
    } catch (error) {
      throw new Error('Token inválido ou expirado');
    }
  }
}

// Rotação de refresh token
class RefreshTokenService {
  private tokens = new Map<string, { userId: string; expires: Date; previousToken?: string }>();

  async createRefreshToken(userId: string): Promise<string> {
    const token = crypto.randomBytes(32).toString('hex');
    const expires = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // 7 dias

    this.tokens.set(token, { userId, expires });
    return token;
  }

  async rotateRefreshToken(oldToken: string): Promise<string> {
    const tokenData = this.tokens.get(oldToken);
    if (!tokenData || tokenData.expires < new Date()) {
      throw new Error('Refresh token inválido ou expirado');
    }

    // Invalidar token antigo
    this.tokens.delete(oldToken);

    // Criar novo token
    return this.createRefreshToken(tokenData.userId);
  }

  async revokeToken(token: string): Promise<void> {
    this.tokens.delete(token);
  }
}

Melhores práticas para prevenir Broken Authentication

PráticaImplementação
Implementar rate limiting em endpoints de autenticaçãoPrevenir ataques de força bruta
Usar hashing de senha segurobcrypt com fator de trabalho apropriado
Implementar bloqueio de contaBloqueio temporário após tentativas falhadas
Rotacionar refresh tokensTokens de refresh de uso único
Implementar revogação de tokenCapacidade de revogar tokens comprometidos

API3:2023 – Quebra de autorização em nível de propriedade de objeto

A vulnerabilidade

APIs que incluem automaticamente todas as propriedades de objeto em respostas podem vazar dados sensíveis ou permitir modificações não autorizadas.

Padrão de implementação

typescript// Padrão DTO (Data Transfer Object) para filtragem de resposta
interface UserDTO {
  id: string;
  email: string;
  name: string;
  createdAt: Date;
}

interface SensitiveUserDTO extends UserDTO {
  phoneNumber: string;
  address: string;
  lastLogin: Date;
}

class UserResponseFactory {
  toPublicDTO(user: User): UserDTO {
    return {
      id: user.id,
      email: user.email,
      name: user.name,
      createdAt: user.createdAt
    };
  }

  toSensitiveDTO(user: User, requester: User): SensitiveUserDTO | UserDTO {
    // Incluir campos sensíveis apenas para administradores ou o próprio usuário
    if (requester.isAdmin || requester.id === user.id) {
      return {
        ...this.toPublicDTO(user),
        phoneNumber: user.phoneNumber,
        address: user.address,
        lastLogin: user.lastLogin
      };
    }

    return this.toPublicDTO(user);
  }
}

API4:2023 – Consumo de recursos irrestrito

A vulnerabilidade

APIs que não limitam o consumo de recursos (requisições, tamanho de dados, computação) são vulneráveis a ataques DoS e exploração de custos.

Padrão de implementação

typescript// Implementação de rate limiting
import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';

// Configuração de rate limiter
interface RateLimitConfig {
  windowMs: number;
  maxRequests: number;
  keyPrefix: string;
}

function createRateLimiter(config: RateLimitConfig, redis?: any) {
  const store = redis ? new RedisStore({
    client: redis,
    prefix: config.keyPrefix
  }) : undefined;

  return rateLimit({
    store,
    windowMs: config.windowMs,
    max: config.maxRequests,
    standardHeaders: true,
    legacyHeaders: false,
    handler: (req, res) => {
      res.status(429).json({
        error: 'Too Many Requests',
        message: 'Limite de taxa excedido',
        retryAfter: Math.ceil(config.windowMs / 1000)
      });
    }
  });
}

// Diferentes limites de taxa para diferentes endpoints
const apiLimiter = createRateLimiter({
  windowMs: 60 * 1000, // 1 minuto
  maxRequests: 100,
  keyPrefix: 'api_limit'
});

const authLimiter = createRateLimiter({
  windowMs: 15 * 60 * 1000, // 15 minutos
  maxRequests: 5,
  keyPrefix: 'auth_limit'
});

// Aplicar rate limiters
app.use('/api/', apiLimiter);
app.use('/api/auth/', authLimiter);

// Limitação de tamanho de requisição
app.use(express.json({
  limit: '1mb' // Limitar tamanho do corpo da requisição
}));

API5:2023 – Quebra de autorização em nível de função

A vulnerabilidade

APIs que escondem funções administrativas atrás de obscuridade em vez de autorização adequada permitem que atacantes acessem funcionalidades privilegiadas.

Padrão de implementação

typescript// Controle de acesso baseado em função (RBAC)
enum Role {
  USER = 'user',
  MODERATOR = 'moderator',
  ADMIN = 'admin'
}

interface Permission {
  resource: string;
  action: string;
}

interface RolePermissions {
  role: Role;
  permissions: Permission[];
}

class AuthorizationService {
  private rolePermissions: Map<Role, Permission[]> = new Map();

  constructor() {
    this.initializePermissions();
  }

  private initializePermissions(): void {
    this.rolePermissions.set(Role.USER, [
      { resource: 'users', action: 'read' },
      { resource: 'posts', action: 'create' },
      { resource: 'posts', action: 'read' }
    ]);

    this.rolePermissions.set(Role.ADMIN, [
      { resource: 'users', action: 'read' },
      { resource: 'users', action: 'update' },
      { resource: 'users', action: 'delete' },
      { resource: 'settings', action: 'update' }
    ]);
  }

  hasPermission(role: Role, resource: string, action: string): boolean {
    const permissions = this.rolePermissions.get(role);
    if (!permissions) {
      return false;
    }

    return permissions.some(
      permission => permission.resource === resource && permission.action === action
    );
  }
}

// Middleware de autorização
function requirePermission(authService: AuthorizationService, resource: string, action: string) {
  return (req: Request, res: Response, next: NextFunction) => {
    const userRole = req.user.role as Role;

    if (!authService.hasPermission(userRole, resource, action)) {
      return res.status(403).json({
        error: 'Forbidden',
        message: 'Você não tem permissão para realizar esta ação'
      });
    }

    next();
  };
}

Monitoramento e resposta a incidentes

Implementação de monitoramento de segurança

typescriptclass SecurityEventLogger {
  async logSecurityEvent(event: {
    type: string;
    severity: 'low' | 'medium' | 'high' | 'critical';
    userId?: string;
    ipAddress: string;
    details: any;
  }): Promise<void> {
    // Registrar em sistema de monitoramento de segurança
    await fetch(`${process.env.SECURITY_MONITORING_URL}/events`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        ...event,
        timestamp: new Date().toISOString(),
        environment: process.env.NODE_ENV
      })
    });

    // Para eventos críticos, também alertar imediatamente
    if (event.severity === 'critical') {
      await this.alertTeam(event);
    }
  }

  private async alertTeam(event: any): Promise<void> {
    // Enviar para PagerDuty, Slack, etc.
    await fetch(`${process.env.ALERT_WEBHOOK_URL}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        text: `EVENTO CRÍTICO DE SEGURANÇA: ${event.type}`,
        details: event.details
      })
    });
  }
}

// Uso no fluxo de autenticação
const securityLogger = new SecurityEventLogger();

app.post('/api/auth/login',
  authLimiter,
  async (req, res) => {
    try {
      const { email, password } = req.body;
      const user = await authService.authenticate(email, password);

      res.json({ token: user.token });
    } catch (error) {
      await securityLogger.logSecurityEvent({
        type: 'AUTHENTICATION_FAILURE',
        severity: 'medium',
        ipAddress: req.ip,
        details: {
          email: req.body.email,
          userAgent: req.headers['user-agent']
        }
      });

      res.status(401).json({
        error: 'Falha na autenticação'
      });
    }
  }
);

Conclusão

Segurança de API em 2026 requer defesa em profundidade: múltiplas camadas de proteção que abordam o OWASP API Security Top 10 de forma abrangente. Os padrões neste guia fornecem uma fundação, mas segurança é um processo contínuo de monitoramento, atualização e melhoria baseado em ameaças emergentes.

Pergunta estratégica para sua equipe: Qual é seu nível de maturidade em segurança de API, e qual é a lacuna entre seu estado atual e práticas de segurança prontas para produção?


Precisa endurecer sua postura de segurança de API e implementar proteções OWASP Top 10? Fale com a Imperialis sobre avaliação de segurança de API, implementação e operações de segurança contínuas.

Fontes

Leituras relacionadas