Skip to content

Commit

Permalink
Add detect_secret_token
Browse files Browse the repository at this point in the history
  • Loading branch information
mxr committed Sep 6, 2023
1 parent 8ef58be commit d4eb9ec
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@
entry: detect-private-key
language: python
types: [text]
- id: detect-secret-token
name: detect secret token
description: detects the presence of RFC 8959 secret-token.
entry: detect-secret-token
language: python
types: [text]
- id: double-quote-string-fixer
name: fix double quoted strings
description: replaces double quoted strings with single quoted strings.
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ The following arguments are available:
#### `detect-private-key`
Checks for the existence of private keys.

#### `detect-secret-token`
Checks for the existence of RFC 8959 `secret-token`.

#### `double-quote-string-fixer`
This hook replaces double quoted strings with single quoted strings.

Expand Down
41 changes: 41 additions & 0 deletions pre_commit_hooks/detect_secret_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from __future__ import annotations

import argparse
import re
import sys
from typing import Sequence

# secret token is defined in https://datatracker.ietf.org/doc/html/rfc8959 as:
#
# secret-token-URI = secret-token-scheme ":" token
# secret-token-scheme = "secret-token"
# token = 1*pchar
#
# pchar is defined in https://www.rfc-editor.org/rfc/rfc3986#section-3.3 as:
#
# pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
SECRET_TOKEN_RE = re.compile(
'secret-token:('
r"[A-Za-z0-9\-._~!$&'()*+,;=:@]" # unreserved / sub-delims / ":" / "@"
'|%[0-9A-Fa-f]{2}' # pct-encoded
')+',
)


def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to check')
args = parser.parse_args(argv)

found = False
for filename in args.filenames:
with open(filename) as f:
if SECRET_TOKEN_RE.match(f.read()):
found = True
print(f'secret-token found: {filename}', file=sys.stderr)

return int(found)


if __name__ == '__main__':
raise SystemExit(main())
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ console_scripts =
destroyed-symlinks = pre_commit_hooks.destroyed_symlinks:main
detect-aws-credentials = pre_commit_hooks.detect_aws_credentials:main
detect-private-key = pre_commit_hooks.detect_private_key:main
detect-secret-token = pre_commit_hooks.detect_secret_token:main
double-quote-string-fixer = pre_commit_hooks.string_fixer:main
end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:main
file-contents-sorter = pre_commit_hooks.file_contents_sorter:main
Expand Down
36 changes: 36 additions & 0 deletions tests/detect_secret_token_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from __future__ import annotations

import pytest

from pre_commit_hooks.detect_secret_token import main


@pytest.mark.parametrize(
('input', 'expected'),
(
pytest.param(
'There is no secret here',
0,
id='no secret-token',
),
pytest.param(
'There is no secret here ☃',
0,
id='no secret-token unicode',
),
pytest.param(
'Read about using "secret-token:" in RFC 8959',
0,
id='has secret-token prefix only',
),
pytest.param(
'secret-token:E92FB7EB-D882-47A4-A265-A0B6135DC842%20foo',
1,
id='has secret-token',
),
),
)
def test_main(input, expected, tmpdir):
path = tmpdir.join('file.txt')
path.write(input)
assert main([str(path)]) == expected

0 comments on commit d4eb9ec

Please sign in to comment.