Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0fda3d8
Custom allow attributes & tags
dab246 Oct 23, 2024
c663ad9
Add validate base64 image tag
dab246 Oct 23, 2024
01c37cd
Add validate CID source for image tag
dab246 Oct 23, 2024
fda32cd
Allow `id` & `class` attribute
dab246 Oct 24, 2024
efa2b4e
feat(sanitize-html): add secure, high-performance HTML sanitization e…
dab246 Dec 2, 2025
dc329ab
feat(sanitize-html): add document for Secure HTML Sanitization Engine
dab246 Dec 3, 2025
1221aaf
feat(sanitize-html): Improve sanitize html to XSS prevention
dab246 Dec 4, 2025
df22ec3
feat(sanitize-html): prevent content loss by preserving text nodes an…
dab246 Dec 8, 2025
1db2906
fix(css-sanitizer): allow valid url() and restore missing allowed pro…
dab246 Dec 8, 2025
ebb41b9
fix(sanitize_html): remove group test is not implemented
dab246 Dec 8, 2025
53f0346
fix(css-sanitizer): block protocol-relative URLs and comment-obfuscat…
dab246 Dec 10, 2025
3aa9c82
fix(css-sanitizer): Add more test case for block protocol-relative UR…
dab246 Dec 10, 2025
eac5302
fix(css-sanitizer): allow safe overflow properties and add comprehens…
dab246 Dec 10, 2025
d8214f5
fix(html_sanitizer): some Nitpick comments and conversation of codera…
dab246 Dec 12, 2025
a47497e
fix(sanitize): keep non-executable JS-like content in text nodes
dab246 Dec 15, 2025
6627e13
Bump version to v3.0.0
dab246 Dec 15, 2025
cb19cbd
sanitize_html: preserve and safely sanitize internal CSS
dab246 Dec 24, 2025
87ac388
sanitize_html: Fix potential attribute injection via unescaped media …
dab246 Dec 24, 2025
9db73f5
sanitize_html: preserve nested CSS with token-level sanitization
dab246 Dec 24, 2025
1247d36
fix(sanitizer): mitigate potential ReDoS in regex patterns
dab246 Dec 29, 2025
21f9da9
Bump version to v3.0.1
dab246 Jan 9, 2026
a1e6dc0
fix(sanitizer): tighten unicodeEscapeReg to require 3+ consecutive \X…
dab246 May 15, 2026
8ca32f0
Bump version to v3.0.2
dab246 May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions sanitize_html/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## v3.0.2
* fix(sanitizer): tighten unicodeEscapeReg to require 3+ consecutive \XX sequences

## v3.0.1
* Preserve and safely sanitize internal CSS
* Preserve nested CSS with token-level sanitization
* Mitigate potential ReDoS in regex patterns

## v3.0.0
* Add secure, high-performance HTML sanitization engine

## v2.1.0
* Remove custom HTML rendering logic in favor of logic from `package:html`.
* Added `topics` to `pubspec.yaml`.
Expand Down
219 changes: 219 additions & 0 deletions sanitize_html/benchmark/fixtures/large_email_1.html

Large diffs are not rendered by default.

291 changes: 291 additions & 0 deletions sanitize_html/benchmark/fixtures/large_email_2.html

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions sanitize_html/benchmark/sanitize_benchmark.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import 'dart:io';

import 'package:sanitize_html/src/sane_html_validator.dart';

final List<String> sampleHtmlDocuments = [
// Short HTML
'<p>Hello <strong>world</strong></p>',
// Medium HTML
'''
<div>
<p onclick="alert(1)">Click me</p>
<img src="javascript:evil()" />
<a href="https://example.com" onclick="hack()">link</a>
</div>
''',
// Large HTML
File('benchmark/fixtures/large_email_1.html').readAsStringSync(),
File('benchmark/fixtures/large_email_2.html').readAsStringSync(),
];

void main() {
const iterations = 200;

final sane = SaneHtmlValidator(
allowElementId: null,
allowClassName: null,
addLinkRel: null,
allowAttributes: null,
allowTags: null,
);

_warmup(sane);

final saneDuration =
_benchmark('SaneHtmlValidator', sane.sanitize, iterations);

final saneMs = saneDuration.inMilliseconds;

print('--- Benchmark result ---');
print('SaneHtmlValidator : $saneMs ms');
}

void _warmup(
SaneHtmlValidator sane,
) {
for (final html in sampleHtmlDocuments) {
sane.sanitize(html);
}
}

Duration _benchmark(
String label,
String Function(String) sanitize,
int iterations,
) {
final sw = Stopwatch()..start();

for (var i = 0; i < iterations; i++) {
for (final html in sampleHtmlDocuments) {
sanitize(html);
}
}

sw.stop();
print('$label finished in ${sw.elapsed.inMilliseconds} ms');
return sw.elapsed;
}
Loading