Skip to content

feat(detectors): add RSA SecurID software token detector#5106

Open
momomuchu wants to merge 3 commits into
trufflesecurity:mainfrom
momomuchu:detector-rsasecurid
Open

feat(detectors): add RSA SecurID software token detector#5106
momomuchu wants to merge 3 commits into
trufflesecurity:mainfrom
momomuchu:detector-rsasecurid

Conversation

@momomuchu

@momomuchu momomuchu commented Jul 2, 2026

Copy link
Copy Markdown

Description

Closes #4395.

Adds a detector for RSA SecurID software tokens distributed as .sdtid XML files. Each token export contains a <SN> serial (12 digits) and a <Seed> TOTP seed (128-bit hex, or an AES-encrypted seed in base64). The seed lets an attacker generate valid one-time passcodes and defeat the MFA factor, so both parts are reported as a multi-part credential (serial + seed).

Detection rationale

  • <SN>(\d{12})</SN> and <Seed>([A-Za-z0-9+/]{16,}={0,2})</Seed> must both be present.
  • A structural guard requires an RSA SecurID marker (<TKNBatch>, <TKNBasic>, or .sdtid) before emitting, so generic XML with unrelated <SN>/<Seed> elements is not flagged. This is the primary false-positive defense.
  • No public endpoint can validate a software token, so results are unverified.

Test coverage

8 pattern cases: 2 positive (hex seed, base64/encrypted seed) and 6 negative (SN only, Seed only, wrong element names, short seed, wrong-length serial, missing structural marker). All synthetic/fake values, no real token material.

Note on generated protobuf

proto/detector_type.proto is updated with the new RSASecurID enum, and the generated detector_type.pb.go carries the matching constant + name/value map entries so the package builds and the enum resolves. The embedded descriptor blob was not regenerated (the make protos toolchain runs in a pinned Docker image unavailable in my environment). Running make protos before merge will regenerate it cleanly from the updated proto source.

Checklist

  • go test ./pkg/detectors/rsasecurid/... passing
  • go vet / gofmt clean
  • Registered in pkg/engine/defaults

Note

Low Risk
Additive secret scanner with structural guards and no verification or auth changes; main risk is false positives on SecurID-shaped XML in repos.

Overview
Adds a new RSA SecurID detector for .sdtid XML exports that pairs a 12-digit <SN> with a <Seed> (hex or base64) and reports them as a multi-part credential (serial + seed, RawV2 as serial:seed). Detection requires SecurID structure markers (<TKNBatch>, <TKNBasic>, or .sdtid) so unrelated XML is ignored; there is no remote verification, so findings stay unverified.

Keywords() includes TKNBatch, TKNBasic, and sdtid so the Aho-Corasick prefilter does not skip valid blobs. Tests cover keyword/context alignment, a <TKNBasic>-only end-to-end path, and positive/negative pattern cases.

The scanner is wired into default detectors and DetectorType_RSASecurID (1058) is added in proto/detector_type.proto with matching generated Go enum/maps (descriptor blob updated in the diff).

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

@momomuchu
momomuchu requested a review from a team July 2, 2026 09:35
@momomuchu
momomuchu requested review from a team as code owners July 2, 2026 09:35
@CLAassistant

CLAassistant commented Jul 2, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Comment thread proto/detector_type.proto Outdated
Comment thread pkg/detectors/rsasecurid/rsasecurid.go
@momomuchu
momomuchu force-pushed the detector-rsasecurid branch from 3c57a83 to db29e15 Compare July 2, 2026 11:40
Comment thread pkg/pb/detector_typepb/detector_type.pb.go

@rajpratham1 rajpratham1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Good addition overall, but I think the Cursor finding is valid. contextPat recognizes both and , whereas Keywords() only returns "TKNBatch" and "sdtid". Since the Aho-Corasick prefilter gates execution of FromData, a valid token containing only may never be scanned. Could you add "TKNBasic" to Keywords() (or otherwise align the prefilter with contextPat) so all supported formats are reachable?

momomuchu added 2 commits July 3, 2026 19:47
…flesecurity#4395

Detects RSA SecurID software tokens distributed as .sdtid XML files. A
token export contains a <SN> element (12-digit serial number) and a <Seed>
element (the TOTP seed, either a 128-bit hex value or an AES-encrypted seed
in base64). Possession of the seed lets an attacker generate valid one-time
passcodes, so both parts are emitted as a multi-part credential
(serial + seed).

False-positive defense: results are only emitted when an RSA SecurID
structural marker (<TKNBatch>, <TKNBasic>, or the .sdtid extension) is
present, so generic XML containing unrelated <SN>/<Seed> elements is not
reported. The serial must be exactly 12 digits and the seed at least 16
characters.

No public endpoint can validate a software token, so results are
unverified. Registers the detector in pkg/engine/defaults and adds the
RSASecurID (1057) enum to proto/detector_type.proto and the generated
detector_typepb constants/maps.
… tokens are scanned, review feedback trufflesecurity#5106

contextPat matches <TKNBatch, <TKNBasic and .sdtid, but Keywords() only
advertised "TKNBatch" and "sdtid". The Aho-Corasick prefilter gates FromData
on Keywords(), so a token whose only structural marker is <TKNBasic> (no
TKNBatch/sdtid literal) was dropped before ever being scanned.

Add "TKNBasic" so every literal in contextPat has a covering keyword. Adds a
BDD given/when/then test proving a <TKNBasic>-only token is now detected
end-to-end through the real prefilter path, plus a structural test asserting
every contextPat marker has a matching keyword. Existing negative controls
unchanged.
momomuchu added a commit to momomuchu/trufflehog that referenced this pull request Jul 3, 2026
… tokens are scanned — review feedback trufflesecurity#5106

contextPat matches <TKNBatch, <TKNBasic and .sdtid, but Keywords() only
advertised "TKNBatch" and "sdtid". The Aho-Corasick prefilter gates FromData
on Keywords(), so a token whose only structural marker is <TKNBasic> (no
TKNBatch/sdtid literal) was dropped before ever being scanned.

Add "TKNBasic" so every literal in contextPat has a covering keyword. Adds a
BDD given/when/then test proving a <TKNBasic>-only token is now detected
end-to-end through the real prefilter path, plus a structural test asserting
every contextPat marker has a matching keyword. Existing negative controls
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@momomuchu
momomuchu force-pushed the detector-rsasecurid branch from db29e15 to 73453d4 Compare July 3, 2026 17:49
@momomuchu

Copy link
Copy Markdown
Author

Addressed: Keywords() now returns ["TKNBatch", "TKNBasic", "sdtid"] so a <TKNBasic>-only token survives the Aho-Corasick prefilter, plus a test that scans a TKNBasic-only blob through the real prefilter path. Ready for another look.

@momomuchu
momomuchu force-pushed the detector-rsasecurid branch from 73453d4 to 7c23b44 Compare July 5, 2026 14:44

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

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.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 7c23b44. Configure here.

Comment thread proto/detector_type.proto Outdated
@momomuchu

Copy link
Copy Markdown
Author

Good catch. Fixed: RSASecurID now uses 1058, the next free value on main after OpenRouter = 1057. Regenerated detector_type.pb.go via make protos so the constant, the name/value maps, and the binary descriptor all match (that also clears the earlier stale-descriptor String() issue). Note the sibling PR #5105 also targets 1058; whichever merges second I'll rebase-bump by one.

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.

Add support for RSA SecurID MFA software tokens

3 participants