|
| 1 | +from __future__ import absolute_import |
| 2 | + |
| 3 | +import pytest |
| 4 | + |
| 5 | +from detect_secrets.plugins.jwt import JwtTokenDetector |
| 6 | + |
| 7 | + |
| 8 | +class TestJwtTokenDetector(object): |
| 9 | + |
| 10 | + @pytest.mark.parametrize( |
| 11 | + 'payload, should_flag', |
| 12 | + [ |
| 13 | + # valid jwt |
| 14 | + ('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c', True), # noqa: E501 |
| 15 | + # valid jwt - but header contains CR/LF-s |
| 16 | + ('eyJ0eXAiOiJKV1QiLA0KImFsZyI6IkhTMjU2In0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ', True), # noqa: E501 |
| 17 | + # valid jwt - but claims contain bunch of LF newlines |
| 18 | + ('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSm9lIiwKInN0YXR1cyI6ImVtcGxveWVlIgp9', True), # noqa: E501 |
| 19 | + # valid jwt - claims contain strings with unicode accents |
| 20 | + ('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IsWww6HFkcOtIMOWxZHDqcOoIiwiaWF0IjoxNTE2MjM5MDIyfQ.k5HibI_uLn_RTuPcaCNkaVaQH2y5q6GvJg8GPpGMRwQ', True), # noqa: E501 |
| 21 | + # as unicode literal |
| 22 | + (u'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c', True), # noqa: E501 |
| 23 | + # no signature - but still valid |
| 24 | + ('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ', True), # noqa: E501 |
| 25 | + # decoded - invalid |
| 26 | + ('{"alg":"HS256","typ":"JWT"}.{"name":"Jon Doe"}.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c', False), # noqa: E501 |
| 27 | + # invalid json - invalid (caught by regex) |
| 28 | + ('bm90X3ZhbGlkX2pzb25fYXRfYWxs.bm90X3ZhbGlkX2pzb25fYXRfYWxs.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c', False), # noqa: E501 |
| 29 | + # missing claims - invalid |
| 30 | + ('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', False), # noqa: E501 |
| 31 | + # totally not a jwt |
| 32 | + ('jwt', False), # noqa: E501 |
| 33 | + # invalid json with random bytes |
| 34 | + ('eyJhbasdGciOiJIUaddasdasfsasdasdzI1NiIasdsInR5cCI6IkpXVCasdJasd9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c', False), # noqa: E501 |
| 35 | + # invalid json in jwt header - invalid (caught by parsing) |
| 36 | + ('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c', False), # noqa: E501 |
| 37 | + # good by regex, but otherwise totally not JWT |
| 38 | + ('eyJAAAA.eyJBBB', False), # noqa: E501 |
| 39 | + ('eyJBB.eyJCC.eyJDDDD', False), # noqa: E501 |
| 40 | + ], |
| 41 | + ) |
| 42 | + def test_analyze_string(self, payload, should_flag): |
| 43 | + logic = JwtTokenDetector() |
| 44 | + |
| 45 | + output = logic.analyze_string(payload, 1, 'mock_filename') |
| 46 | + assert len(output) == int(should_flag) |
0 commit comments