Scanning & correlation
How raw scanner output becomes one clean list of findings.
Semgrep (JSON) ─┐
├─► normalise ─► merge duplicates ─► group by fix ─► findings.json ─► triage
CodeQL (SARIF) ─┘
1. Two scanners, in parallel
SecureSense runs Semgrep (pattern rules, output as JSON) and CodeQL (semantic data-flow queries, output as SARIF, the standard format for static-analysis tools) at the same time as background processes. CodeQL's database is cached per project, so later scans are faster. If one scanner fails, the other's results are still used.
2. Normalise
The two formats describe findings differently. Each hit is converted into one common shape — file, lines, CWE number, severity, message, rule id — with paths made relative to the project and CWE labels parsed consistently (Semgrep writes CWE-89: Improper Neutralization…, CodeQL tags external/cwe/cwe-089).
3. Merge duplicates
Two hits become one finding when they are:
- in the same file,
- on overlapping lines, and
- about the same kind of weakness.
"Same kind" uses CWE families, because the scanners label one bug differently — CodeQL may call an eval of user input CWE-94 (code injection) where Semgrep says CWE-95 (eval injection):
| Family | Includes |
|---|---|
| Command injection (CWE-78) | CWE-77, CWE-88 |
| Code injection (CWE-94) | CWE-95 |
| Cross-site scripting (CWE-79) | CWE-80 |
| SQL injection (CWE-89) | CWE-564 |
| Path traversal (CWE-22) | CWE-23, CWE-36 |
| XXE (CWE-611) | CWE-776 |
A merged finding keeps every scanner that reported it. Two scanners means cross-scanner agreement, which raises the finding's priority. Merging also folds away Semgrep firing several rules on the same line. On the sample app, 17 raw hits become 7 findings. When scanners disagree on severity, the higher one is kept.
4. Group findings that share a fix
Findings on the same statement but of different kinds share a correlation group. pickle.loads(request.data) is both unsafe deserialization (CWE-502) and cross-site scripting (CWE-79): one fix resolves both. The dashboard's Approve all in this group (one fix) acts on these groups, and the panel can group by them.
5. Stable ids
A finding's id is a hash of its file, lines and category, not a random number. Re-scanning unchanged code gives the same ids, so your decisions and cached verdicts stay attached. (On the team server, ids are additionally scoped to the project, so two projects never collide.)
The findings file
The result is written to .securesense/findings.json in the scanned project (git-ignored automatically). The triage agent reads it, and so can your own tools — its format is defined in agent/securesense_agent/schema.py (CanonicalFinding).
Something unclear or wrong? Edit these docs on GitHub.