Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@
**Vulnerability:** A CRLF injection vulnerability was identified where unvalidated inputs could be reflected directly into HTTP response headers, leading to HTTP response splitting.
**Learning:** Instead of sanitizing individual headers independently, the overarching wrapper that interacts with the HTTP response output should inherently validate and sanitize the input to prevent injection across all headers.
**Prevention:** `TusServletResponse.java` was modified to include a `sanitizeHeaderValue` method, replacing any instances of `\r` and `\n` characters before interacting with the core `HttpServletResponse`, ensuring consistent CRLF prevention application-wide.
## 2026-09-08 - Fix Arbitrary Origin Reflection in CORS Configuration
**Vulnerability:** The `CorsRequestHandler.java` implementation blindly read the `Origin` header from incoming HTTP requests and reflected its exact value back in the `Access-Control-Allow-Origin` response header.
**Learning:** Blindly mirroring the request's origin bypasses the intended security of CORS restrictions and can lead to arbitrary cross-origin data exposure, effectively negating the same-origin policy enforcement by browsers. Moreover, doing so without `Vary: Origin` could lead to cache poisoning in intermediate CDNs.
**Prevention:** Hardcode public API endpoint CORS rules to return the explicitly permissive `*` (wildcard) instead of reflecting the user's string input.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void process(

String origin = servletRequest.getHeader("Origin");
if (StringUtils.isNotBlank(origin)) {
servletResponse.setHeader("Access-Control-Allow-Origin", origin);
servletResponse.setHeader("Access-Control-Allow-Origin", "*");
servletResponse.setHeader(
"Access-Control-Expose-Headers",
"Upload-Offset, Upload-Length, Upload-Metadata, Upload-Expires, Upload-Concat, "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1843,7 +1843,7 @@ public void testCorsHeaders() throws Exception {
servletRequest.addHeader(HttpHeader.UPLOAD_LENGTH, 100L);

tusFileUploadService.process(servletRequest, servletResponse, OWNER_KEY);
assertResponseHeader("Access-Control-Allow-Origin", "https://example.com");
assertResponseHeader("Access-Control-Allow-Origin", "*");
assertResponseHeaderNotBlank("Access-Control-Expose-Headers");
}

Expand All @@ -1856,7 +1856,7 @@ public void testCorsPreflight() throws Exception {
servletRequest.addHeader("Access-Control-Request-Method", "PATCH");

tusFileUploadService.process(servletRequest, servletResponse, OWNER_KEY);
assertResponseHeader("Access-Control-Allow-Origin", "https://example.com");
assertResponseHeader("Access-Control-Allow-Origin", "*");
assertResponseHeader("Access-Control-Allow-Methods", "POST, GET, HEAD, PATCH, DELETE, OPTIONS");
assertResponseHeaderNotBlank("Access-Control-Allow-Headers");
assertResponseHeader("Access-Control-Max-Age", "86400");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void processWithOrigin() throws Exception {

handler.process(HttpMethod.GET, req, resp, null, null);

assertThat(mockResp.getHeader("Access-Control-Allow-Origin"), is("https://example.com"));
assertThat(mockResp.getHeader("Access-Control-Allow-Origin"), is("*"));
assertThat(
mockResp.getHeader("Access-Control-Expose-Headers"),
is(
Expand All @@ -70,7 +70,7 @@ public void processPreflight() throws Exception {

handler.process(HttpMethod.OPTIONS, req, resp, null, null);

assertThat(mockResp.getHeader("Access-Control-Allow-Origin"), is("https://example.com"));
assertThat(mockResp.getHeader("Access-Control-Allow-Origin"), is("*"));
assertThat(
mockResp.getHeader("Access-Control-Allow-Methods"),
is("POST, GET, HEAD, PATCH, DELETE, OPTIONS"));
Expand Down
Loading