GitHub Advisoryadvisory · PyPI
GHSA-gj48-438w-jh9v Bleach clean() / Cleaner() fails to sanitize dangerous URI schemes in allowed formaction attributes
MEDIUM
Official page ↗
- Ecosystem
- PyPI
- Packages
- bleach
- Severity
- Moderate
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
- Weaknesses
- CWE-79
- Reviewed
- 2026-06-16
Affected packages
• PyPI bleach: < 6.4.0 → fixed in 6.4.0
Description
Summary
Bleach `clean()` / `Cleaner()` fails to sanitize dangerous URI schemes in allowed `formaction` attributes.
Bleach applies URI protocol sanitization only to attributes listed in `attr_val_is_uri`. While URI-bearing attributes such as `action`, `href`, `src`, and `poster` are included in that set, `formaction` is not. As a result, if a downstream application explicitly allows `formaction` on submit-capable controls in untrusted HTML, Bleach preserves dangerous values such as `javascript:alert(1)` instead of stripping them.
This can lead to submit-triggered JavaScript execution in applications that rely on Bleach to sanitize untrusted HTML and allow the relevant tag/attribute combination.
---
Details
The issue appears to be a URI-sanitization coverage gap in Bleach’s sanitizer logic.
Relevant code paths:
• `bleach/sanitizer.py` — `BleachSanitizerFilter.allow_token` (around line 553)
• `bleach/_vendor/html5lib/filters/sanitizer.py` — `attr_val_is_uri` (around line 525)
In `BleachSanitizerFilter.allow_token`, URI protocol sanitization is only applied when:
```python id="pft79m"
if namespaced_name in self.attr_val_is_uri:
```
However, `(None, 'formaction')` is currently missing from `attr_val_is_uri`.
This creates an inconsistency where `action` is protocol-sanitized, but `formaction` is not.
As a result, if a downstream application allows:
• tags such as `` or ``
• the `formaction` attribute
then Bleach preserves dangerous URI schemes such as `javascript:` in `formaction`.
Examples of affected submit-capable controls include:
• `` (default submit behavior unless `type="button"` is set)
• ``
• ``
This appears to be a real library-side sanitizer gap rather than only an application misuse issue, because Bleach already treats similar URI-bearing attributes (such as `action`) as protocol-sensitive and sanitizes them.
Suggested minimal fix:
Add:
```python id="4v4fkn"
(None, 'formaction')
```
to `attr_val_is_uri` in:
• `bleach/_vendor/html5lib/filters/sanitizer.py`
I also prepared a minimal patch and focused regression tests if helpful.
---
PoC
Below are minimal reproductions using `bleach.clean()`.
1) ``
```python id="d3g0v7"
from bleach import clean
print(clean(
'go',
tags={'form', 'button'},
attributes={'button': ['formaction']},
))
```
Actual output:
```html id="i4nd7s"
go
```
Expected output:
```html id="g4d2r1"
go
```
---
2) ``
```python id="l4dy0j"
print(clean(
'',
tags={'form', 'input'},
attributes={'input': ['type', 'formaction', 'value']},
))
```
Actual output:
```html id="h8lgbt"
```
Expected output:
```html id="6y8mws"
```
---
3) ``
```python id="g8q0x8"
print(clean(
'',
tags={'form', 'input'},
attributes={'input': ['type', 'formaction', 'src']},
))
```
Actual output:
```html id="fd22kg"
```
Expected output:
```html id="z6t6je"
```
---
Impact
This is a client-side HTML sanitization bypass / dangerous URI preservation issue.
If an application relies on Bleach to sanitize untrusted HTML and explicitly allows:
• `formaction`
• and submit-capable controls such as `` or ``
then Bleach can emit sanitized output that still contains a dangerous `javascript:` URI in `formaction`.
That can lead to submit-triggered JavaScript execution when the user activates the control.
Impact is limited to configurations that explicitly allow the relevant tag/attribute combination, but the issue is still security-relevant because:
• `formaction` is a real browser sink
• Bleach already protocol-sanitizes similar URI-bearing attributes like `action`
• the omission creates inconsistent sanitizer coverage for dangerous URI schemes
I would currently assess this as Medium severity.
If useful, I also have:
• a minimal patch
• focused regression tests for:
• ``
• ``
• ``
• a safe control case where `formaction="/submit"` is preserved
Related
Weakness · CWE (1)
- CWE-79 Improper Neutralization of Input During Web Page Generation weakness