Progpilot Integration with DefectDojo
Progpilot Integration with DefectDojo
Progpilot is an open source static application security testing (SAST) tool for PHP, published by the designsecurity project on GitHub. It performs taint analysis: it tracks data from sources such as request parameters through the code to sensitive sinks such as database queries, output functions, and file operations, and it also supports custom rules for patterns like security misconfigurations. Progpilot runs as a PHAR, through Composer, or in Docker, and produces results as JSON, which DefectDojo imports.
Progpilot Integration with DefectDojo
PHP codebases are often old, large, and short on test coverage, which makes a taint-tracking scanner like Progpilot useful and its output long. We import Progpilot results into DefectDojo so each finding lands on the Asset that owns the code, with its CWE, file path, and line number set, and with the taint flow from source to sink in the description. Reimporting after each scan shows which flows the team actually closed and keeps the count honest.
Why Progpilot Matters
Injection and output-encoding flaws are still the bread and butter of PHP vulnerabilities, and they follow the shape Progpilot is built to detect.
- Taint-style results show the full path: which variable carried untrusted input, the functions it flowed through, and the sink it reached.
- Each result carries a CWE (for example CWE-89 for SQL injection or CWE-79 for cross-site scripting), which helps with reporting and prioritization.
- It is free and runs locally or in CI, so teams can scan PHP code without sending source to a third party.
- Progpilot does not grade severity or remember previous runs. Without a platform behind it, every scan is a long list with no sense of what is new.
Advantages of This Integration
What we gained by sending Progpilot results through DefectDojo:
- Code location on every finding. File path and line come from the sink (or the custom rule match), so findings link straight to the code that needs to change.
- Stable identity from the tool. Progpilot's own
vuln_idhash is stored as the unique ID from the tool, which gives each source-to-sink flow a consistent identifier across runs. - Lifecycle on reimport. Reimporting the next scan into the same Test mitigates flows that were fixed, adds new ones, and reactivates any that return.
- Triage that sticks. SAST tools produce false positives. Marking one as a false positive in DefectDojo keeps it out of future metrics for that Test, rather than reappearing in every report.
- Ownership and ticketing. Findings can be assigned to the PHP team, annotated, risk-accepted, or pushed to Jira.
How This Integration Works
DefectDojo imports Progpilot results with the Progpilot Scan scan type.
1. Run Progpilot and capture JSON. Point Progpilot at your PHP source and write its output to a file:
progpilot src/ > progpilot.json
Pass --configuration progpilot.yml if you use a custom configuration for sources, sinks, or rules. The file you import must be the JSON array of results, so make sure nothing else in the job writes to the same output.
2. Import it. In the UI, open the Engagement, choose Import Scan Results, select Progpilot 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=Progpilot Scan" \
-F "file=@progpilot.json" \
-F "product_name=storefront-php" \
-F "engagement_name=CI" \
-F "auto_create_context=true"
DefectDojo Pro users can run the same import with Universal Importer:
universal-importer import \
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
--scan-type "Progpilot Scan" \
--report-path "./progpilot.json" \
--product-name "storefront-php" \
--engagement-name "CI" \
--auto-create-context
3. Reimport on later scans. Send subsequent reports to /api/v2/reimport-scan/ against the same Test so the finding history for the codebase stays in one place.
Data Granularity: What Gets Imported
Progpilot emits two kinds of results: taint-style (source to sink flows) and custom (rule matches). Both import as one finding per result.
| DefectDojo Field | Source in Progpilot Report | Notes |
|---|---|---|
| Title | vuln_name |
For example sql_injection or xss |
| Severity | Not in report | Every finding is imported as Medium |
| Description | Result fields | Includes vuln type, source name, line, column and file, tainted flow, sink name and column, rule, and rule description when present |
| File Path | sink_file, else vuln_file |
Sink file for taint results, match file for custom rules |
| Line | sink_line, else vuln_line |
Same precedence as file path |
| CWE | vuln_cwe |
CWE_89 style values become the number 89 |
| Unique ID from tool | vuln_id |
Progpilot's 64-character hash for the result |
| Finding type | Static | All Progpilot findings are marked static |
| Deduplication | Legacy algorithm | No per-parser entry; docs list title, CWE, line, file path, description |
Use Cases
In a PHP CI pipeline: Every pull request to a PHP service runs Progpilot and reimports into the Test for the main branch scan. Reviewers see the new flows the change introduced, and the team decides whether to block the merge on them.
For legacy application cleanup: A team inheriting a 10-year-old PHP application imports a first Progpilot scan as a baseline, triages false positives once, and then works down the remaining SQL injection and XSS findings by CWE, measuring progress with each reimport.
Alongside other scanners: Progpilot findings sit on the same Asset as dependency findings from a Composer audit and DAST results against the deployed site. When a DAST tool reports XSS on a page, the Progpilot finding for the matching sink gives the developer the line to fix.
For security reviews before release: AppSec can filter the Asset's findings by CWE to answer specific questions, such as whether any open SQL injection flows remain, without rerunning the scan.
Operational Tips
- Set severity during triage. Every Progpilot finding arrives as Medium, so SLA timers start from the same point. Raise confirmed injection flows to High or Critical and lower noise to Low.
- Tune sources and sinks in Progpilot's configuration rather than marking the same framework helper as a false positive over and over.
- Scan from a consistent working directory. File paths in the report are the paths Progpilot saw, and they feed deduplication, so moving the checkout location between runs can change them.
- Titles are short identifiers like
xss. Many findings share a title, so filter by file path and CWE when assigning work. - Read the tainted flow in the description before closing a finding. It is copied in as raw data rather than formatted, but it lists every variable, line, and file the input passed through, which is often the fastest way to find where sanitization belongs.
- Use one Test per repository and branch you track, and reimport into it.
- Tag imports with the commit or release (for example
tags=release-4.2) to tie findings to the code that produced them.