Breaking News

“My little birds are in all places, even all the way through the North, they whisper to me the strangest tales.” – Lord Varys

Whispers is a static code research device designed for parsing reasonably a lot of not unusual knowledge codecs in search of hardcoded credentials and perilous purposes. Whispers can run all the way through the CLI or you are able to combine it to your CI/CD pipeline.


  • Passwords
  • API tokens
  • AWS keys
  • Personal keys
  • Hashed credentials
  • Authentication tokens
  • Dangerous purposes
  • Delicate wisdom

Supported Codecs

Whispers is meant to be a structured textual content parser, now not a code parser.

The next forever used codecs are in recent years supported:

  • YAML
  • JSON
  • XML
  • .npmrc
  • .pypirc
  • .htpasswd
  • .homes
  • pip.conf
  • conf / ini
  • Dockerfile
  • Dockercfg
  • Shell scripts
  • Python3

Python3 wisdom are parsed as ASTs on account of local language enhance.

Declaration & Project Codecs

The next language wisdom are parsed as textual content, and checked for not unusual variable declaration and challenge patterns:

Particular Codecs

  • AWS credentials wisdom
  • JDBC connection strings
  • Jenkins config wisdom
  • SpringFramework Beans config wisdom
  • Java Properties wisdom
  • Dockercfg non-public registry auth wisdom
  • Github tokens


From PyPI

From GitHub

git clone
cd whispers
make prepare



whispers --help
whispers --info
whispers supply/code/fileOrDir
whispers --config config.yml supply/code/fileOrDir
whispers --output /tmp/secrets and techniques and methods and strategies.yml supply/code/fileOrDir
whispers --rules aws-id,aws-secret supply/code/fileOrDir
whispers --severity BLOCKER,CRITICAL supply/code/fileOrDir
whispers --exitcode 7 supply/code/fileOrDir


from whispers.cli import parse_args
from whispers.core import run

src = ""
configfile = "whispers/config.yml"
args = parse_args(["-c", configfile, src])
for secret in run(args):


There are a variety of configuration choices to be had in Whispers. It’s possible to incorporate/exclude ends up in protecting with file trail, key, or value. Report trail specs are interpreted as globs. Keys and values settle for now not peculiar expressions and somewhat numerous other different parameters. There’s a default configuration file integrated which may be used if you do not supply a customized one.

config.yml should have the next development:

come with:
- "**/*.yml"

- "**/check out/**/*"
- "**/exams/**/*"
- ^foo
- bar$

message: Whispers from the North
severity: CRITICAL
regex: (Aria|Ned) Stark
ignorecase: True

The quickest approach to tweak detection (ie: take away false positives and undesirable effects) is to copy the default config.yml into a brand new file, adapt it, and go it as an issue to Whispers.

whispers --config config.yml --rules starks src/file/or/dir

Customized Laws

Laws specify the true issues that are meant to be pulled out from key-value pairs. There are a variety of not unusual ones that come integrated, paying homage to AWS keys and passwords, on the other hand the device is made to be simply expandable with new guidelines.

  • Customized guidelines may also be outlined in the primary config file beneath guidelines:
  • Customized guidelines may also be added to whispers/guidelines
rule-id:  # distinctive rule decide
description: Values formatted like AWS Consultation Token
message: AWS Consultation Token # report will display this message
severity: BLOCKER # one in every of BLOCKER, CRITICAL, MAJOR, MINOR, INFO

key: # specify key construction
regex: (aws.?consultation.?token)?
ignorecase: True # case-insensitive matching

value: # specify value construction
regex: ^(?=.*[a-z])(?=.*[A-Z])[A-Za-z0-9+/]{270,450}$
ignorecase: False # case-sensitive matching
minlen: 270 # value is a minimum of this lengthy
isBase64: True # value is base64-encoded
isAscii: False # value is binary knowledge when decoded
isUri: False # value isn't formatted like a URI

equivalent: 0.35 # most allowed similarity between key and value
# (1.0 being precisely the an identical)


All parsing capability is carried out by means of plugins. Every plugin implements a category with the pairs() way that runs by the use of wisdom and returns the key-value pairs to be checked with guidelines.

class PluginName:
def pairs(self, file):
yield "key", "value"

Leave a Reply

Your email address will not be published. Required fields are marked *

Donate Us