Repository navigation
fix: secret scanning hardening (severity, truncation, provider validation, override matching) - #41
Merged
Merged
Conversation
Documenta os conceitos Secret Scanner e Secret Match, referencias cruzadas com Detector/Allowlist/Severity Override/Fixer, e a ADR com o escopo, estrategia de deteccao e defaults decididos.
…tropia Adiciona o pacote internal/secretscanner com deteccao por assinatura (AWS, Stripe, GitHub, PEM, Bearer token) e heuristica de entropia opt-in, desenvolvido em TDD por fatias verticais. Integra ao Scanner existente: cada Finding agora carrega SecretMatches com severidade propria (piso HIGH/CRITICAL conforme status git, tetada pelo Severity Override do arquivo), pulando arquivos do Allowlist e conteudo binario/acima de 1MB. hook run e fix permanecem sem conhecimento do Secret Scanner, conforme a ADR 0005. Novas opcoes de configuracao: detector.entropy_scan, .secret_providers e .secret_ignore. Reporters terminal e JSON passam a exibir os Secret Matches aninhados por finding, sem nunca imprimir o valor.
…s filtros de severidade CalculateSummary usava apenas Finding.Severity, ignorando a severidade individual de cada SecretMatch. Um segredo real em um arquivo .env corretamente ignorado (Finding.Severity=Info) podia ser omitido do summary, fazendo check/scan reportarem PASSED com exit code 0 mesmo com um segredo detectado (ADR 0005, item 4). Adiciona Finding.EffectiveSeverity(), que retorna o maior valor entre a severidade do Finding e a de seus SecretMatches, e passa a usá-lo em CalculateSummary e nos filtros --severity de check/scan. Fixes #32
Scanner.Scan usava bufio.NewScanner com o limite padrao de 64KB por linha e nunca verificava scanner.Err(). Uma unica linha maior que isso (ex.: um certificado PEM ou blob de credenciais JSON em uma variavel) fazia o scan parar silenciosamente em bufio.ErrTooLong, descartando sem aviso qualquer segredo presente nas linhas seguintes. O buffer agora e dimensionado para cobrir todo o conteudo (nenhuma linha pode ser maior que o conteudo total), e o erro do scanner.Err() passa a ser retornado em vez de ignorado. Scan e scanSecrets agora retornam error, propagado ate Scanner.Scan (aborta o walk, como os demais erros de diretorio). Fixes #33
Config.Validate() nao verificava se as entradas de secret_providers correspondiam a provedores reais do secretscanner, entao um typo (ex.: "awss") desabilitava silenciosamente toda a deteccao por assinatura enquanto o config continuava validando normalmente. Expoe secretscanner.ValidProviders()/IsValidProvider() e usa em Validate() para rejeitar entradas invalidas, espelhando a validacao ja existente para severity_overrides. Fixes #34
…com severidade nao reconhecida O loop original de severity override tinha um break incondicional fora do switch: o primeiro pattern que desse match sempre vencia, mesmo com uma severidade nao reconhecida (nesse caso, sem efeito). Na extracao para matchSeverityOverride, os return passaram a ficar dentro dos cases do switch, entao um match com severidade nao reconhecida deixava de interromper o loop e um override seguinte, nao intencional, podia vencer silenciosamente. So e alcancavel com um config.Config montado programaticamente sem passar por Validate() (varios testes ja fazem isso via scanner.NewWithConfig), ja que Validate() ja rejeita severidades invalidas em severity_overrides. Fixes #35
joaooncode
force-pushed
the
feat/secret-scanning
branch
from
September 12, 2026 05:03
2672b59 to
7190979
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CalculateSummaryignorava a severidade dosSecretMatches, podendo reportarPASSEDcom segredos reais expostos. AdicionaFinding.EffectiveSeverity()e passa a usá-la no summary e nos filtros--severity.secretscanner.Scanner.Scantruncava silenciosamente linhas maiores que 64KB (limite padrão dobufio.Scanner) sem checarscanner.Err(). Buffer agora é dimensionado para cobrir todo o conteúdo e o erro é propagado.Config.Validate()não validavadetector.secret_providerscontra os provedores reais dosecretscanner, então um typo (awss) desabilitava silenciosamente toda a detecção por assinatura sem erro de config. Adicionasecretscanner.ValidProviders()/IsValidProvider()e valida emValidate().Scanner.matchSeverityOverridemudou a semântica silenciosamente — um match com severidade não reconhecida deixou de interromper o loop, permitindo que um override seguinte (não intencional) vencesse. Restaura o "para no primeiro match" com umdefaultexplícito noswitch.Closes #32, #33, #34, #35
Test plan
go build ./...go vet ./...go test ./...TestCalculateSummary_SecretMatchSeverityEscalatesFinding/TestFinding_EffectiveSeverity(bug: Summary do check/scan ignora a severidade dos SecretMatches e pode reportar PASSED mesmo com segredos reais expostos #32), cobertura de linhas >64KB emsecretscanner_test.go(bug: Secret Scanner trunca silenciosamente em linhas maiores que 64KB #33),TestParseYAML_InvalidSecretProvider(bug: valores inválidos em detector.secret_providers desabilitam silenciosamente toda a detecção por padrão #34),TestMatchSeverityOverrideStopsAtFirstMatchEvenWhenUnrecognized(bug: comportamento do matching de severity override mudou silenciosamente na refatoração para matchSeverityOverride #35)