Spring Framework Denial of Service via AntPathMatcher
Research is free — Hunters explains how the bug works, the root-cause code pattern, how the fix addresses it, and how to test whether a target is affected, in chat. Investigate & write exploit is a paid run — the engine reads the advisory and fix commits, then builds and validates a working proof-of-concept exploit with reproduction steps.
Affected versions
Details
Applications may be vulnerable to a Regular Expression Denial of Service (ReDoS) attack if an attacker is able to provide a pattern which is then directly or indirectly supplied to one of the following methods in AntPathMatcher: match(String pattern, String path), matchStart(String pattern, String path), extractUriTemplateVariables(String pattern, String path). Affected versions: Spring Framework 7.0.0 through 7.0.7; 6.2.0 through 6.2.18; 6.1.0 through 6.1.27; 5.3.0 through 5.3.48.
The fix
Avoid too many character access attempts in AntPathMatcher
spring-core/src/main/java/org/springframework/util/AntPathMatcher.java+55 −1
@@ -723,7 +723,7 @@ public boolean matchStrings(String str, @Nullable Map<String, String> uriTemplatreturn this.caseSensitive ? this.rawPattern.equals(str) : this.rawPattern.equalsIgnoreCase(str);}else if (this.pattern != null) {-Matcher matcher = this.pattern.matcher(str);+Matcher matcher = this.pattern.matcher(new MaxAttemptsCharSequence(str));if (matcher.matches()) {if (uriTemplateVariables != null) {if (this.variableNames.size() != matcher.groupCount()) {@@ -748,6 +748,60 @@ else if (this.pattern != null) {return false;}++private static class MaxAttemptsCharSequence implements CharSequence {++private static final int MAX_ATTEMPTS = 1_000_000;++private final String text;++private final Counter counter;+++MaxAttemptsCharSequence(String text) {+this(text, new Counter());+}++private MaxAttemptsCharSequence(String text, Counter counter) {+this.text = text;+this.counter = counter;+}+++@Override+public int length() {+return this.text.length();+}++@Override+public char charAt(int index) {+if (this.counter.value++ >= MAX_ATTEMPTS) {+throw new IllegalStateException(+"Too many character access attempts encountered during pattern matching");+}+return this.text.charAt(index);+}++@Override+public boolean isEmpty() {+return this.text.isEmpty();+}++@Override+public CharSequence subSequence(int start, int end) {+return new MaxAttemptsCharSequence(this.text.substring(start, end), this.counter);+}++@Override+public String toString() {+return this.text;+}+++private static class Counter {+private int value;+}+}}
References
- ADVISORYhttps://nvd.nist.gov/vuln/detail/CVE-2026-41848
- WEBhttps://github.com/spring-projects/spring-framework/commit/12b44f2545a1bec6150c7a05e66092c732597a94
- PACKAGEhttps://github.com/spring-projects/spring-framework
- WEBhttps://github.com/spring-projects/spring-framework/releases/tag/v6.2.19
- WEBhttps://github.com/spring-projects/spring-framework/releases/tag/v7.0.8
- WEBhttps://spring.io/security/cve-2026-41848