2ms (too many secrets) Integration with DefectDojo
2ms (too many secrets) Integration with DefectDojo
2ms, short for "too many secrets", is an open source secrets scanner maintained by Checkmarx and released under the Apache 2.0 license. Built on the gitleaks detection engine, it looks for credentials, API keys, tokens, and other sensitive values in local directories and git repositories, and also in collaboration platforms such as Confluence, Slack, Discord, and Paligo, each through its own subcommand. Every rule carries a severity and a CVSS score, and reports can be written as JSON, YAML, or SARIF. DefectDojo imports the JSON report.
2ms (too many secrets) Integration with DefectDojo
We picked 2ms because secrets do not only leak into code. They end up in wiki pages and chat threads too, and one tool can scan all of those. DefectDojo is where the results get worked. Each 2ms result imports as a Finding with the severity and CVSS score 2ms assigned, the location and line it was found at, and remediation text that says to revoke and rotate. When the same secret shows up in five places, each location is its own Finding, so nothing gets closed until every copy is dealt with.
Why 2ms (too many secrets) Matters
Code scanners cover repositories. Many leaks happen elsewhere: a token pasted into a Confluence runbook, a key shared in a Slack channel during an incident.
- One CLI scans filesystems, git history, and several collaboration platforms, so coverage does not depend on stitching tools together.
- It builds on the gitleaks rule engine, which recognizes a wide set of credential formats.
- Each rule has a severity and CVSS score, so results arrive already graded instead of as a flat list.
- Results include a validation status field, which DefectDojo keeps in the Finding description for triage.
- It is open source and runs locally or in CI, with no hosted service required.
Advantages of This Integration
- Severity and CVSS preserved. 2ms severities (Critical through Info) map one to one, and the CVSS score is stored on the Finding, so SLAs and sorting follow the tool's own grading.
- One Finding per location. 2ms groups results by the identity it gives each secret. DefectDojo keeps each location as its own Finding and records the shared secret id in the description, so you can see every place one credential appears.
- Precise deduplication. Findings are hashed on title, file path, line, and description. The description is included because 2ms can report two different secrets on the same line of the same file.
- Reimport lifecycle. Reimporting into the same Test mitigates secrets that were removed, adds new ones, and reactivates any that reappear.
- Clear remediation. Every Finding carries the same instruction: revoke and rotate the secret, then remove it from source history.
- Shared triage. Findings can be assigned to the owner of the repository or space, pushed to Jira, risk accepted, or marked false positive like any other finding.
How This Integration Works
DefectDojo imports 2ms output with the 2ms Scan scan type.
1. Produce a JSON report. Scan a directory and write a JSON report. 2ms infers the report format from the file extension given to --report-path:
2ms filesystem --path . --report-path 2ms-report.json
Other targets use their own subcommands (for example 2ms git for a repository, or 2ms confluence for a Confluence space) and write the same JSON report. The parser reads the results object, which groups results by secret id.
2. Import it. In the UI, open the Engagement, choose Import Scan Results, select 2ms Scan, and upload the file. For automation, use the API in Community Edition or DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/"
-H "Authorization: Token $DD_API_TOKEN"
-F "scan_type=2ms Scan"
-F "file=@2ms-report.json"
-F "product_name=platform-docs"
-F "engagement_name=Secrets"
-F "auto_create_context=true"
DefectDojo Pro users can use Universal Importer:
universal-importer import
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/"
--scan-type "2ms Scan"
--report-path "./2ms-report.json"
--product-name "platform-docs"
--engagement-name "Secrets"
--auto-create-context
3. Reimport on a schedule. Send later reports for the same target to /api/v2/reimport-scan/ against the same Test so findings keep their history.
Data Granularity: What Gets Imported
| DefectDojo Field | Source in 2ms Report | Notes |
|---|---|---|
| Title | ruleName |
Formatted as Secret detected: <rule> |
| Severity | severity |
Critical, High, Medium, Low, Info map directly; unknown values are Medium |
| CVSS v3 Score | cvssScore |
Stored when present |
| Description | Rule and match details | Rule description, source, category, validation status, line content, secret id |
| File Path | source |
Location 2ms reported for the secret |
| Line | startLine |
Start line of the match |
| Vulnerability ID from tool | ruleId |
2ms rule identifier |
| Mitigation | Fixed text | Revoke and rotate the secret, then remove it from source history |
| Finding type | Static | All findings are static |
| Deduplication | Hashcode | Title, file path, line, description |
Use Cases
Beyond the repository: A security team runs 2ms against the engineering Confluence space weekly and imports into a "Documentation" Asset. Credentials pasted into runbooks become Findings assigned to the page owners, with SLAs by severity.
In a CI/CD pipeline: Each merge runs 2ms git or 2ms filesystem on the repository and reimports into the repository's Test. New High and Critical findings fail the build through a DefectDojo API check, while accepted test fixtures stay out of the way.
Tracking one leaked credential: The secret id in the description is shared by every location of the same secret. Searching for it shows every file or page that still holds the value, which is the list to clean up after rotation.
Reporting exposure by team: Because each location is a Finding on the owning Asset, security leads can report open secrets by team and severity, including those found outside code.
Operational Tips
- The description includes the line content 2ms matched, which can contain the secret itself. Restrict who can view these Findings, and rotate rather than relying on the value staying hidden.
- The description is part of the hashcode. If anything in it changes between scans, such as the validation status, the next reimport treats the result as a new Finding and mitigates the old one.
- Close a Finding only after the secret is revoked. Deleting it from the file or page does not invalidate copies already cloned, cached, or exported.
- Use one Test per scan target (a repository, a Confluence space, a Slack workspace) so each source has its own history.
- Tag imports with the source type, for example
confluenceorgit, to report where secrets are leaking most. - Mark test fixtures and sample values as false positives once, and the same location will stay matched on future reimports.