Skip to content

New Detector: TelerikLicenseKey [1039]#4479

Open
LanceMcCarthy wants to merge 18 commits intotrufflesecurity:mainfrom
LanceMcCarthy:prgs-devtools-license-key-detector
Open

New Detector: TelerikLicenseKey [1039]#4479
LanceMcCarthy wants to merge 18 commits intotrufflesecurity:mainfrom
LanceMcCarthy:prgs-devtools-license-key-detector

Conversation

@LanceMcCarthy
Copy link
Copy Markdown

@LanceMcCarthy LanceMcCarthy commented Sep 29, 2025

Description:

Added new detector for Telerik and Kendo License Keys (https://www.telerik.com). These JWTs are secrets which contain license information that must not be in source code.

This detector does everything locally by checking only the JWT's header for the typ attribute for our unique value "Telerik License Key".

Optimized Performance

There are no remote API calls to perform the detector's work, so I've also optimized the detector code and tests by removing httpClient usage for the following benefits:

✅ Reduced Dependencies, Cleaner Code, Better Performance: No HTTP client overhead (mocked or not)
✅ Simpler Testing: Tests are more focused on actual JWT validation logic
✅ All Tests Pass: Both unit tests and integration tests work perfectly (and the benchmarks look good too)

Tests

In my tests, there are two hard coded JWTs secret and inactiveSecret. This is nothing to be concerned about, they are sample values generated specifically for long term testing support and are not secrets.

One has the expected header value to verify a confirmed positive hit, while the other is like any other normal JWT, and does not trigger a false positive.

image

Note

If these test keys trigger your secret-detection workflow, please let me know how to add an ignore for them. Alternatively, I can switch back to the GCP approach, but that was giving me nothing but headaches.

Checklist:

  • ✅ Tests passing (make test-community)?
    • image
  • Lint passing (make lint this requires golangci-lint)?
    • I attempted to run this, but it seems to be an outdated instruction as there's a default flag not accepted. Might be outdated tooling in the GitHub Codespace, I can rerun with additional instructions.
    • image

[EDIT] Spelling corrections, and added links/note about the test keys.


Note

Medium Risk
Adds a new detector type/enum and enables it by default, which can change scan results (new findings/false positives) and slightly affect performance due to additional pattern matching on all scans.

Overview
Introduces a new teleriklicensekey detector that matches JWT-shaped tokens and locally validates them by decoding the JWT header and requiring typ == "Telerik License Key" (no remote verification).

Registers the detector in defaults.go, adds the new DetectorType_TelerikLicenseKey enum value in detector_type.proto (and regenerated protobufs), and expands tests to cover detector parsing/stringification plus unit/integration coverage for matching/filtering long JWT chunks.

Reviewed by Cursor Bugbot for commit b39f67a. Bugbot is set up for automated code reviews on this repo. Configure here.

@LanceMcCarthy LanceMcCarthy requested review from a team as code owners September 29, 2025 18:59
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Sep 29, 2025

CLA assistant check
All committers have signed the CLA.

@LanceMcCarthy
Copy link
Copy Markdown
Author

Hi Team,

A couple notes/questions:

  • Once it's time for merge, please consider squash to avoid the mess. I have a few commits in there just so I could move between my local environment to GH Codespaces.
  • I'd like to ask how detector updates work. For example, if we introduce new key types, can I update this detector. If yes, are they versioned or just continuous improvement?

Thanks!

@LanceMcCarthy LanceMcCarthy changed the title New Detector: TelerikLicenseKey New Detector: TelerikLicenseKey [1039] Sep 29, 2025
@shahzadhaider1
Copy link
Copy Markdown
Contributor

Hey @LanceMcCarthy, thanks for the contribution! We’ll review the PR and share feedback if needed.

Regarding detector updates: if a secret type is deprecated and no longer works for authentication, we update the existing detector. But if a new key type is introduced while the old one still works, we create a new version (v2) of the detector that supports the new key type, and move the old type into v1. That way, we can maintain both versions of the detector side by side.

For more info: https://github.com/trufflesecurity/trufflehog/blob/main/hack/docs/Adding_Detectors_external.md

@LanceMcCarthy
Copy link
Copy Markdown
Author

Thank you for the prompt follow up and answers @shahzadhaider1! I was eagerly awaiting the results of the checks because I couldn't run the linter manually, but the two linter workflows/check look good :)

My remaining worry was if the 'scan for secrets` check would throw a false positive because of my test JWTs. Is there a reason they were skipped, do I need the code review first?

@LanceMcCarthy
Copy link
Copy Markdown
Author

Hi @shahzadhaider1 I just wanted to hop in and see if there's anything I can do to help speed things up.

I also suspect that by the time this is ready, I'll need to change the detector ID as newer detectors are added before this is merged. Let me know how you guys prefer to handle this; do I push a commit with n+1 or do you do it?

@LanceMcCarthy
Copy link
Copy Markdown
Author

Hi @shahzadhaider1 I wanted to check in with you again. Is there anything I can do to help speed tings up? Is there something I missed?

@shahzadhaider1
Copy link
Copy Markdown
Contributor

Hi @shahzadhaider1 I wanted to check in with you again. Is there anything I can do to help speed tings up? Is there something I missed?

Hey @LanceMcCarthy, we’re currently pausing the addition of new detectors. We’ll get this merged once we’ve refined our process for maintaining them.

@LanceMcCarthy
Copy link
Copy Markdown
Author

Hi @shahzadhaider1 I wanted to check in with you again. Is there anything I can do to help speed tings up? Is there something I missed?

Hey @LanceMcCarthy, we’re currently pausing the addition of new detectors. We’ll get this merged once we’ve refined our process for maintaining them.

Ah! Okay, thanks for letting me know that the delay is not due to something on my side.

@LanceMcCarthy
Copy link
Copy Markdown
Author

LanceMcCarthy commented Apr 6, 2026

@shahzadhaider1 Hi Shahzad, is there any progress on this? Are there ways I can assist?

Rebasing to catch up on 5 months of changes, and adding my detector on the end of the newest

✅ Reduced Dependencies: No longer depends on HTTP client libraries
✅ Cleaner Code: Removed unused HTTP client logic
✅ Better Performance: No HTTP client initialization overhead
✅ Simpler Testing: Tests are more focused on actual JWT validation logic
✅ All Tests Pass: Both unit tests and integration tests work perfectly
@LanceMcCarthy LanceMcCarthy force-pushed the prgs-devtools-license-key-detector branch from 1e3041f to a768ee8 Compare April 6, 2026 16:08
@LanceMcCarthy LanceMcCarthy requested a review from a team as a code owner April 6, 2026 16:08
Comment thread pkg/detectors/teleriklicensekey/teleriklicensekey.go
Comment thread pkg/pb/detectorspb/detectors.pb.go Outdated
This resolves two items raised in the PR

- ☑️ Missing MaxSecretSizeProvider causes truncation of long JWTs
- ☑️ Protobuf name/value maps missing TelerikLicenseKey entry
- Additional refinements.
Comment thread pkg/detectors/teleriklicensekey/teleriklicensekey.go Outdated
Comment thread pkg/detectors/teleriklicensekey/teleriklicensekey.go
Resolved:

- Regex character class has unintended range operator
- Detector not registered in engine defaults
Comment thread pkg/engine/defaults/defaults.go Outdated
Comment thread pkg/detectors/teleriklicensekey/teleriklicensekey_integration_test.go Outdated
Comment thread pkg/detectors/teleriklicensekey/teleriklicensekey.go Outdated
Comment thread pkg/detectors/teleriklicensekey/teleriklicensekey_integration_test.go Outdated
Can someone change the Bugbot setting so that it can give you more than 2 at time to fix?
Comment thread pkg/detectors/teleriklicensekey/teleriklicensekey.go
Comment thread pkg/detectors/teleriklicensekey/teleriklicensekey_test.go Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 33d14f8. Configure here.

Comment thread pkg/detectors/teleriklicensekey/teleriklicensekey.go Outdated
…low Bugbot to report all unique items at once)
@LanceMcCarthy
Copy link
Copy Markdown
Author

