Skip to content

Commit

Permalink
62 check for gitleaks and trufflehog before program runs (#66)
Browse files Browse the repository at this point in the history
* feat: added gitleaks and trufflehog detection

* chore: ran black

* feat: adjusted tests

* chore: ran black

* feat: Update backends and fix tests

feat: Update gitleaks
feat: Update trufflehog
feat: Fix tests

* feat: Run black

---------

Co-authored-by: Alex Brozych <alex.brozych@punksecurity.co.uk>
  • Loading branch information
VKotwicki and alexbrozych authored Jul 9, 2024
1 parent fb25ed4 commit 45968bd
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 14 deletions.
22 changes: 22 additions & 0 deletions argparsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import math
from os import linesep, environ, cpu_count
import sys
import shutil

runtime = environ.get("SM_COMMAND", f"{sys.argv[0]}")

Expand All @@ -24,6 +25,10 @@
parallel = math.ceil(cores / 4)


def check_exists(var):
return shutil.which(var)


class CustomParser(argparse.ArgumentParser):
def error(self, message):
sys.stdout.write(f" ❌ error: {message}{linesep}{linesep}")
Expand Down Expand Up @@ -210,4 +215,21 @@ def parse_args():

if args.gl_config is not None and args.disable_gitleaks:
parser.error("Gitleaks can't be disabled if passing a .toml file")

if not args.disable_gitleaks:
gitleaks = check_exists("gitleaks")

if not isinstance(gitleaks, str) or len(gitleaks) == 0:
parser.error(
"Could not find Gitleaks on your system. Ensure it's on the PATH or pass --disable-gitleaks"
)

if not args.disable_trufflehog:
trufflehog = check_exists("trufflehog")

if not isinstance(trufflehog, str) or len(trufflehog) == 0:
parser.error(
"Could not find Trufflehog on your system. Ensure it's on the PATH or pass --disable-trufflehog"
)

return args
4 changes: 2 additions & 2 deletions dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.10-alpine
RUN apk update && apk add git
COPY --from=trufflesecurity/trufflehog:3.20.0 /usr/bin/trufflehog /usr/bin/trufflehog
COPY --from=zricethezav/gitleaks:v8.15.2 /usr/bin/gitleaks /usr/bin/gitleaks
COPY --from=trufflesecurity/trufflehog:3.79.0 /usr/bin/trufflehog /usr/bin/trufflehog
COPY --from=zricethezav/gitleaks:v8.18.4 /usr/bin/gitleaks /usr/bin/gitleaks
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

Expand Down
50 changes: 43 additions & 7 deletions features/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import stat
import subprocess

from unittest.mock import patch

from behave import given, when, then, step


Expand Down Expand Up @@ -54,7 +56,16 @@ def step_impl(context, name):
f.write(context.text)


def run_secret_magpie(context, engines, outformat="csv", args=[]):
@given("{binary} is not present")
def step_impl(context, binary):
try:
context.patches
except:
context.patches = []
context.patches.append((["shutil.which"], {"return_value": None}))


def run_secret_magpie(context, engines, outformat="csv", args=[], err_check=True):
try:
context.repos = LocalRepos(context.rules, TESTING_DIRECTORY)
except:
Expand All @@ -64,6 +75,17 @@ def run_secret_magpie(context, engines, outformat="csv", args=[]):

param_list = []

patchers = []

try:
context.patches
patchers = list(map(lambda p: patch(*p[0], **p[1]), context.patches))
except:
pass

for patcher in patchers:
patcher.start()

match context.repo_type:
case "local":
param_list = [
Expand Down Expand Up @@ -160,14 +182,15 @@ def run_secret_magpie(context, engines, outformat="csv", args=[]):
param_list, capture_output=True, env=env, encoding="UTF-8"
)

if context.proc.stderr != "":
raise AssertionError(context.proc.stderr)
if err_check:
if context.proc.stderr != "":
raise AssertionError(context.proc.stderr)

if "❌" in context.proc.stdout:
raise AssertionError(context.proc.stdout)
if "❌" in context.proc.stdout:
raise AssertionError(context.proc.stdout)

if "warning" in context.proc.stdout:
raise AssertionError(context.proc.stdout)
if "warning" in context.proc.stdout:
raise AssertionError(context.proc.stdout)

stdout = context.proc.stdout.split("\n")

Expand All @@ -194,6 +217,9 @@ def run_secret_magpie(context, engines, outformat="csv", args=[]):
except:
context.found_unique = 0

for patcher in reversed(patchers):
patcher.stop()


@when("we run secret-magpie-cli with engines: {engines}")
def step_impl(context, engines):
Expand Down Expand Up @@ -366,6 +392,16 @@ def step_impl(context):
)


