
Hartcodierte Geheimnisse in statischem strukturiertem Text identifizieren

„Meine kleinen Vögel sind überall, sogar im Norden, sie flüstern mir die seltsamsten Geschichten zu.“ - Lord Varys
Whispers ist ein statisches Code-Analyse-Tool, das verschiedene gängige Datenformate parst, um hartcodierte Anmeldeinformationen und gefährliche Funktionen zu finden. Whispers kann in der CLI ausgeführt oder in Ihre CI/CD-Pipeline integriert werden.
Whispers ist als strukturierter Text-Parser konzipiert, kein Code-Parser.
Die folgenden häufig verwendeten Formate werden derzeit unterstützt:
Python3-Dateien werden aufgrund der nativen Sprachunterstützung als ASTs geparst.
Die folgenden Sprachdateien werden als Text geparst und auf häufig vorkommende Variablendeklarations- und Zuweisungsmuster überprüft:
pip3 install whispers
git clone https://github.com/Skyscanner/whispers
cd whispers
make install
whispers --help
whispers --info
whispers source/code/fileOrDir
whispers --config config.yml source/code/fileOrDir
whispers --output /tmp/secrets.yml source/code/fileOrDir
whispers --rules aws-id,aws-secret source/code/fileOrDir
whispers --severity BLOCKER,CRITICAL source/code/fileOrDir
whispers --exitcode 7 source/code/fileOrDir
from whispers.cli import parse_args
from whispers.core import run
src = "tests/fixtures"
configfile = "whispers/config.yml"
args = parse_args(["-c", configfile, src])
for secret in run(args):
print(secret)
Es gibt verschiedene Konfigurationsoptionen in Whispers. Es ist möglich, Ergebnisse basierend auf Dateipfad, Schlüssel oder Wert ein- oder auszuschließen. Dateipfadangaben werden als Globs interpretiert. Schlüssel und Werte akzeptieren reguläre Ausdrücke und mehrere andere Parameter. Es gibt eine integrierte Standardkonfigurationsdatei, die verwendet wird, wenn Sie keine benutzerdefinierte bereitstellen.
config.yml sollte die folgende Struktur haben:
include:
files:
- "**/*.yml"
exclude:
files:
- "**/test/**/*"
- "**/tests/**/*"
keys:
- ^foo
values:
- bar$
rules:
starks:
message: Whispers from the North
severity: CRITICAL
value:
regex: (Aria|Ned) Stark
ignorecase: True
Der schnellste Weg, die Erkennung anzupassen (d.h. falsch positive und unerwünschte Ergebnisse zu entfernen), besteht darin, die Standarddatei config.yml in eine neue Datei zu kopieren, sie anzupassen und als Argument an Whispers zu übergeben.
whispers --config config.yml --rules starks src/file/or/dir
Regeln legen die tatsächlichen Dinge fest, die aus Schlüssel-Wert-Paaren extrahiert werden sollen. Es gibt mehrere häufig verwendete, die integriert sind, wie AWS-Schlüssel und Passwörter, aber das Tool ist so konzipiert, dass es leicht mit neuen Regeln erweitert werden kann.
rules: definiert werden.rule-id: # unique rule name
description: Values formatted like AWS Session Token
message: AWS Session Token # report will show this message
severity: BLOCKER # one of BLOCKER, CRITICAL, MAJOR, MINOR, INFO
key: # specify key format
regex: (aws.?session.?token)?
ignorecase: True # case-insensitive matching
value: # specify value format
regex: ^(?=.*[a-z])(?=.*[A-Z])[A-Za-z0-9\+\/]{270,450}$
ignorecase: False # case-sensitive matching
minlen: 270 # value is at least this long
isBase64: True # value is base64-encoded
isAscii: False # value is binary data when decoded
isUri: False # value is not formatted like a URI
similar: 0.35 # maximum allowed similarity between key and value
# (1.0 being exactly the same)
Die gesamte Parsing-Funktionalität wird über Plugins implementiert. Jedes Plugin implementiert eine Klasse mit der Methode pairs(), die Dateien durchläuft und die Schlüssel-Wert-Paare zurückgibt, die mit den Regeln überprüft werden sollen.
class PluginName:
def pairs(self, file):
yield "key", "value"