diff --git a/src/main/java/org/owasp/html/HtmlPolicyBuilder.java b/src/main/java/org/owasp/html/HtmlPolicyBuilder.java
index bae6d13e..ea74b109 100644
--- a/src/main/java/org/owasp/html/HtmlPolicyBuilder.java
+++ b/src/main/java/org/owasp/html/HtmlPolicyBuilder.java
@@ -1045,10 +1045,9 @@ public String apply(String elementName, List attrs) {
for (int i = 0; i <= n; ++i) {
if (i == n || Strings.isHtmlSpace(rels.charAt(i))) {
if (left < i) {
- if (skip.isEmpty()
- || !skip.contains(
- Strings.toLowerCase(rels.substring(left, i)))) {
- String rel = rels.substring(left, i);
+ final String rel = rels.substring(left, i);
+ final String lowerCaseRel = Strings.toLowerCase(rel);
+ if ((skip.isEmpty() || !skip.contains(lowerCaseRel)) && !present.contains(lowerCaseRel)) {
present.add(rel);
sb.append(rel).append(' ');
}
diff --git a/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java b/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java
index 746a1017..978e3daf 100644
--- a/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java
+++ b/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java
@@ -874,6 +874,31 @@ public final void testRelLinksWhenRelIsPartOfData() {
assertEquals(toSanitize, pf.sanitize(toSanitize));
}
+ @Test
+ public static final void testRelLinksWithDuplicateRels() {
+ PolicyFactory pf = new HtmlPolicyBuilder()
+ .allowElements("a")
+ .allowAttributes("href").onElements("a")
+ .allowAttributes("rel").onElements("a")
+ .allowAttributes("target").onElements("a")
+ .allowStandardUrlProtocols()
+ .toFactory();
+ assertEquals("test", pf.sanitize("test"));
+ }
+
+ @Test
+ public static final void testRelLinksWithDuplicateRelsRequired() {
+ PolicyFactory pf = new HtmlPolicyBuilder()
+ .allowElements("a")
+ .allowAttributes("href").onElements("a")
+ .allowAttributes("rel").onElements("a")
+ .allowAttributes("target").onElements("a")
+ .allowStandardUrlProtocols()
+ .requireRelsOnLinks("noreferrer")
+ .toFactory();
+ assertEquals("test", pf.sanitize("test"));
+ }
+
@Test
public static final void testFailFastOnSpaceSeparatedStrings() {
boolean failed;