Skip to content

Commit cfd2880

Browse files
authored
Merge pull request #494 from NielsDoucet/RCE-fix
Resolve RCE vulnerability.
2 parents d670750 + 9c93c17 commit cfd2880

4 files changed

Lines changed: 18 additions & 9 deletions

File tree

src/main/java/com/cronutils/parser/CronParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public Cron parse(final String expression) {
128128
}
129129
return new SingleCron(cronDefinition, results).validate();
130130
} catch (final IllegalArgumentException e) {
131-
throw new IllegalArgumentException(String.format("Failed to parse '%s'. %s", expression, e.getMessage()), e);
131+
throw new IllegalArgumentException(String.format("Failed to parse cron expression. %s", e.getMessage()), e);
132132
}
133133
}
134134
}

src/test/java/com/cronutils/Issue418Test.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.cronutils.model.definition.CronDefinitionBuilder;
66
import com.cronutils.model.time.ExecutionTime;
77
import com.cronutils.parser.CronParser;
8+
import org.hamcrest.core.StringEndsWith;
89
import org.junit.Test;
910

1011
import java.time.LocalDate;
@@ -13,8 +14,8 @@
1314
import java.time.ZonedDateTime;
1415
import java.util.Optional;
1516

16-
import static org.junit.Assert.assertEquals;
17-
import static org.junit.Assert.fail;
17+
import static org.hamcrest.core.StringEndsWith.endsWith;
18+
import static org.junit.Assert.*;
1819

1920
public class Issue418Test {
2021

@@ -59,7 +60,7 @@ public void testInvalidWeekDayStart() {
5960
parser.parse("0 0 2 ? * 0/7 *");
6061
fail("Expected exception for invalid expression");
6162
} catch (IllegalArgumentException expected) {
62-
assertEquals("Failed to parse '0 0 2 ? * 0/7 *'. Value 0 not in range [1, 7]", expected.getMessage());
63+
assertThat(expected.getMessage(), endsWith("Value 0 not in range [1, 7]"));
6364
}
6465
}
6566

@@ -71,7 +72,7 @@ public void testInvalidWeekDayEnd() {
7172
parser.parse("0 0 2 ? * 1/8 *");
7273
fail("Expected exception for invalid expression");
7374
} catch (IllegalArgumentException expected) {
74-
assertEquals("Failed to parse '0 0 2 ? * 1/8 *'. Period 8 not in range [1, 7]", expected.getMessage());
75+
assertThat(expected.getMessage(), endsWith("Period 8 not in range [1, 7]"));
7576
}
7677
}
7778
}

src/test/java/com/cronutils/parser/CronParserQuartzIntegrationTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,19 @@
2020
import com.cronutils.model.definition.CronDefinitionBuilder;
2121
import com.cronutils.model.field.expression.FieldExpressionFactory;
2222
import com.cronutils.model.time.ExecutionTime;
23+
import org.hamcrest.core.StringEndsWith;
2324
import org.junit.Before;
2425
import org.junit.Rule;
2526
import org.junit.Test;
27+
import org.junit.internal.matchers.ThrowableMessageMatcher;
2628
import org.junit.rules.ExpectedException;
2729

2830
import java.time.ZonedDateTime;
2931
import java.util.Locale;
3032
import java.util.Optional;
3133

3234
import static org.junit.Assert.*;
35+
import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
3336

3437
public class CronParserQuartzIntegrationTest {
3538

@@ -248,9 +251,7 @@ public void testReportedErrorContainsSameExpressionAsProvided() {
248251
public void testMissingExpressionAndInvalidCharsInErrorMessage() {
249252
thrown.expect(IllegalArgumentException.class);
250253
final String cronexpression = "* * -1 * * ?";
251-
thrown.expectMessage(
252-
String.format("Failed to parse '%s'. Invalid expression! Expression: -1 does not describe a range. Negative numbers are not allowed.",
253-
cronexpression));
254+
thrown.expect(hasMessage(StringEndsWith.endsWith("Invalid expression! Expression: -1 does not describe a range. Negative numbers are not allowed.")));
254255
assertNotNull(ExecutionTime.forCron(parser.parse(cronexpression)));
255256
}
256257

src/test/java/com/cronutils/validation/CronValidatorTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import org.junit.Test;
55
import org.junit.runner.RunWith;
66
import org.junit.runners.Parameterized;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
79

810
import javax.validation.ConstraintViolation;
911
import javax.validation.Validation;
@@ -16,6 +18,8 @@
1618
@RunWith(Parameterized.class)
1719
public class CronValidatorTest {
1820

21+
private static final Logger LOGGER = LoggerFactory.getLogger(CronValidatorTest.class);
22+
1923
private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
2024

2125
private final String expression;
@@ -38,14 +42,17 @@ public static Object[] expressions() {
3842
{"0 0 0 25 12 ?", true},
3943
{"0 0 0 L 12 ?", false},
4044
{"1,2, * * * * *", false},
41-
{"1- * * * * *", false}
45+
{"1- * * * * *", false},
46+
// Verification for RCE security vulnerability fix: https://github.com/jmrozanec/cron-utils/issues/461
47+
{"java.lang.Runtime.getRuntime().exec('touch /tmp/pwned'); // 4 5 [${''.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('js').eval(validatedValue)}]", false}
4248
};
4349
}
4450

4551
@Test
4652
public void validateExamples() {
4753
TestPojo testPojo = new TestPojo(expression);
4854
Set<ConstraintViolation<TestPojo>> violations = validator.validate(testPojo);
55+
violations.stream().map(ConstraintViolation::getMessage).forEach(LOGGER::info);
4956

5057
if (valid) {
5158
assertTrue(violations.isEmpty());

0 commit comments

Comments
 (0)