mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix path traversal bug in router (#2398)
* fix path traversal bug in router Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * add tests Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
0765bcee9c
commit
4856fdda2f
40
src/main/__test__/router.test.ts
Normal file
40
src/main/__test__/router.test.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { Router } from "../router";
|
||||||
|
|
||||||
|
const staticRoot = __dirname;
|
||||||
|
|
||||||
|
class TestRouter extends Router {
|
||||||
|
protected resolveStaticRootPath() {
|
||||||
|
return staticRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Router", () => {
|
||||||
|
it("blocks path traversal attacks", async () => {
|
||||||
|
const router = new TestRouter();
|
||||||
|
const res = {
|
||||||
|
statusCode: 200,
|
||||||
|
end: jest.fn()
|
||||||
|
};
|
||||||
|
|
||||||
|
await router.handleStaticFile("../index.ts", res as any, {} as any, 0);
|
||||||
|
|
||||||
|
expect(res.statusCode).toEqual(404);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("serves files under static root", async () => {
|
||||||
|
const router = new TestRouter();
|
||||||
|
const res = {
|
||||||
|
statusCode: 200,
|
||||||
|
write: jest.fn(),
|
||||||
|
setHeader: jest.fn(),
|
||||||
|
end: jest.fn()
|
||||||
|
};
|
||||||
|
const req = {
|
||||||
|
url: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
await router.handleStaticFile("router.test.ts", res as any, req as any, 0);
|
||||||
|
|
||||||
|
expect(res.statusCode).toEqual(200);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -40,10 +40,16 @@ export interface LensApiRequest<P = any> {
|
|||||||
|
|
||||||
export class Router {
|
export class Router {
|
||||||
protected router: any;
|
protected router: any;
|
||||||
|
protected staticRootPath: string;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
this.router = new Call.Router();
|
this.router = new Call.Router();
|
||||||
this.addRoutes();
|
this.addRoutes();
|
||||||
|
this.staticRootPath = this.resolveStaticRootPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected resolveStaticRootPath() {
|
||||||
|
return path.resolve(__static);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async route(cluster: Cluster, req: http.IncomingMessage, res: http.ServerResponse): Promise<boolean> {
|
public async route(cluster: Cluster, req: http.IncomingMessage, res: http.ServerResponse): Promise<boolean> {
|
||||||
@ -102,7 +108,15 @@ export class Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handleStaticFile(filePath: string, res: http.ServerResponse, req: http.IncomingMessage, retryCount = 0) {
|
async handleStaticFile(filePath: string, res: http.ServerResponse, req: http.IncomingMessage, retryCount = 0) {
|
||||||
const asset = path.join(__static, filePath);
|
const asset = path.join(this.staticRootPath, filePath);
|
||||||
|
const normalizedFilePath = path.resolve(asset);
|
||||||
|
|
||||||
|
if (!normalizedFilePath.startsWith(this.staticRootPath)) {
|
||||||
|
res.statusCode = 404;
|
||||||
|
res.end();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const filename = path.basename(req.url);
|
const filename = path.basename(req.url);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user