@@ -24,22 +24,24 @@ public StaticFileHandler(String webRoot) {
2424 }
2525
2626 public void sendGetRequest (OutputStream outputStream , String uri ) throws IOException {
27- if (isPathTraversal (uri )) {
27+ String sanitizedUri = sanitizeUri (uri );
28+
29+ if (isPathTraversal (sanitizedUri )) {
2830 writeResponse (outputStream , 403 , "Forbidden" );
2931 return ;
3032 }
3133
3234 try {
33- String cacheKey = "www:" + uri ;
35+ String cacheKey = "www:" + sanitizedUri ;
3436 byte [] fileBytes = FileCache .get (cacheKey );
3537
3638 if (fileBytes == null ) {
37- fileBytes = Files .readAllBytes (new File (webRoot , uri ).toPath ());
39+ fileBytes = Files .readAllBytes (new File (webRoot , sanitizedUri ).toPath ());
3840 FileCache .put (cacheKey , fileBytes );
3941 }
4042
4143 HttpResponseBuilder response = new HttpResponseBuilder ();
42- response .setContentTypeFromFilename (uri );
44+ response .setContentTypeFromFilename (sanitizedUri );
4345 response .setBody (fileBytes );
4446 outputStream .write (response .build ());
4547 outputStream .flush ();
@@ -51,6 +53,21 @@ public void sendGetRequest(OutputStream outputStream, String uri) throws IOExcep
5153 }
5254 }
5355
56+
57+ private String sanitizeUri (String uri ) {
58+ if (uri == null || uri .isEmpty ()) return "index.html" ;
59+
60+ int endIndex = Math .min (
61+ uri .indexOf ('?' ) < 0 ? uri .length () : uri .indexOf ('?' ),
62+ uri .indexOf ('#' ) < 0 ? uri .length () : uri .indexOf ('#' )
63+ );
64+
65+ return uri .substring (0 , endIndex )
66+ .replace ("\0 " , "" )
67+ .replaceAll ("^/+" , "" )
68+ .replaceAll ("^$" , "index.html" );
69+ }
70+
5471 private boolean isPathTraversal (String uri ) {
5572 try {
5673 Path webRootPath = Paths .get (webRoot ).toAbsolutePath ().normalize ();
0 commit comments