Unverified Commit 3bc4a826 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] avoid serving files outside of expected paths (#58653)

parent 03524a42
...@@ -275,7 +275,10 @@ class WebAssetServer implements AssetReader { ...@@ -275,7 +275,10 @@ class WebAssetServer implements AssetReader {
// handle requests for JavaScript source, dart sources maps, or asset files. // handle requests for JavaScript source, dart sources maps, or asset files.
@visibleForTesting @visibleForTesting
Future<shelf.Response> handleRequest(shelf.Request request) async { Future<shelf.Response> handleRequest(shelf.Request request) async {
final String requestPath = request.url.path; String requestPath = request.url.path;
while (requestPath.startsWith('/')) {
requestPath = requestPath.substring(1);
}
final Map<String, String> headers = <String, String>{}; final Map<String, String> headers = <String, String>{};
// If the response is `/`, then we are requesting the index file. // If the response is `/`, then we are requesting the index file.
if (request.url.path == '/' || request.url.path.isEmpty) { if (request.url.path == '/' || request.url.path.isEmpty) {
...@@ -339,8 +342,9 @@ class WebAssetServer implements AssetReader { ...@@ -339,8 +342,9 @@ class WebAssetServer implements AssetReader {
} }
if (!file.existsSync()) { if (!file.existsSync()) {
final String webPath = globals.fs.path.join( final Uri webPath = globals.fs.currentDirectory
globals.fs.currentDirectory.childDirectory('web').path, requestPath); .childDirectory('web')
.uri.resolve(requestPath);
file = globals.fs.file(webPath); file = globals.fs.file(webPath);
} }
...@@ -524,16 +528,14 @@ class WebAssetServer implements AssetReader { ...@@ -524,16 +528,14 @@ class WebAssetServer implements AssetReader {
final Directory dartSdkParent = globals.fs final Directory dartSdkParent = globals.fs
.directory(globals.artifacts.getArtifactPath(Artifact.engineDartSdkPath)) .directory(globals.artifacts.getArtifactPath(Artifact.engineDartSdkPath))
.parent; .parent;
final File dartSdkFile = globals.fs.file(globals.fs.path final File dartSdkFile = globals.fs.file(dartSdkParent.uri.resolve(path));
.joinAll(<String>[dartSdkParent.path, ...segments]));
if (dartSdkFile.existsSync()) { if (dartSdkFile.existsSync()) {
return dartSdkFile; return dartSdkFile;
} }
final String flutterWebSdk = globals.artifacts final Directory flutterWebSdk = globals.fs.directory(globals.artifacts
.getArtifactPath(Artifact.flutterWebSdk); .getArtifactPath(Artifact.flutterWebSdk));
final File webSdkFile = globals.fs final File webSdkFile = globals.fs.file(flutterWebSdk.uri.resolve(path));
.file(globals.fs.path.joinAll(<String>[flutterWebSdk, ...segments]));
return webSdkFile; return webSdkFile;
} }
......
...@@ -108,6 +108,27 @@ void main() { ...@@ -108,6 +108,27 @@ void main() {
Platform: () => linux, Platform: () => linux,
})); }));
test('Removes leading slashes for valid requests to avoid requesting outside'
' of served directory', () => testbed.run(() async {
globals.fs.file('foo.png').createSync();
globals.fs.currentDirectory = globals.fs.directory('project_directory')
..createSync();
final File source = globals.fs.file(globals.fs.path.join('web', 'foo.png'))
..createSync(recursive: true)
..writeAsBytesSync(kTransparentImage);
final Response response = await webAssetServer
.handleRequest(Request('GET', Uri.parse('http://foobar////foo.png')));
expect(response.headers, allOf(<Matcher>[
containsPair(HttpHeaders.contentLengthHeader, source.lengthSync().toString()),
containsPair(HttpHeaders.contentTypeHeader, 'image/png'),
containsPair(HttpHeaders.etagHeader, isNotNull),
containsPair(HttpHeaders.cacheControlHeader, 'max-age=0, must-revalidate')
]));
expect((await response.read().toList()).first, source.readAsBytesSync());
}));
test('serves JavaScript files from in memory cache not from manifest', () => testbed.run(() async { test('serves JavaScript files from in memory cache not from manifest', () => testbed.run(() async {
webAssetServer.writeFile('foo.js', 'main() {}'); webAssetServer.writeFile('foo.js', 'main() {}');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment