security

Security ferramentas

As tarefas cotidianas de segurança na engenharia web — hashing, entropia de senhas, claims de JWT, redação de CSP e ocultação de capturas antes de compartilhá-las — e qual ferramenta serve para cada uma.

11 ferramentas

§01 GUIA DO TEMA

A camada de tarefas rotineiras da segurança web

A maior parte do trabalho de segurança em uma semana normal de engenharia não é adversarial. É mecânica: escolher um algoritmo de digest, gerar uma credencial que satisfaça a política de alguém, ler as claims de um token para descobrir por que a autenticação falhou, escrever um Content-Security-Policy que não quebre o site, limpar uma captura antes de colá-la em um ticket. Nada disso se parece com um pentest, e é exatamente aí que os incidentes reais começam — o modo de falha é um mau hábito, não uma habilidade ausente.

O modelo que previne a maioria desses hábitos é uma divisão em três que as pessoas colapsam em uma só. Codificação — Base64, percent-encoding, Punycode — é reversível e não envolve segredo algum; muda a forma dos dados, nunca a sua confidencialidade. HashingSHA-256, SHA-512 — é de mão única e também não envolve segredo; prova que duas sequências de bytes são idênticas, nada mais. Operações com chave — HMAC, assinaturas de JWT, TLS — são as únicas que provam quem produziu algo, e apenas enquanto a chave permanece secreta. Sem chave, sem autenticação: um blob Base64, um digest nu e um payload de JWT decodificado são afirmações legíveis sem nada por trás.

O segundo eixo é a direção. Tarefas que emitem política — diretivas de CSP, cabeçalhos, segredos gerados — só estão corretas depois que você verifica o artefato na resposta implantada. Tarefas que inspecionam algo que lhe foi entregue carregam o risco oposto: o que está dentro do artefato. A ocultação de dados pertence a este lado porque a forma usual de segredos saírem de uma empresa é um HAR anexado a um relatório de bug, não um exploit.

O que cada primitiva realmente garante

PrimitivaProvaNão forneceMau uso comum
Base64 / URL-encodingTransporte seguro de bytes por canais de textoConfidencialidade — qualquer um reverte«Esconder» uma chave de API em um payload
SHA-256 / SHA-512Integridade: mesma entrada, mesmo digestSigilo; custo de força bruta em entrada de baixa entropiaArmazenar hashes de senha
SHA-1Compatibilidade com checksums legadosResistência a colisões (praticamente quebrada)Assinaturas; deduplicação de entrada hostil
HMAC (hash + chave secreta)Autenticidade enquanto a chave permanece secretaConfidencialidade — o payload continua legívelEnviar a chave para um navegador
Argon2id / bcrypt / scryptArmazenamento de senha com sal e deliberadamente lentoVelocidade — a lentidão é o recursoTrocar por um hash rápido «por performance»
Assinatura de JWT (HS256, RS256)Autenticidade do emissor — só após a verificaçãoNada, se você apenas decodificarConfiar nas claims de um payload decodificado
Content-Security-PolicyLista de permissões imposta pelo navegador para carregamento de recursosUma correção para a injeção; clientes que não são navegadores'unsafe-inline' deixado em script-src
TLS + Strict-Transport-SecurityConfidencialidade do transporte; sem downgrade para httpQualquer afirmação sobre a lógica da aplicaçãoLer um cadeado como «o app é seguro»

Quanta entropia é suficiente

Entropia é comprimento × log2(tamanho do conjunto), então o conjunto importa tanto quanto o comprimento.

Conjunto de caracteresBits por caractere8 caracteres14 caracteres20 caracteres
a–z (26)4,70386694
a–z0–9 (36)5,174172103
a–zA–Z0–9 (62)5,954883119
todos os quatro conjuntos (87)6,445290129

Abaixo de 40 bits está quebrado; 80 é o piso para uma conta que importa; um UUID v4 aleatório carrega 122 bits.

Escolher a ferramenta certa

Para impressões digitais, o Gerador de Hash calcula SHA-1, SHA-256, SHA-384 e SHA-512 de uma vez via Web Crypto, então um digest bate com echo -n "text" | shasum -a 256 byte por byte — o caminho rápido para reconciliar um checksum cujo algoritmo ninguém anotou. O MD5 está ausente porque o Web Crypto não o implementa.

Para segredos que você cria, a pergunta é quem guarda o valor. O Gerador de Senha serve quando quem guarda é um humano ou um gerenciador de senhas e um site impõe uma política de comprimento ou de conjunto de caracteres; ele reporta a entropia ao vivo para o conjunto que você habilitou. O Gerador UUID serve quando o consumidor é uma máquina e você quer um identificador opaco sem negociação de conjunto de caracteres. Os dois são apoiados em CSPRNG — o gerador de senha usa crypto.getRandomValues, o de UUID usa crypto.randomUUID() — então nenhum recorre a Math.random.

Para tokens, o Decodificador JWT divide header.payload.signature, formata as duas primeiras partes e renderiza iat, exp e nbf como ISO 8601 com um veredito de expiração — o suficiente para resolver «isto está vencido, ou as claims estão erradas?» em uma colagem. Use o Base64 quando tudo o que você resgatou de um log foi um único segmento; o Base64url usa - e _, então troque-os por + e / primeiro.

Para política, mantenha a redação e a verificação separadas. O Gerador CSP monta o cabeçalho a partir de 14 campos, um por diretiva, sobre uma base endurecida — default-src 'self', object-src 'none', base-uri 'self', frame-ancestors 'none' — e o hub de CSP vai diretiva por diretiva. Depois prove que a resposta implantada carrega o cabeçalho com os Cabeçalhos HTTP, que buscam do lado do servidor e mostram os cabeçalhos brutos como a origem os enviou. CDNs reescrevem cabeçalhos, e uma tag <meta> não consegue carregar frame-ancestors.

