mirror of https://github.com/status-im/metro.git
Fix asset path-traversal outside of roots
Summary:`/assets/...` requests previously supported path-traversal potentially exposing and serving (private) files outside roots. **Test plan** Prior to patching perform the a path-traversal request to the server: ``` GET /assets/../../../../etc/hosts HTTP/1.1 Cache-Control: no-store Host: 127.0.0.1:8081 Connection: close Accept-Encoding: gzip User-Agent: okhttp/2.5.0 ``` Apply patch and verify a `404` response with body: `Asset not found` Test normal asset requests work. Closes https://github.com/facebook/react-native/pull/6398 Differential Revision: D3034857 Pulled By: shayne fb-gh-sync-id: f0e6714e4e3c5a63a3a402634a1eb5f3186d3561 shipit-source-id: f0e6714e4e3c5a63a3a402634a1eb5f3186d3561
This commit is contained in:
parent
ebfb4f738a
commit
18612273be
|
@ -129,16 +129,23 @@ class AssetServer {
|
|||
_findRoot(roots, dir) {
|
||||
return Promise.all(
|
||||
roots.map(root => {
|
||||
const absPath = path.join(root, dir);
|
||||
// important: we want to resolve root + dir
|
||||
// to ensure the requested path doesn't traverse beyond root
|
||||
const absPath = path.resolve(root, dir);
|
||||
return stat(absPath).then(fstat => {
|
||||
return {path: absPath, isDirectory: fstat.isDirectory()};
|
||||
}, err => {
|
||||
return {path: absPath, isDirectory: false};
|
||||
// keep asset requests from traversing files
|
||||
// up from the root (e.g. ../../../etc/hosts)
|
||||
if (!absPath.startsWith(root)) {
|
||||
return {path: absPath, isValid: false};
|
||||
}
|
||||
return {path: absPath, isValid: fstat.isDirectory()};
|
||||
}, _ => {
|
||||
return {path: absPath, isValid: false};
|
||||
});
|
||||
})
|
||||
).then(stats => {
|
||||
for (let i = 0; i < stats.length; i++) {
|
||||
if (stats[i].isDirectory) {
|
||||
if (stats[i].isValid) {
|
||||
return stats[i].path;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue