Skip to main content

Identify secrets in static structured text

Project description

Whispers

"My little birds are everywhere, even in the North, they whisper to me the strangest stories." - Varys

Whispers is a static structured text analysis tool designed for parsing various common software config formats in search of hardcoded secrets. Whispers can be used as a CLI executable, as well as a Python library, which is meant to facilitate its integration into automated processes and pipelines.

Installation

pip3 install whispers

Supported formats

Detects

  • Passwords
  • API tokens
  • Cloud keys
  • Private keys
  • Hashed credentials
  • Authentication tokens
  • Webhooks
  • Sensitive files
  • Python functions
  • See all rules

Usage

CLI

# General usage & help
whispers

# More information about Whispers
whispers --info
# Simplest usage with JSON output
whispers dir/or/file

# Simplest usage with human-readable output
whispers -H dir/or/file

# Write results to a file instead of the screen
whispers -o /tmp/secrets.json dir/or/file

# Advanced usage:
#   - only check 'keys' rule group
#   - with BLOCKER or CRITICAL severity
#   - everywhere in target/dir except for .log & .raw files
whispers -g keys -s BLOCKER,CRITICAL -F '.*\.(log|raw)' target/dir
# Configuration file template
whispers --print_config > config.yml

# Provide custom configuration file
whispers --config config.yml dir/or/file

# Return this system code on success
whispers --exitcode 7 dir/or/file
# Include only 'aws-id' & 'aws-secret' rule IDs
whispers --rules aws-id,aws-secret dir/or/file

# Exclude 'file-known' rule ID
whispers --xrules file-known dir/or/file
# Include only 'keys' & 'misc' rule groups
whispers --groups keys,misc dir/or/file

# Exclude 'files' rule group
whispers --xgroups files dir/or/file
# Include only BLOCKER & CRITICAL severity
whispers --severity BLOCKER,CRITICAL dir/or/file

# Exclude all MINOR severity
whispers --xseverity MINOR dir/or/file
# Include only .json & .yml files
whispers --files '*.json,*.yml' dir/or/file

# Exclude .log & .cfg files
whispers --xfiles '.*\.(log|cfg)' dir/or/file

Python

import whispers

args = "-c whispers/config.yml -R file-known -S INFO tests/fixtures"

for secret in whispers.secrets(args):
  print(f"[{secret.file}:{secret.line}] {secret.key} = {secret.value}")

Config

There are several configuration options available in Whispers. It’s possible to include and exclude results based on file path, keys, values, individual or grouped rules, and severity levels. There is a default configuration file that will be used if you don't specify a custom one.

Note: all keys and static values are always included, and then filtered out based on config and rules.

  • File path specifications are lists of globs
  • Key and value specifications are lists of regular expressions
  • Rule specifications are lists of rule IDs or inline rule definitions
  • Everything else is a list of strings

Simple examples

Exclude all log files:

exclude:
  files:
    - .*\.log

Only scan for CRITICAL level findings in .npmrc files, excluding a known testing value:

include:
  files:
    - "**/*.npmrc"
  severity:
    - CRITICAL

exclude:
  values: 
    - ^token_for_testing$

General config format

include:
  files:
    - "**/*.yml"  # glob
  rules:
    - password
    - uri
    - id: starks  # inline rule
      message: Whispers from the North
      severity: CRITICAL
      value:
        regex: (Aria|Ned) Stark
        ignorecase: True
  groups:
    - keys
  severity:
    - CRITICAL
    - BLOCKER
    - MAJOR

exclude:
  files:
    - .*/tests?/  # regex
  keys:
    - ^foo        # regex
  values:
    - bar$        # regex
  rules:
    - apikey-known

The fastest way to tweak detection in a repeatable way (ie: remove false positives and unwanted results) is to copy the default config.yml into a new file, adapt it, and pass it as an argument to Whispers, for example:

whispers --print_config > custom.yml
# edit custom.yml as needed
whispers -c custom.yml target

Simple filtering based on rules and severity can also be done with CLI arguments directly, without having to provide a config file. See whispers --info for details.

Rules

Group Rule ID Severity
files file-known MINOR
infra dockercfg CRITICAL
infra htpasswd MAJOR
infra npmrc CRITICAL
infra pip CRITICAL
infra pypirc CRITICAL
keys apikey MAJOR
keys apikey-known CRITICAL
keys aws-id BLOCKER
keys aws-secret BLOCKER
keys aws-token BLOCKER
keys privatekey CRITICAL
misc comment INFO
misc creditcard MINOR
misc secret MINOR
misc webhook MINOR
passwords password CRITICAL
passwords uri CRITICAL
python cors MINOR
python system MINOR

Custom rules

Rules specify the actual things that should be pulled out from key-value pairs. There are several common ones that come built-in, such as AWS keys and passwords, but the tool is made to be easily expandable with new rules.

  • Custom rules can be defined in the main config file under rules: key
  • Custom rules can be added to whispers/rules directory

General rule format

- id: rule-id                 # unique rule name
  group: rule-group           # rule group 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 Jaro-Winkler similarity
                              # between key and value (1.0 being exactly the same)

Plugins

All parsing functionality is implemented via plugins. Each plugin implements a class with the pairs() method that runs through files and yields KeyValuePair objects to be checked with rules.

from pathlib import Path
from whispers.models.pair import KeyValuePair

class PluginName:
  def pairs(self, filepath: Path) -> Iterator[KeyValuePair]:
    yield KeyValuePair(
      "key",
      "value",
      keypath=["path", "to", "key"],
      file=filepath.as_posix()
    )

Development

git clone https://github.com/adeptex/whispers
cd whispers
make install-dev
make test

License

GNU General Public License v3.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

whispers-2.0.5.tar.gz (38.7 kB view details)

Uploaded Source

Built Distribution

whispers-2.0.5-py3-none-any.whl (47.2 kB view details)

Uploaded Python 3

File details

Details for the file whispers-2.0.5.tar.gz.

File metadata

  • Download URL: whispers-2.0.5.tar.gz
  • Upload date:
  • Size: 38.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.10

File hashes

Hashes for whispers-2.0.5.tar.gz
Algorithm Hash digest
SHA256 3343169cdc36a8e444bc036d5b8ccb131ce2aadec855efa72f0ed171f96375af
MD5 25b7c07b2149c531a88f22fb941e808b
BLAKE2b-256 fbc548ca84790bad31144ed698b90c18f2e2c4c8700d10bd253d037c00ba5e8f

See more details on using hashes here.

File details

Details for the file whispers-2.0.5-py3-none-any.whl.

File metadata

  • Download URL: whispers-2.0.5-py3-none-any.whl
  • Upload date:
  • Size: 47.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.10

File hashes

Hashes for whispers-2.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 1dc7efefc2f00332c8ba44fcc5d31d6b3dfb7d27d823a22dbc92cef4ebc3f179
MD5 5cd6df0ceaa2cc199b0e062e12bef7c7
BLAKE2b-256 4c2c562722b589ce0b2a9e53d946dad3c93c2411c2f6e859df1815dc2d16f41c

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page