Antes de compartilhar, o Visualizador HAR lê a sua própria captura — método, status, tipo MIME, tamanho, tempo por entrada — enquanto o Sanitizador HAR prepara a cópia que sai da sua máquina, substituindo cookie, authorization, x-api-key e cabeçalhos semelhantes por [REDACTED], esvaziando corpos e mascarando parâmetros de consulta que parecem tokens. Quando o suspeito é uma única URL, o Parseador de URL decodifica a query string para mostrar se um token assinado está ali dentro, e o Conversor IDN revela se um domínio sósia é realmente cirílico na forma xn--.

Tudo isso roda localmente, exceto o verificador de cabeçalhos, que envia a sua URL para api.sitekits.dev. A seleção para segurança reúne a maior parte destes em uma página — os de uso geral (UUID, Base64, o visualizador de HAR) ficam em outros conjuntos por papel; o hub de privacidade cobre o que o seu navegador vaza.

Pegadinhas que causam incidentes de verdade

Um token decodificado não é um token verificado

Decodificar prova apenas que o Base64url está bem formado. A verificação precisa da chave do emissor, de um algoritmo fixado e de checagens de exp / nbf / iss / aud no servidor. Nunca tire o algoritmo do próprio cabeçalho alg do token — é assim que funcionam o alg: none e a confusão de RS256 para HS256.

Um hash rápido não é armazenamento de senha

Um SHA-256 nu de uma senha é um benchmark de GPU, não uma defesa; sem sal, uma única rainbow table quebra todos os usuários. Fazer hash para comparar arquivos é o caso oposto — ali um digest rápido é o correto.

'unsafe-inline' cancela a maior parte do CSP

Ele volta a permitir exatamente o script inline injetado que o CSP existe para bloquear. Use nonces ou hashes. Um connect-src com curinga é a mesma armadilha pelo outro lado: a exfiltração continua aberta mesmo com a execução de script trancada.

Ocultar dados é casamento de padrões, não compreensão

O sanitizador casa com uma lista fixa de cabeçalhos e com nomes de parâmetro que contenham token, key, secret, password, passwd, pwd, auth, session, sig ou signature. Uma credencial em um segmento de caminho de URL, ou chamada de t, sobrevive — e uma contagem de ocultações igual a zero em uma sessão autenticada é um sinal, não uma aprovação.

A entropia descreve o gerador, não a string

A fórmula só vale quando cada caractere foi sorteado aleatoriamente. P@ssw0rd!2024 tem 13 caracteres e todas as quatro classes, e ainda assim está em toda lista de palavras de quebra de senha. Só a forma como uma string foi gerada decide se a pontuação de um medidor significa alguma coisa.

FAQ
SHA-256 é bom o bastante para armazenar senhas?
Não. O SHA-256 é rápido por projeto, e GPUs comuns calculam bilhões de digests por segundo, então um atacante com uma tabela de hashes vazada quebra senhas curtas ou comuns em horas. Use uma KDF com sal e deliberadamente lenta — Argon2id, bcrypt ou scrypt — com o fator de trabalho ajustado. O SHA-256 é a escolha certa para integridade de arquivos, endereçamento por conteúdo e detecção de mudanças, não para credenciais.
Posso confiar em um JWT depois de decodificá-lo?
Não. O cabeçalho e o payload de um JWT são codificados em Base64url, não cifrados nem protegidos, então qualquer pessoa pode lê-los e qualquer pessoa pode forjar um token com claims arbitrárias. Só verificar a assinatura contra a chave do emissor prova quem o emitiu. Decodificar serve para depurar — imponha exp, nbf e audiência no servidor, porque o relógio de um cliente pode estar errado ou mentindo de propósito.
De quantos caracteres uma senha realmente precisa?
Depende do conjunto de caracteres, porque entropia é comprimento × log2(tamanho do conjunto). Com maiúsculas, minúsculas, dígitos e símbolos — um conjunto de 87 caracteres — cada caractere vale cerca de 6,44 bits, então 13 caracteres dão aproximadamente 84 bits e 20 caracteres cerca de 129. Só minúsculas dão 4,70 bits por caractere, então 8 caracteres minúsculos são cerca de 38 bits e quebráveis por força bruta. Busque 80 bits ou mais em contas que importam.
Uma Content-Security-Policy vai impedir XSS?
Ela contém o XSS em vez de corrigi-lo. Uma política estrita impede que script injetado execute ou exfiltre dados, mas só em navegadores que aplicam CSP e só se o script-src evitar 'unsafe-inline' e 'unsafe-eval'. Corrija a injeção com codificação de saída adequada e use CSP para limitar o dano do bug que você deixou passar. Implante primeiro com Content-Security-Policy-Report-Only e depois confirme que o cabeçalho em vigor está presente na resposta real.
Posso esconder uma chave de API codificando-a em Base64 dentro do payload de uma requisição?
Não. Base64 é uma codificação, não uma cifra: não usa chave, e qualquer pessoa com o payload recupera os bytes originais com um comando, que é justamente por que um decodificador não precisa de nada seu para ler. O problema mais profundo é o lugar, não o formato — qualquer segredo enviado a um navegador ou a um binário móvel já está divulgado, esteja embrulhado no que estiver. Mantenha a chave de longa duração no servidor e dê ao cliente algo que prove autenticidade sem ser o segredo: um token de vida curta, ou uma requisição assinada com HMAC em que a chave nunca sai da sua infraestrutura.