Skip to content

Commit 876eb3f

Browse files
committed
Fix #35524: fix XSS from config file
1 parent a8075a5 commit 876eb3f

5 files changed

Lines changed: 62 additions & 5 deletions

File tree

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
<jakarta-json-api.version>2.1.3</jakarta-json-api.version>
4141
<glassfish-jakarta-json.version>2.0.1</glassfish-jakarta-json.version>
4242
<guava-version>33.4.8-jre</guava-version>
43+
<jsoup.version>1.21.2</jsoup.version>
4344
<!-- Plugin versions -->
4445
<maven.license-plugin.version>4.6</maven.license-plugin.version>
4546
<maven.build-helper-maven.plugin.version>3.6.0</maven.build-helper-maven.plugin.version>
@@ -360,6 +361,11 @@
360361
<artifactId>fontawesome</artifactId>
361362
<version>${fontawesome.version}</version>
362363
</dependency>
364+
<dependency>
365+
<groupId>org.jsoup</groupId>
366+
<artifactId>jsoup</artifactId>
367+
<version>${jsoup.version}</version>
368+
</dependency>
363369

364370
<!-- Amazon Base libraries-->
365371
<dependency>

src/main/java/eu/openanalytics/containerproxy/model/spec/ParameterDefinition.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
*/
2121
package eu.openanalytics.containerproxy.model.spec;
2222

23+
import eu.openanalytics.containerproxy.util.CleanHtml;
2324
import org.apache.commons.collections4.BidiMap;
2425
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
2526

@@ -39,7 +40,7 @@ public class ParameterDefinition {
3940
public ParameterDefinition(String id, String displayName, String description, List<ValueName> valueNames, String defaultValue) {
4041
this.id = id;
4142
this.displayName = displayName;
42-
this.description = description;
43+
this.description = CleanHtml.clean(description);
4344
this.defaultValue = defaultValue;
4445
this.valueNames = new DualHashBidiMap<>();
4546
if (valueNames != null) {

src/main/java/eu/openanalytics/containerproxy/model/spec/ProxySpec.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import eu.openanalytics.containerproxy.spec.expression.SpecExpressionContext;
2727
import eu.openanalytics.containerproxy.spec.expression.SpecExpressionResolver;
2828
import eu.openanalytics.containerproxy.spec.expression.SpelField;
29+
import eu.openanalytics.containerproxy.util.CleanHtml;
2930
import lombok.AccessLevel;
3031
import lombok.AllArgsConstructor;
3132
import lombok.Builder;
@@ -159,4 +160,18 @@ public ProxySpec finalResolve(SpecExpressionResolver resolver, SpecExpressionCon
159160
)
160161
.build();
161162
}
163+
164+
public void setDescription(String description) {
165+
this.description = CleanHtml.clean(description);
166+
}
167+
168+
public static class ProxySpecBuilder {
169+
170+
public ProxySpecBuilder description(String description) {
171+
this.description = CleanHtml.clean(description);
172+
return this;
173+
}
174+
175+
}
176+
162177
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2025 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
21+
package eu.openanalytics.containerproxy.util;
22+
23+
import org.jsoup.Jsoup;
24+
import org.jsoup.safety.Safelist;
25+
26+
public class CleanHtml {
27+
28+
public static String clean(String html) {
29+
if (html == null) {
30+
return null;
31+
}
32+
return Jsoup.clean(html, Safelist.basic());
33+
}
34+
35+
}

src/test/java/eu/openanalytics/containerproxy/test/proxy/TestIntegrationProxySharing.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,16 +302,16 @@ public void testConfigChange(String backend, Map<String, String> properties) {
302302
waitUntilDelegateProxyIsToRemove(proxySharingScaler, proxy.getTargetId());
303303
DelegateProxy delegateProxy = delegateProxyStore.getDelegateProxy(proxy.getTargetId());
304304
Assertions.assertEquals(DelegateProxyStatus.ToRemove, delegateProxy.getDelegateProxyStatus());
305-
Assertions.assertEquals("ad6af20f8aedf92add768e80144f6d9a5b8d8f6c", delegateProxy.getProxySpecHash());
305+
Assertions.assertEquals("347774a74415bed95752b7cd35d5c18f31094874", delegateProxy.getProxySpecHash());
306306

307307
// a DelegateProxy with new config should exist in DelegateProxyStore
308308
waitUntilNumberOfDelegateProxies(inst, 3, 1, 0, 2);
309309
Optional<DelegateProxy> newDelegateProxy = delegateProxyStore.getAllDelegateProxies().stream()
310-
.filter(it -> !it.getProxySpecHash().equals("ad6af20f8aedf92add768e80144f6d9a5b8d8f6c"))
310+
.filter(it -> !it.getProxySpecHash().equals("347774a74415bed95752b7cd35d5c18f31094874"))
311311
.findFirst();
312312
Assertions.assertTrue(newDelegateProxy.isPresent());
313313
Assertions.assertEquals(DelegateProxyStatus.Available, newDelegateProxy.get().getDelegateProxyStatus());
314-
Assertions.assertEquals("07a0e545cb66bb58afabe9e57d501fdffc81a5fb", newDelegateProxy.get().getProxySpecHash());
314+
Assertions.assertEquals("9662ccd14ac5bbbdacf0283d3de0370f50131498", newDelegateProxy.get().getProxySpecHash());
315315

316316
// stop running app
317317
inst.client.stopProxy(oldAppId);
@@ -322,7 +322,7 @@ public void testConfigChange(String backend, Map<String, String> properties) {
322322
waitUntilNumberOfDelegateProxies(inst, 1, 1);
323323
DelegateProxy newDelegateProxy3 = delegateProxyStore.getAllDelegateProxies().stream().findFirst().get();
324324
Assertions.assertEquals(newDelegateProxy.get().getProxy().getId(), newDelegateProxy3.getProxy().getId());
325-
Assertions.assertEquals("07a0e545cb66bb58afabe9e57d501fdffc81a5fb", newDelegateProxy3.getProxySpecHash());
325+
Assertions.assertEquals("9662ccd14ac5bbbdacf0283d3de0370f50131498", newDelegateProxy3.getProxySpecHash());
326326
}
327327
}
328328
}

0 commit comments

Comments
 (0)