8281305: Test com/sun/net/httpserver/simpleserver/MapToPathTest.java fails on Windows 11
Reviewed-by: dfuchs
This commit is contained in:
parent
b4900b1298
commit
9ca435b4c0
@ -227,9 +227,12 @@ public final class FileServerHandler implements HttpHandler {
|
||||
// resolve each path segment against the root
|
||||
Path path = root;
|
||||
for (var segment : pathSegment) {
|
||||
if (!URIPathSegment.isSupported(segment)) {
|
||||
return null; // stop resolution, null results in 404 response
|
||||
}
|
||||
path = path.resolve(segment);
|
||||
if (!Files.isReadable(path) || isHiddenOrSymLink(path)) {
|
||||
return null; // stop resolution, null results in 404 response
|
||||
return null; // stop resolution
|
||||
}
|
||||
}
|
||||
path = path.normalize();
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.net.httpserver.simpleserver;
|
||||
|
||||
/**
|
||||
* A class that represents a URI path segment.
|
||||
*/
|
||||
final class URIPathSegment {
|
||||
|
||||
private URIPathSegment() { throw new AssertionError(); }
|
||||
|
||||
/**
|
||||
* Checks if the segment of a URI path is supported.
|
||||
*
|
||||
* @param segment the segment string
|
||||
* @return true
|
||||
*/
|
||||
static boolean isSupported(String segment) {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.net.httpserver.simpleserver;
|
||||
|
||||
/**
|
||||
* A class that represents a URI path segment.
|
||||
*/
|
||||
final class URIPathSegment {
|
||||
|
||||
private URIPathSegment() { throw new AssertionError(); }
|
||||
|
||||
/**
|
||||
* Checks if the segment of a URI path is supported. For example,
|
||||
* "C:" is supported as a drive on Windows only.
|
||||
*
|
||||
* @param segment the segment string
|
||||
* @return true if the segment is supported
|
||||
*/
|
||||
static boolean isSupported(String segment) {
|
||||
// apply same logic as WindowsPathParser
|
||||
if (segment.length() >= 2 && isLetter(segment.charAt(0)) && segment.charAt(1) == ':') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isLetter(char c) {
|
||||
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
|
||||
}
|
||||
}
|
@ -137,19 +137,27 @@ public class MapToPathTest {
|
||||
var res3 = client.send(req3, BodyHandlers.ofString());
|
||||
assertEquals(res3.statusCode(), 404); // not found
|
||||
|
||||
var req4 = HttpRequest.newBuilder(uri(server, "/foo/file:" + TEST_DIR.getParent())).build();
|
||||
var req4 = HttpRequest.newBuilder(uri(server, "/foo/bar/baz/c:.//")).build();
|
||||
var res4 = client.send(req4, BodyHandlers.ofString());
|
||||
assertEquals(res4.statusCode(), 404); // not found
|
||||
|
||||
var req5 = HttpRequest.newBuilder(uri(server, "/foo/bar/\\..\\../")).build();
|
||||
var req5 = HttpRequest.newBuilder(uri(server, "/foo/bar/baz/c:..//")).build();
|
||||
var res5 = client.send(req5, BodyHandlers.ofString());
|
||||
assertEquals(res5.statusCode(), 404); // not found
|
||||
|
||||
var req6 = HttpRequest.newBuilder(uri(server, "/foo")).build();
|
||||
var req6 = HttpRequest.newBuilder(uri(server, "/foo/file:" + TEST_DIR.getParent())).build();
|
||||
var res6 = client.send(req6, BodyHandlers.ofString());
|
||||
assertEquals(res6.statusCode(), 301); // redirect
|
||||
assertEquals(res6.headers().firstValue("content-length").get(), "0");
|
||||
assertEquals(res6.headers().firstValue("location").get(), "/foo/");
|
||||
assertEquals(res6.statusCode(), 404); // not found
|
||||
|
||||
var req7 = HttpRequest.newBuilder(uri(server, "/foo/bar/\\..\\../")).build();
|
||||
var res7 = client.send(req7, BodyHandlers.ofString());
|
||||
assertEquals(res7.statusCode(), 404); // not found
|
||||
|
||||
var req8 = HttpRequest.newBuilder(uri(server, "/foo")).build();
|
||||
var res8 = client.send(req8, BodyHandlers.ofString());
|
||||
assertEquals(res8.statusCode(), 301); // redirect
|
||||
assertEquals(res8.headers().firstValue("content-length").get(), "0");
|
||||
assertEquals(res8.headers().firstValue("location").get(), "/foo/");
|
||||
} finally {
|
||||
server.stop(0);
|
||||
}
|
||||
@ -250,6 +258,29 @@ public class MapToPathTest {
|
||||
server.stop(0);
|
||||
}
|
||||
}
|
||||
{
|
||||
// Test that a request path segment that is a Windows root drive
|
||||
// does not circumvent access restrictions.
|
||||
//
|
||||
// For example, given the test directory tree:
|
||||
//
|
||||
// |-- TEST_DIR
|
||||
// |-- foo
|
||||
// |-- bar ----->>> if hidden, itself and any of its subdirectories are not accessible
|
||||
// |-- baz
|
||||
// |-- file.txt
|
||||
// ...
|
||||
var handler = SimpleFileServer.createFileHandler(TEST_DIR);
|
||||
var server = HttpServer.create(LOOPBACK_ADDR, 10, "/", handler, OUTPUT_FILTER);
|
||||
server.start();
|
||||
try {
|
||||
var req1 = HttpRequest.newBuilder(uri(server, "/foo/bar/c:/baz/")).build();
|
||||
var res1 = client.send(req1, BodyHandlers.ofString());
|
||||
assertEquals(res1.statusCode(), 404); // not found
|
||||
} finally {
|
||||
server.stop(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests with a mixture of in-memory and file handlers.
|
||||
|
Loading…
x
Reference in New Issue
Block a user