Okay after the Bugbot review and adjustments, @shahzadhaider1 it's ready :D

IF I had any feedback for you team, see if Bugbot has a setting that allows for more than 2 issues at once. While yes, I understand newly introduced issue, but this was 95% existing issues that could have bene listed in a single recommendation flow

@LanceMcCarthy
Copy link
Copy Markdown
Author

@shahzadhaider1 can you please review this again. I have

Pulled in all the changes from main
Completely migrated my detector to the new approach

Everything lines up to how you need it, you can squash this into a single commit and it will line up perfectly.

Here's the latest test result:

go test -v ./pkg/config ./pkg/detectors/teleriklicensekey -tags=detectors

=== RUN   TestDetectorParsing
...
=== RUN   TestDetectorParsing/new_detector_by_name
...
--- PASS: TestDetectorParsing (0.00s)
...
=== RUN   TestDetectorIDString
--- PASS: TestDetectorIDString (0.00s)
PASS
ok      github.com/trufflesecurity/trufflehog/v3/pkg/config     4.047s

=== RUN   TestTeleriklicensekey_FromChunk
=== RUN   TestTeleriklicensekey_FromChunk/found,_not_verified
=== RUN   TestTeleriklicensekey_FromChunk/non-telerik_jwt_is_filtered
=== RUN   TestTeleriklicensekey_FromChunk/not_found
--- PASS: TestTeleriklicensekey_FromChunk (0.00s)
...
=== RUN   TestTeleriklicensekey_Pattern
=== RUN   TestTeleriklicensekey_Pattern/Valid_JWT_-_Telerik_License_Key
=== RUN   TestTeleriklicensekey_Pattern/Malformed_JWT_-_no_JWT_pattern_detected
=== RUN   TestTeleriklicensekey_Pattern/No_JWT_present
--- PASS: TestTeleriklicensekey_Pattern (0.00s)
=== RUN   TestTeleriklicensekey_LongJWTChunkSpan
--- PASS: TestTeleriklicensekey_LongJWTChunkSpan (0.00s)
PASS
ok      github.com/trufflesecurity/trufflehog/v3/pkg/detectors/teleriklicensekey 2.828s

