Skip to content

pscanrules: Move META tag CSP check to LOW threshold for performace reasons#7096

Open
AshharAhmadKhan wants to merge 5 commits intozaproxy:mainfrom
AshharAhmadKhan:fix-csp-meta-performance
Open

pscanrules: Move META tag CSP check to LOW threshold for performace reasons#7096
AshharAhmadKhan wants to merge 5 commits intozaproxy:mainfrom
AshharAhmadKhan:fix-csp-meta-performance

Conversation

@AshharAhmadKhan
Copy link

@AshharAhmadKhan AshharAhmadKhan commented Jan 31, 2026

OVERVIEW

This PR resolves a performance bottleneck in the Content Security Policy (CSP) Header Missing passive scan rule (ID 10038). The issue was caused by CspUtils.hasMetaCsp() performing full HTML DOM parsing to check for META tag CSP definitions on every response without a CSP header, regardless of threshold setting.

The fix moves META tag checking to LOW threshold only, while preserving HTTP header validation at all thresholds. This maintains security coverage while eliminating unnecessary DOM parsing overhead at MEDIUM and HIGH thresholds.

Performance testing confirms significant improvements: 59% faster on pages with 500 META tags, and approximately 17 seconds saved on a 10,000 page scan with realistic modern web pages. The solution is fully backward compatible - users requiring META tag validation can simply set the threshold to LOW.

RELATED ISSUES

Fixes zaproxy/zaproxy#9229

- Performance optimization: META tag parsing now only runs at LOW threshold
- Reduces DOM parsing overhead on pages without CSP headers at MEDIUM/HIGH
- Added 'Other Info' message when META tags are not checked
- Updated unit tests to verify threshold behavior
- Fixes #9229

Signed-off-by: Ashhar Ahmad Khan <145142826+AshharAhmadKhan@users.noreply.github.com>
- 500 META tags: 59% performance improvement at MEDIUM vs LOW
- On 10,000 page scan: ~17.4 seconds additional overhead

Confirms that CspUtils.hasMetaCsp() DOM parsing is the bottleneck.

Related to #9229

Signed-off-by: Ashhar Ahmad Khan <145142826+AshharAhmadKhan@users.noreply.github.com>
@github-actions
Copy link

github-actions bot commented Jan 31, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@AshharAhmadKhan
Copy link
Author

@github-actions I have read the CLA Document and I hereby sign the CLA

@psiinon
Copy link
Member

psiinon commented Jan 31, 2026

Logo
Checkmarx One – Scan Summary & Details93ec33ff-3519-4d03-9eb3-273af71b7a01

Great job! No new security vulnerabilities introduced in this pull request


Use @Checkmarx to interact with Checkmarx PR Assistant.
Examples:
@Checkmarx how are you able to help me?
@Checkmarx rescan this PR

@kingthorin
Copy link
Member

The comment needs to be literal, no mentions no extra text

@AshharAhmadKhan
Copy link
Author

I have read the CLA Document and I hereby sign the CLA

Latest code: <a href="https://github.com/zaproxy/zap-extensions/blob/main/addOns/pscanrules/src/main/java/org/zaproxy/zap/extension/pscanrules/ContentSecurityPolicyMissingScanRule.java">ContentSecurityPolicyMissingScanRule.java</a>
<br>
Alert ID: <a href="https://www.zaproxy.org/docs/alerts/10038/">10038</a>.

Copy link
Member

Choose a reason for hiding this comment

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

This blank line should be restored


// Add informational message if META tags were not checked
if (msg != null && !AlertThreshold.LOW.equals(this.getAlertThreshold())) {
builder.setOtherInfo(getAlertAttribute("meta.not.checked"));
Copy link
Member

Choose a reason for hiding this comment

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

Is this clobbering anything? (Ex: should this be an append vs a set? Or an appending set)

*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2024 The ZAP Development Team
Copy link
Member

Choose a reason for hiding this comment

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

2026

@thc202 thc202 changed the title fix: Move META tag CSP check to LOW threshold only (#9229) pscanrules: Move META tag CSP check to LOW threshold for performace reasons Feb 1, 2026
@thc202
Copy link
Member

thc202 commented Feb 1, 2026

What's the performance issue?

@AshharAhmadKhan
Copy link
Author

hey @thc202
The performance issue is that CspUtils.hasMetaCsp() calls source.getAllElements(HTMLElementName.META) which performs full HTML DOM parsing on every response without a CSP header, at all thresholds. This creates unnecessary overhead, especially on pages with many META tags. The fix moves this check to LOW threshold only, while preserving header validation at all thresholds.

@thc202
Copy link
Member

thc202 commented Feb 2, 2026

Your performance tests don't show that, much less the 5s+ delays, and to be clear while that's the likely source of the performance issue (as was indicated in the original report) we should still confirm it before jumping to changes/potential fixes (e.g. zaproxy/zaproxy#9229 (comment) seems better approach, if it works, than make the check under low).

@kingthorin
Copy link
Member

@AshharAhmadKhan to clarify things a bit further. We have stats that show it's taking longer than 5sec on single pages, but we don't have examples of the pages that are causing the issue.

@AshharAhmadKhan
Copy link
Author

Thanks for the feedback @kingthorin @thc202 I’ve pushed updates addressing the review comments (append vs set, docs, and formatting fixes).

CI is still running; once the checks complete, I’d appreciate another look.

Regarding the performance concern: I agree confirmation is important. If you prefer, I can add targeted instrumentation or a reproducible test case to validate the DOM parsing cost before we adjust behavior further.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Missing CSP header rule is sometimes slow

4 participants