@then("secret-magpie-cli's error output will be")
def step_impl(context):
stderr = context.proc.stdout
expected = list(map(lambda s: s.rstrip("\r"), context.text.split("\n")))

assert str(expected) not in str(stderr), (
"Expected error output: " + str(expected) + ", found " + str(stderr)
)


@then("directory {dir} won't exist")
def step_impl(context, dir):
assert (
Expand Down
2 changes: 1 addition & 1 deletion features/match_files/Gitleaks.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[
[
{
"Description": "Private Key",
"Description": "Identified a Private Key, which may compromise cryptographic security and sensitive data encryption.",
"StartLine": 1,
"EndLine": 16,
"StartColumn": 1,
Expand Down
3 changes: 2 additions & 1 deletion features/match_files/Trufflehog.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
}
}
},
"SourceID": 0,
"SourceID": 1,
"SourceType": 16,
"SourceName": "trufflehog - git",
"DetectorType": 15,
"DetectorName": "PrivateKey",
"DecoderName": "PLAIN",
"Verified": false,
"Raw": "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAIEAuaJtfDkJfu0BhyQACpCeu6y1hWPHEN6kXbKJ4Da5ammYQrrmUjLS\nWJXhU8i8tM1438ZuJiA+49ZDP/Kh6P8Hs9GulRuYDNa9a+WuZurcsKUvr5WDK67KX7mU8K\nR0+1XkN6tzXTaBdjZldOGQ+V3DXAsWoWHbkzL6Cm1Iy6w57msAAAIAH+jd2h/o3doAAAAH\nc3NoLXJzYQAAAIEAuaJtfDkJfu0BhyQACpCeu6y1hWPHEN6kXbKJ4Da5ammYQrrmUjLSWJ\nXhU8i8tM1438ZuJiA+49ZDP/Kh6P8Hs9GulRuYDNa9a+WuZurcsKUvr5WDK67KX7mU8KR0\n+1XkN6tzXTaBdjZldOGQ+V3DXAsWoWHbkzL6Cm1Iy6w57msAAAADAQABAAAAgFRV1MPQ7d\n16M22AD3y9Q0AkMLuPHwss+yOOT1FLy2Tq4D/AxY6mhCW2wg3cbs79YmLXtYcgszGzUA4n\nXyOJaaekEVVgmeH8214bckwSIDadtDiIBLKZJ6thQOjk7ijS2ZCq/8PQdK4j7J2/Nl9X3e\n0ciE8lbU49occQl1ppE8aRAAAAQQDXkWIMdUhnSZ3LRkSBpLOEXiJ9UEHHNYg3dNZSmqK1\nLhNRpiY5GJAMBGPXujt6oGyoSCLCSqU9ckOUN8I+LRtuAAAAQQDaKzn9XIkNQjtbMDO4lx\ni/94me4HgbgrJjWdsmKpNJd6pMTXaIjCv992MWKIp4tv/uuMQNRuqiNHGeDZbwFDKPAAAA\nQQDZ0vZDS/MF4T2nmkkZyDEzSG5bf3pzZVpopTwidC2bbKRxsvRiDMHz0+iGbtNNJKq183\nUJor65LswerJbV7ERlAAAABm5vbmFtZQECAwQ=\n-----END OPENSSH PRIVATE KEY-----\n",
"RawV2": "",
"Redacted": "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5v",
"ExtraData": null,
"StructuredData": null
Expand Down
4 changes: 1 addition & 3 deletions features/steps/fuzzy_validate_output_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ def step_impl(context, file):
with open("features/match_files/" + file) as f:
expected_json = json.loads(f.read())

assert recursive_compare_json(
expected_json, context.json
), "JSON output did not match!"
assert recursive_compare_json(expected_json, context.json), context.json


def do_match_test(format, expected):
Expand Down
18 changes: 18 additions & 0 deletions features/validate_output.feature
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,21 @@ Feature: Validate that the results files produced by secret-magpie-cli is of val
"""
ERROR: File at rules_not_found.toml not found.
"""

@localrepos
Scenario: Ensure that secret-magpie-cli gives the expected error when gitleaks is not found
Given gitleaks is not present
When we run secret-magpie-cli with engines: gitleaks
Then secret-magpie-cli's error output will be
"""
❌ error: Could not find Gitleaks on your system. Ensure it's on the PATH or pass --disable-gitleaks
"""

@localrepos
Scenario: Ensure that secret-magpie-cli gives the expected error when trufflehog is not found
Given trufflehog is not present
When we run secret-magpie-cli with engines: trufflehog
Then secret-magpie-cli's error output will be
"""
❌ error: Could not find Trufflehog on your system. Ensure it's on the PATH or pass --disable-trufflehog
"""

0 comments on commit 45968bd

Please sign in to comment.