@shahzadhaider1
Copy link
Copy Markdown
Contributor

@shahzadhaider1 can you please review this again. I have

Pulled in all the changes from main Completely migrated my detector to the new approach

Everything lines up to how you need it, you can squash this into a single commit and it will line up perfectly.

Here's the latest test result:

go test -v ./pkg/config ./pkg/detectors/teleriklicensekey -tags=detectors

=== RUN   TestDetectorParsing
...
=== RUN   TestDetectorParsing/new_detector_by_name
...
--- PASS: TestDetectorParsing (0.00s)
...
=== RUN   TestDetectorIDString
--- PASS: TestDetectorIDString (0.00s)
PASS
ok      github.com/trufflesecurity/trufflehog/v3/pkg/config     4.047s

=== RUN   TestTeleriklicensekey_FromChunk
=== RUN   TestTeleriklicensekey_FromChunk/found,_not_verified
=== RUN   TestTeleriklicensekey_FromChunk/non-telerik_jwt_is_filtered
=== RUN   TestTeleriklicensekey_FromChunk/not_found
--- PASS: TestTeleriklicensekey_FromChunk (0.00s)
...
=== RUN   TestTeleriklicensekey_Pattern
=== RUN   TestTeleriklicensekey_Pattern/Valid_JWT_-_Telerik_License_Key
=== RUN   TestTeleriklicensekey_Pattern/Malformed_JWT_-_no_JWT_pattern_detected
=== RUN   TestTeleriklicensekey_Pattern/No_JWT_present
--- PASS: TestTeleriklicensekey_Pattern (0.00s)
=== RUN   TestTeleriklicensekey_LongJWTChunkSpan
--- PASS: TestTeleriklicensekey_LongJWTChunkSpan (0.00s)
PASS
ok      github.com/trufflesecurity/trufflehog/v3/pkg/detectors/teleriklicensekey 2.828s

Hey, thanks for your patience--this is solid work and the implementation looks good overall.
I do have one concern though: the regex pattern used here appears to overlap with the existing JWT detector in TruffleHog. I did a quick local test with the latest version, using the sample secret from your test, and it was already detected by the JWT detector.

I might be missing something, but do you think this detector adds meaningful value given that similar secrets are already being caught? Would be great to understand if there are cases this would uniquely cover.

@amanfcp
Copy link
Copy Markdown
Contributor

amanfcp commented Apr 16, 2026

Hey @LanceMcCarthy, thanks for the contribution.

We’re currently prioritizing updates to high-usage/high-impact detectors. Other detector PRs are being queued and will be reviewed and merged based on their relative impact.

We’re also being deliberate with detector additions/updates to maintain signal quality and avoid regressions or anomalous behavior observed in prior changes.

@LanceMcCarthy
Copy link
Copy Markdown
Author

Hi team!

@shahzadhaider1
I will review it again, but the last time I checked, the default TruffleHog JWT detector did not match our license keys. Today, I will run a test against a large amount of sample keys niu another rpo, using the latest release of trufflehog, then I'll come back here and share the results.

@amanfcp
Understood, thank you. To be clear, I'm not proposing this is a high-priority opsec detector. Rather it is an infosec detector, it is important for Progress Software and all of our customers; they don't want to leak their license keys, and it is a very common mistake on their part.

Thank you both for taking the time to discuss, I sincerely appreciate it. Shahzad, I will get back to you with the results of my test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants