Skip to content

Commit 959cf61

Browse files
neVERberleRfellerERrstoyanchev
authored andcommitted
Sanitize request fragment in ResourceUrlEncodingFilter
Prior to this change, ResourceUrlEncodingFilter would try to resolve the resource path using request URL without removing fragment first, whereas only paths should be used. This commit synchronizes behavior of ResourceUrlEncodingFilter with behavior of ResourceUrlProvider. Issue: SPR-17535
1 parent 82eb82a commit 959cf61

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public String resolveUrlPath(String url) {
115115
return null;
116116
}
117117
if (this.indexLookupPath != null && url.startsWith(this.prefixLookupPath)) {
118-
int suffixIndex = getQueryParamsIndex(url);
118+
int suffixIndex = getEndPathIndex(url);
119119
String suffix = url.substring(suffixIndex);
120120
String lookupPath = url.substring(this.indexLookupPath, suffixIndex);
121121
lookupPath = this.resourceUrlProvider.getForLookupPath(lookupPath);
@@ -126,9 +126,17 @@ public String resolveUrlPath(String url) {
126126
return null;
127127
}
128128

129-
private int getQueryParamsIndex(String url) {
130-
int index = url.indexOf('?');
131-
return (index > 0 ? index : url.length());
129+
private int getEndPathIndex(String lookupPath) {
130+
int suffixIndex = lookupPath.length();
131+
int queryIndex = lookupPath.indexOf('?');
132+
if (queryIndex > 0) {
133+
suffixIndex = queryIndex;
134+
}
135+
int hashIndex = lookupPath.indexOf('#');
136+
if (hashIndex > 0) {
137+
suffixIndex = Math.min(suffixIndex, hashIndex);
138+
}
139+
return suffixIndex;
132140
}
133141
}
134142

spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,30 @@ public void encodeUrlPreventStringOutOfBounds() throws Exception {
173173
});
174174
}
175175

176+
@Test // SPR-17535
177+
public void encodeURLWitFragment() throws Exception {
178+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
179+
request.setContextPath("/");
180+
MockHttpServletResponse response = new MockHttpServletResponse();
181+
182+
this.filter.doFilter(request, response, (req, res) -> {
183+
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
184+
String result = ((HttpServletResponse) res).encodeURL("/resources/bar.css#something");
185+
assertEquals("/resources/bar-11e16cf79faee7ac698c805cf28248d2.css#something", result);
186+
});
187+
}
188+
189+
@Test // SPR-13374 and SPR-17535 combined
190+
public void encodeURLWitFragmentAndRequestParams() throws Exception {
191+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
192+
request.setContextPath("/");
193+
MockHttpServletResponse response = new MockHttpServletResponse();
194+
195+
this.filter.doFilter(request, response, (req, res) -> {
196+
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
197+
String result = ((HttpServletResponse) res).encodeURL("/resources/bar.css?foo=bar&url=http://example.org#something");
198+
assertEquals("/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=http://example.org#something", result);
199+
});
200+
}
201+
176202
}

0 commit comments

Comments
 (0)