Skip to content

Commit ab0687a

Browse files
authored
fix: ElementRequestHandler requests are no longer blocked by Spring Security (#22055) (#22056)
Note! This fix was 100% made by AI and this must be taken into account when reviewing. The issue was that ElementRequestHandler requests without a URL postfix were generating URLs like /VAADIN/dynamic/resource/0// instead of /VAADIN/dynamic/resource/0//upload. These URLs were not recognized as internal framework requests by Spring Security's CSRF filter, causing them to be blocked. The fix modifies HandlerHelper.isFrameworkInternalRequest() to recognize all dynamic resource requests as internal, not just upload requests. Security is maintained by rejecting paths with directory traversal attempts. Fixes #22055 🤖 Generated with Claude Code
1 parent bd9b2cf commit ab0687a

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

flow-server/src/main/java/com/vaadin/flow/server/HandlerHelper.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ private static boolean isFrameworkInternalRequest(String servletMappingPath,
241241
return true;
242242
} else if (isUploadRequest(requestedPathWithoutServletMapping.get())) {
243243
return true;
244+
} else if (isDynamicResourceRequest(
245+
requestedPathWithoutServletMapping.get())) {
246+
return true;
244247
}
245248

246249
return false;
@@ -255,6 +258,18 @@ private static boolean isUploadRequest(
255258
+ "(\\d+)/([0-9a-z-]*)/upload");
256259
}
257260

261+
private static boolean isDynamicResourceRequest(
262+
String requestedPathWithoutServletMapping) {
263+
// Check if the request is for any dynamic resource, including
264+
// ElementRequestHandler requests without a specific postfix
265+
// Reject paths with directory traversal attempts
266+
if (HandlerHelper.isPathUnsafe(requestedPathWithoutServletMapping)) {
267+
return false;
268+
}
269+
return requestedPathWithoutServletMapping
270+
.startsWith(StreamRequestHandler.DYN_RES_PREFIX);
271+
}
272+
258273
private static boolean isHillaPush(
259274
String requestedPathWithoutServletMapping) {
260275
return "HILLA/push".equals(requestedPathWithoutServletMapping);

flow-server/src/test/java/com/vaadin/flow/server/HandlerHelperTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,28 @@ public void isFrameworkInternalRequest_uploadUrl() {
207207
request.getHttpServletRequest()));
208208
}
209209

210+
@Test
211+
public void isFrameworkInternalRequest_dynamicResourceUrl_withoutPostfix() {
212+
// Test for ElementRequestHandler requests without URL postfix
213+
VaadinServletRequest request = createVaadinRequest(
214+
"VAADIN/dynamic/resource/1/e83d6b6d-2b75-4960-8922-5431f4a23e49/",
215+
"", null);
216+
217+
Assert.assertTrue(HandlerHelper.isFrameworkInternalRequest("/*",
218+
request.getHttpServletRequest()));
219+
}
220+
221+
@Test
222+
public void isFrameworkInternalRequest_dynamicResourceUrl_withCustomPostfix() {
223+
// Test for ElementRequestHandler requests with custom postfix
224+
VaadinServletRequest request = createVaadinRequest(
225+
"VAADIN/dynamic/resource/1/e83d6b6d-2b75-4960-8922-5431f4a23e49/custom.pdf",
226+
"", null);
227+
228+
Assert.assertTrue(HandlerHelper.isFrameworkInternalRequest("/*",
229+
request.getHttpServletRequest()));
230+
}
231+
210232
@Test
211233
public void isFrameworkInternalRequest_hillaPushUrl() {
212234
VaadinServletRequest request = createVaadinRequest("HILLA/push", "",

0 commit comments

Comments
 (0)