
Nimmt HTML von Drittanbietern entgegen und erzeugt HTML, das sicher in Ihre Webanwendung eingebettet werden kann. Schnell und einfach zu konfigurieren.
Ein schneller und einfach konfigurierbarer HTML-Sanitizer in Java, der es Ihnen ermöglicht, von Dritten erstelltes HTML in Ihre Webanwendung einzubinden und gleichzeitig vor XSS zu schützen.
Die vorhandene Abhängigkeit ist auf JSR 305. Die anderen JARs werden nur für die Testsuite benötigt. Die Abhängigkeit zu JSR 305 ist eine reine Compile-Abhängigkeit, die nur für Annotationen benötigt wird.
Dieser Code wurde unter Berücksichtigung von Sicherheitsbest Practices geschrieben, verfügt über eine umfangreiche Testsuite und wurde einer adversarial security review unterzogen.
Erste Schritte enthält Anweisungen, wie Sie mit oder ohne Maven beginnen können.
Sie können vorgefertigte Richtlinien verwenden:
PolicyFactory policy = Sanitizers.FORMATTING.and(Sanitizers.LINKS);
String safeHTML = policy.sanitize(untrustedHTML);
Die Tests zeigen, wie Sie Ihre eigene Richtlinie konfigurieren:
PolicyFactory policy = new HtmlPolicyBuilder()
.allowElements("a")
.allowUrlProtocols("https")
.allowAttributes("href").onElements("a")
.requireRelNofollowOnLinks()
.toFactory();
String safeHTML = policy.sanitize(untrustedHTML);
Sie können benutzerdefinierte Richtlinien schreiben, um Dinge wie das Ändern von h1 in divs mit einer bestimmten Klasse zu erreichen:
PolicyFactory policy = new HtmlPolicyBuilder()
.allowElements("p")
.allowElements(
(String elementName, List<String> attrs) -> {
// Add a class attribute.
attrs.add("class");
attrs.add("header-" + elementName);
// Return elementName to include, null to drop.
return "div";
}, "h1", "h2", "h3", "h4", "h5", "h6")
.toFactory();
String safeHTML = policy.sanitize(untrustedHTML);
Bitte beachten Sie, dass die Elemente "a", "font", "img", "input" und "span" explizit mit der Methode allowWithoutAttributes() in die Whitelist aufgenommen werden müssen, wenn sie durch den Filter gelassen werden sollen, wenn diese Elemente keine Attribute enthalten.
Attributrichtlinien erlauben ebenfalls die Ausführung von benutzerdefiniertem Code. Das Hinzufügen einer Attributrichtlinie verwässert keine Standardrichtlinie wie style oder URL-Attributprüfungen.
new HtmlPolicyBuilder = new HtmlPolicyBuilder()
.allowElement("div", "span")
.allowAttributes("data-foo")
.matching(
(String elementName, String attributeName, String value) -> {
// Return value for the attribute or null to drop.
})
.onElements("div", "span")
.build()
Preprozessoren ermöglichen das Einfügen von Text und großflächige strukturelle Änderungen.
new HtmlPolicyBuilder = new HtmlPolicyBuilder()
// Use a preprocessor to be backwards compatible with the
// <plaintext> element which
.withPreprocessor(
(HtmlStreamEventReceiver r) -> {
// Provide user with info about links before they click.
// Before: <a href="https://example.com/...">
// After: (https://example.com) <a href="https://example.com/...">
return new HtmlStreamEventReceiverWrapper(r) {
@Override public void openTag(String elementName, List<String> attrs) {
if ("a".equals(elementName)) {
for (int i = 0, n = attrs.size(); i < n; i += 2) {
if ("href".equals(attrs.get(i)) {
String url = attrs.get(i + 1);
String origin;
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
String authority = uri.getRawAuthority();
if (scheme == null && authority == null) {
origin = null;
} else {
origin = (scheme != null ? scheme + ":" : "")
+ (authority != null ? "//" + authority : "");
}
} catch (URISyntaxException ex) {
origin = "about:invalid";
}
if (origin != null) {
text(" (" + origin + ") ");
}
}
}
}
super.openTag(elementName, attrs);
}
};
}
.allowElement("a")
...
.build()
Die Vorverarbeitung erfolgt, bevor eine Richtlinie angewendet wird, und kann daher die Sicherheit der Ausgabe nicht beeinträchtigen.
Wenn eine Richtlinie ein Element oder Attribut ablehnt, benachrichtigt sie einen HtmlChangeListener.
Sie können dies verwenden, um Trends bei Richtlinienverstößen zu verfolgen und herauszufinden, wenn jemand versucht, Ihre Sicherheit zu umgehen.
PolicyFactory myPolicyFactory = ...;
// If you need to associate reports with some context, you can do so.
MyContextClass myContext = ...;
String sanitizedHtml = myPolicyFactory.sanitize(
unsanitizedHtml,
new HtmlChangeListener<MyContextClass>() {
@Override
public void discardedTag(MyContextClass context, String elementName) {
// ...
}
@Override
public void discardedAttributes(
MyContextClass context, String elementName, String... attributeNames) {
// ...
}
},
myContext);
Hinweis: Wenn eine Zeichenkette ohne Änderungsbenachrichtigungen bereinigt wird, ist dies nicht unbedingt ein Hinweis darauf, dass die Eingabezeichenkette sicher verwendet werden kann. Verwenden Sie nur die Ausgabe des Sanitizers.
Der Sanitizer stellt sicher, dass die Ausgabe in einer Teilmenge von HTML liegt, über deren Bedeutung gängige HTML-Parser übereinstimmen. Das Fehlen von Benachrichtigungen bedeutet jedoch nicht, dass die Eingabe in einer solchen Teilmenge liegt, sondern nur, dass sie keine Elemente oder Attribute enthält, die entfernt wurden.
Siehe "Warum bereinigen, wenn man validieren kann" für weitere Informationen zu diesem Thema.
Wenn Sie eine Sicherheitslücke melden möchten, lesen Sie bitte AttackReviewGroundRules.
Abonnieren Sie die Mailingliste, um über bekannte Sicherheitslücken und wichtige Updates informiert zu werden.
Wenn Sie mitwirken möchten, wenden Sie sich bitte an @mvsamuel oder @manicode.
Wir begrüßen Issue-Meldungen und Pull-Requests. PRs, die das Verhalten ändern oder Funktionalität hinzufügen, sollten sowohl positive als auch negative Tests enthalten.
Bitte beachten Sie, dass Beiträge unter die Apache 2.0-Lizenz fallen.