From 67898152171cd8a9f6f927f12c47aa306105158c Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 24 Mar 2021 19:22:17 +0200 Subject: [PATCH 1/6] Set initial cursor position for the editor to beginning (#2385) Signed-off-by: Roman --- src/renderer/components/ace-editor/ace-editor.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/renderer/components/ace-editor/ace-editor.tsx b/src/renderer/components/ace-editor/ace-editor.tsx index 2dceb48bba..180c142ffd 100644 --- a/src/renderer/components/ace-editor/ace-editor.tsx +++ b/src/renderer/components/ace-editor/ace-editor.tsx @@ -32,6 +32,7 @@ const defaultProps: Partial = { useWorker: false, onBlur: noop, onFocus: noop, + cursorPos: { row: 0, column: 0 }, }; @observer From 7a352537100e3543021f65105fc08f71c700d927 Mon Sep 17 00:00:00 2001 From: Jari Kolehmainen Date: Thu, 25 Mar 2021 12:50:13 +0200 Subject: [PATCH 2/6] Proxy should listen only on loopback device (#2388) Signed-off-by: Jari Kolehmainen --- src/main/lens-proxy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/lens-proxy.ts b/src/main/lens-proxy.ts index 7e1aa98b7e..0bc3528a33 100644 --- a/src/main/lens-proxy.ts +++ b/src/main/lens-proxy.ts @@ -28,7 +28,7 @@ export class LensProxy { } listen(port = this.port): this { - this.proxyServer = this.buildCustomProxy().listen(port); + this.proxyServer = this.buildCustomProxy().listen(port, "127.0.0.1"); logger.info(`[LENS-PROXY]: Proxy server has started at ${this.origin}`); return this; From 2c50e7aa1c97e0764f5bdf628b571e36207814b5 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 25 Mar 2021 13:19:58 +0200 Subject: [PATCH 3/6] refactoring: get rid of SidebarItem.props.subMenus in favour of props.children only (#2384) Signed-off-by: Roman --- .../components/layout/sidebar-item.tsx | 30 ++++--- src/renderer/components/layout/sidebar.tsx | 84 ++++++++++--------- 2 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/renderer/components/layout/sidebar-item.tsx b/src/renderer/components/layout/sidebar-item.tsx index da36b43c17..64956842aa 100644 --- a/src/renderer/components/layout/sidebar-item.tsx +++ b/src/renderer/components/layout/sidebar-item.tsx @@ -26,7 +26,6 @@ interface SidebarItemProps { * this item should be shown as active */ isActive?: boolean; - subMenus?: React.ReactNode | React.ComponentType[]; } @observer @@ -53,11 +52,9 @@ export class SidebarItem extends React.Component { } @computed get isExpandable(): boolean { - if (this.compact) { - return false; // not available currently - } + if (this.compact) return false; // not available in compact-mode currently - return Boolean(this.props.subMenus || this.props.children); + return Boolean(this.props.children); } toggleExpand = () => { @@ -66,8 +63,22 @@ export class SidebarItem extends React.Component { }); }; + renderSubMenu() { + const { isExpandable, expanded, isActive } = this; + + if (!isExpandable || !expanded) { + return; + } + + return ( +
    + {this.props.children} +
+ ); + } + render() { - const { isHidden, icon, text, children, url, className, subMenus } = this.props; + const { isHidden, icon, text, url, className } = this.props; if (isHidden) return null; @@ -90,12 +101,7 @@ export class SidebarItem extends React.Component { material={expanded ? "keyboard_arrow_up" : "keyboard_arrow_down"} />} - {isExpandable && expanded && ( -
    - {subMenus} - {children} -
- )} + {this.renderSubMenu()} ); } diff --git a/src/renderer/components/layout/sidebar.tsx b/src/renderer/components/layout/sidebar.tsx index 522e06674c..531c9db1a0 100644 --- a/src/renderer/components/layout/sidebar.tsx +++ b/src/renderer/components/layout/sidebar.tsx @@ -51,25 +51,20 @@ export class Sidebar extends React.Component { } return Object.entries(crdStore.groups).map(([group, crds]) => { - const crdGroupSubMenu: React.ReactNode = crds.map((crd) => { - return ( - - ); - }); + const id = `crd-group:${group}`; + const crdGroupsPageUrl = crdURL({ query: { groups: group } }); return ( - + + {crds.map((crd) => ( + + ))} + ); }); } @@ -147,8 +142,9 @@ export class Sidebar extends React.Component { isActive={isActive} text={menuItem.title} icon={} - subMenus={this.renderTreeFromTabRoutes(tabRoutes)} - /> + > + {this.renderTreeFromTabRoutes(tabRoutes)} + ); }); } @@ -175,88 +171,94 @@ export class Sidebar extends React.Component {
} /> } /> } - /> + > + {this.renderTreeFromTabRoutes(Workloads.tabRoutes)} + } - /> + > + {this.renderTreeFromTabRoutes(Config.tabRoutes)} + } - /> + > + {this.renderTreeFromTabRoutes(Network.tabRoutes)} + } - text="Storage" - /> + > + {this.renderTreeFromTabRoutes(Storage.tabRoutes)} + } - text="Namespaces" /> } - text="Events" /> } - text="Apps" - /> + > + {this.renderTreeFromTabRoutes(Apps.tabRoutes)} + } - text="Access Control" - /> + > + {this.renderTreeFromTabRoutes(UserManagement.tabRoutes)} + Date: Thu, 25 Mar 2021 17:19:45 +0200 Subject: [PATCH 4/6] Add security policy (#2387) * add security policy Signed-off-by: Jari Kolehmainen * tweak Signed-off-by: Jari Kolehmainen --- SECURITY.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..b1a54ec9d0 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,9 @@ +# Security Policy + +## Reporting a Vulnerability + +Team Lens encourages users who become aware of a security vulnerability in Lens to contact Team Lens with details of the vulnerability. Team Lens has established an email address that should be used for reporting a vulnerability. Please send descriptions of any vulnerabilities found to security@k8slens.dev. Please include details on the software and hardware configuration of your system so that we can duplicate the issue being reported. + +Team Lens hopes that users encountering a new vulnerability will contact us privately as it is in the best interests of our users that Team Lens has an opportunity to investigate and confirm a suspected vulnerability before it becomes public knowledge. + +In the case of vulnerabilities found in third-party software components used in Lens, please also notify Team Lens as described above. From 4856fdda2fac1408ff053fd3dad1a9ffe137af4e Mon Sep 17 00:00:00 2001 From: Jari Kolehmainen Date: Fri, 26 Mar 2021 14:53:53 +0200 Subject: [PATCH 5/6] Fix path traversal bug in router (#2398) * fix path traversal bug in router Signed-off-by: Jari Kolehmainen * add tests Signed-off-by: Jari Kolehmainen --- src/main/__test__/router.test.ts | 40 ++++++++++++++++++++++++++++++++ src/main/router.ts | 16 ++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/main/__test__/router.test.ts diff --git a/src/main/__test__/router.test.ts b/src/main/__test__/router.test.ts new file mode 100644 index 0000000000..8c2fa9c822 --- /dev/null +++ b/src/main/__test__/router.test.ts @@ -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); + }); +}); diff --git a/src/main/router.ts b/src/main/router.ts index bb49aacdab..6fa14e1444 100644 --- a/src/main/router.ts +++ b/src/main/router.ts @@ -40,10 +40,16 @@ export interface LensApiRequest

{ export class Router { protected router: any; + protected staticRootPath: string; public constructor() { this.router = new Call.Router(); this.addRoutes(); + this.staticRootPath = this.resolveStaticRootPath(); + } + + protected resolveStaticRootPath() { + return path.resolve(__static); } public async route(cluster: Cluster, req: http.IncomingMessage, res: http.ServerResponse): Promise { @@ -102,7 +108,15 @@ export class Router { } 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 { const filename = path.basename(req.url); From 6d7b6489d589bdbef9fee0a78118c212ab9c6496 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 26 Mar 2021 11:40:39 -0400 Subject: [PATCH 6/6] release v4.2.0-rc.3 Signed-off-by: Sebastian Malton --- package.json | 2 +- static/RELEASE_NOTES.md | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e346f8c11f..abeb0816b0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "kontena-lens", "productName": "Lens", "description": "Lens - The Kubernetes IDE", - "version": "4.2.0-rc.2", + "version": "4.2.0-rc.3", "main": "static/build/main.js", "copyright": "© 2021, Mirantis, Inc.", "license": "MIT", diff --git a/static/RELEASE_NOTES.md b/static/RELEASE_NOTES.md index 7aa58e564c..f391d0d4b2 100644 --- a/static/RELEASE_NOTES.md +++ b/static/RELEASE_NOTES.md @@ -2,7 +2,7 @@ Here you can find description of changes we've built into each release. While we try our best to make each upgrade automatic and as smooth as possible, there may be some cases where you might need to do something to ensure the application works smoothly. So please read through the release highlights! -## 4.2.0-rc.2 (current version) +## 4.2.0-rc.3 (current version) - Add lens:// protocol handling with a routing mechanism - Add common app routes to the protocol renderer router from the documentation @@ -33,6 +33,10 @@ Here you can find description of changes we've built into each release. While we - Fix: Closing workspace menu after clicking on iframe - Fix: extension global pages are never able to be visible - Fix: recreate proxy kubeconfig if it is deleted +- Fix: Proxy should listen only on loopback device +- Fix: Block global path traversal in router +- Fix: Set initial cursor position for the editor to beginning +- Fix: Highlight sidebar's active section ## 4.1.4