Skip to content
This repository was archived by the owner on Jun 11, 2024. It is now read-only.

Commit 7b3c0c8

Browse files
committed
Fix Critical Java EL Injection RCE vulnerability from GHSL-2020-213
1 parent c3ff661 commit 7b3c0c8

File tree

5 files changed

+52
-9
lines changed

5 files changed

+52
-9
lines changed

browserup-proxy-rest/src/main/java/com/browserup/bup/rest/validation/LongPositiveConstraint.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import javax.validation.ConstraintValidatorContext;
99
import javax.validation.Payload;
1010

11+
import com.browserup.bup.rest.validation.util.MessageSanitizer;
1112
import org.slf4j.Logger;
1213
import org.slf4j.LoggerFactory;
1314

@@ -41,12 +42,14 @@ public boolean isValid(String value, ConstraintValidatorContext context) {
4142
longValue = Long.parseLong(value);
4243
} catch (NumberFormatException ex) {
4344
failed = true;
44-
errorMessage = String.format("Invalid integer value: '%s'", value);
45+
String escapedValue = MessageSanitizer.escape(value);
46+
errorMessage = String.format("Invalid integer value: '%s'", escapedValue);
4547
}
4648

4749
if (!failed && longValue < 0) {
4850
failed = true;
49-
errorMessage = String.format("Expected positive integer value, got: '%s'", value);
51+
String escapedValue = MessageSanitizer.escape(value);
52+
errorMessage = String.format("Expected positive integer value, got: '%s'", escapedValue);
5053
}
5154

5255
if (!failed) {
@@ -59,4 +62,4 @@ public boolean isValid(String value, ConstraintValidatorContext context) {
5962
return false;
6063
}
6164
}
62-
}
65+
}

browserup-proxy-rest/src/main/java/com/browserup/bup/rest/validation/NotBlankConstraint.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import javax.validation.ConstraintValidatorContext;
99
import javax.validation.Payload;
1010

11+
import com.browserup.bup.rest.validation.util.MessageSanitizer;
1112
import org.apache.commons.lang3.StringUtils;
1213
import org.slf4j.Logger;
1314
import org.slf4j.LoggerFactory;
@@ -36,11 +37,13 @@ public boolean isValid(Object value, ConstraintValidatorContext context) {
3637
if (value != null && StringUtils.isNotEmpty(String.valueOf(value))) {
3738
return true;
3839
}
39-
String errorMessage = String.format("Expected not empty value, got '%s'", value);
40+
41+
String escapedValue = MessageSanitizer.escape(value == null ? null : value.toString());
42+
String errorMessage = String.format("Expected not empty value, got '%s'", escapedValue);
4043
LOG.warn(errorMessage);
4144

4245
context.buildConstraintViolationWithTemplate(errorMessage).addConstraintViolation();
4346
return false;
4447
}
4548
}
46-
}
49+
}

browserup-proxy-rest/src/main/java/com/browserup/bup/rest/validation/PatternConstraint.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import javax.validation.ConstraintValidatorContext;
1010
import javax.validation.Payload;
1111

12+
import com.browserup.bup.rest.validation.util.MessageSanitizer;
1213
import org.apache.commons.lang3.StringUtils;
1314
import org.slf4j.Logger;
1415
import org.slf4j.LoggerFactory;
@@ -42,12 +43,13 @@ public boolean isValid(String value, ConstraintValidatorContext context) {
4243
Pattern.compile(value);
4344
return true;
4445
} catch (Exception ex) {
45-
String errorMessage = String.format("URL parameter '%s' is not a valid regexp", value);
46+
String escapedValue = MessageSanitizer.escape(value);
47+
String errorMessage = String.format("URL parameter '%s' is not a valid regexp", escapedValue);
4648
LOG.warn(errorMessage);
4749

4850
context.buildConstraintViolationWithTemplate(errorMessage).addConstraintViolation();
4951
}
5052
return false;
5153
}
5254
}
53-
}
55+
}

browserup-proxy-rest/src/main/java/com/browserup/bup/rest/validation/PortWithExistingProxyConstraint.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import com.browserup.bup.proxy.MitmProxyManager;
1313

14+
import com.browserup.bup.rest.validation.util.MessageSanitizer;
1415
import org.slf4j.Logger;
1516
import org.slf4j.LoggerFactory;
1617

@@ -47,11 +48,12 @@ public boolean isValid(Integer value, ConstraintValidatorContext context) {
4748
return true;
4849
}
4950

50-
String errorMessage = String.format("No proxy server found for specified port %d", value);
51+
String escapedValue = MessageSanitizer.escape(value.toString());
52+
String errorMessage = String.format("No proxy server found for specified port %s", escapedValue);
5153
LOG.warn(errorMessage);
5254

5355
context.buildConstraintViolationWithTemplate(errorMessage).addPropertyNode(PARAM_NAME).addConstraintViolation();
5456
return false;
5557
}
5658
}
57-
}
59+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.browserup.bup.rest.validation.util;
2+
/*
3+
* Modifications Copyright (c) 2019 BrowserUp, Inc.
4+
* Original from:
5+
* https://github.com/hibernate/hibernate-validator/blob/master/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/util/InterpolationHelper.java
6+
*/
7+
/*
8+
* License: Apache License, Version 2.0
9+
* See the license file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
10+
*/
11+
12+
import java.util.regex.Matcher;
13+
import java.util.regex.Pattern;
14+
15+
public class MessageSanitizer {
16+
17+
public static final char BEGIN_CHAR = '{';
18+
public static final char END_CHAR = '}';
19+
public static final char EL_DESIGNATOR = '$';
20+
public static final char ESCAPE_CHARACTER = '\\';
21+
22+
private static final Pattern ESCAPE_PATTERN = Pattern.compile( "([\\" + ESCAPE_CHARACTER + BEGIN_CHAR + END_CHAR + EL_DESIGNATOR + "])" );
23+
24+
private MessageSanitizer() {
25+
}
26+
27+
public static String escape(String message) {
28+
if ( message == null ) {
29+
return null;
30+
}
31+
return ESCAPE_PATTERN.matcher( message ).replaceAll( Matcher.quoteReplacement( String.valueOf( ESCAPE_CHARACTER ) ) + "$1" );
32+
}
33+
}

0 commit comments

Comments
 (0)