fix: Handle Empty String in iFrame Embedding Config options#2958
fix: Handle Empty String in iFrame Embedding Config options#2958crivetimihai merged 1 commit intomainfrom
Conversation
69caaeb to
40e89a3
Compare
|
Looks good to me Verified by following steps:
`index.html`<!DOCTYPE html>
<html>
<head>
<title>Test X-Frame-Options</title>
</head>
<body>
<h1>Testing X-Frame-Options</h1>
<p>The iframe below should may or may not be blocked depending on config by the browser:</p>
<iframe src="http://localhost:8000/" width="800" height="600"></iframe>
<p>Check browser console (F12) for errors.</p>
</body>
</html>
Regards, |
e394c61 to
e147eaa
Compare
Review NotesRebased onto current Changes made during rebase
Review findingsBug confirmed: The root cause was correctly identified. When Fix is correct: Normalizing Security: No regression — default remains Test coverage: 100% on the middleware module, 99% on config (3 misses are unrelated). All validator branches covered. The All 167 related tests pass. |
The config validator now converts empty/whitespace-only X_FRAME_OPTIONS values to None, matching the middleware's expectation that None means "allow all embedding". Previously, an empty string fell through to the default DENY behavior in the middleware, blocking embedding unexpectedly. Closes #2492 Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com> Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
e147eaa to
e93f7c8
Compare
crivetimihai
left a comment
There was a problem hiding this comment.
Approved
Rebased onto main, squashed 9 commits into 1, and applied additional hardening based on review.
Changes applied during review
-
Docs fix (P2): Updated
.env.example— empty string docs incorrectly claimed""yieldsframe-ancestors * file: http: https:. It now correctly documents that""/null/noneall remove iframe restrictions (no headers sent). -
Middleware hardening (P3): Added defense-in-depth normalization in the middleware itself — if
x_frame_optionsis ever set to""or whitespace programmatically (bypassing the config validator), the middleware now treats it asNoneinstead of falling through toframe-ancestors 'none'. -
Stale comments (P4): Fixed misleading comments in middleware (line 258) and test file (line 665) that still referenced the old empty-string semantics.
-
Test coverage: Added 2 new middleware-level unit tests (
test_x_frame_options_raw_empty_string,test_x_frame_options_raw_whitespace_string) to exercise the hardened bypass path. Middleware coverage remains at 100%.
Manual verification
Tested end-to-end with Playwright across all four config scenarios:
| Config | X-Frame-Options | CSP frame-ancestors | iframe Result |
|---|---|---|---|
| Default (DENY) | DENY |
'none' |
Blocked |
X_FRAME_OPTIONS="" |
absent | absent | Loads successfully |
X_FRAME_OPTIONS=SAMEORIGIN |
SAMEORIGIN |
'self' |
Blocked (cross-origin) |
X_FRAME_OPTIONS=" " |
absent | absent | Loads successfully |
Test results
- 223 related tests pass (config + security + middleware)
- Full unit suite: 11,932 passed
- Full security suite: 238 passed
- Differential coverage:
security_headers.py100%,config.py99%
…ing (#2958) The config validator now converts empty/whitespace-only X_FRAME_OPTIONS values to None, matching the middleware's expectation that None means "allow all embedding". Previously, an empty string fell through to the default DENY behavior in the middleware, blocking embedding unexpectedly. Closes #2492 Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com> Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
…ing (IBM#2958) The config validator now converts empty/whitespace-only X_FRAME_OPTIONS values to None, matching the middleware's expectation that None means "allow all embedding". Previously, an empty string fell through to the default DENY behavior in the middleware, blocking embedding unexpectedly. Closes IBM#2492 Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com> Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> Signed-off-by: Nithin Katta <Nithin.Katta@ibm.com>
…ing (#2958) The config validator now converts empty/whitespace-only X_FRAME_OPTIONS values to None, matching the middleware's expectation that None means "allow all embedding". Previously, an empty string fell through to the default DENY behavior in the middleware, blocking embedding unexpectedly. Closes #2492 Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com> Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> Signed-off-by: Nithin Katta <Nithin.Katta@ibm.com>
…ing (#2958) The config validator now converts empty/whitespace-only X_FRAME_OPTIONS values to None, matching the middleware's expectation that None means "allow all embedding". Previously, an empty string fell through to the default DENY behavior in the middleware, blocking embedding unexpectedly. Closes #2492 Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com> Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
🔗 Related Issue
Closes #2492
📝 Summary
This PR fixes X_FRAME_OPTIONS related middleware behavior not properly handling empty string values.
Key changes:
""was falling through to the default case and being treated like DENY (addingframe-ancestors 'none'), when it should allow all embedding (no frame-ancestors directive)test_security_middleware_comprehensive.pyto useNoneinstead of""when testing disabled iframe restrictions, matching the config validator's behavior that converts empty strings toNoneThe root cause was:
""as an unknown value, defaulting to DENY behavior(adding frame-ancestors 'none') (blocking embedding)All X_FRAME_OPTIONS now exhibit expected behaviour
🏷️ Type of Change
🧪 Verification
✅ Checklist
make black isort pre-commit)📓 Notes (optional)
Targeted local verification executed:
pytest tests/unit/mcpgateway/test_config.py -v✅pytest tests/security/test_security_middleware_comprehensive.py✅