fix(security): require https for trusted links
This commit is contained in:
1 parent
4e5af2b45f
commit
2ab001b18a
3 files changed
+15
-2
No files matched your search
@@ -47,7 +47,7 @@ export function classifyExternalUrl(rawUrl: string): ExternalUrlDecision {
|
|||||||
}
|
}
|
||||||
const parsed = new URL(normalized);
|
const parsed = new URL(normalized);
|
||||||
const host = parsed.hostname.toLowerCase();
|
const host = parsed.hostname.toLowerCase();
|
||||||
if (TRUSTED_EXTERNAL_HOSTS.has(host)) {
|
if (parsed.protocol === "https:" && TRUSTED_EXTERNAL_HOSTS.has(host)) {
|
||||||
return { kind: "trusted", url: normalized, host };
|
return { kind: "trusted", url: normalized, host };
|
||||||
}
|
}
|
||||||
return { kind: "confirm", url: normalized, host };
|
return { kind: "confirm", url: normalized, host };
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe("external URL policy", () => {
|
|||||||
|
|
||||||
it("separates trusted hosts from confirmation hosts", () => {
|
it("separates trusted hosts from confirmation hosts", () => {
|
||||||
expect(classifyExternalUrl("https://github.com/acme/repo")).toMatchObject({ kind: "trusted", host: "github.com" });
|
expect(classifyExternalUrl("https://github.com/acme/repo")).toMatchObject({ kind: "trusted", host: "github.com" });
|
||||||
|
expect(classifyExternalUrl("http://github.com/acme/repo")).toMatchObject({ kind: "confirm", host: "github.com" });
|
||||||
expect(classifyExternalUrl("https://example.com/report")).toMatchObject({ kind: "confirm", host: "example.com" });
|
expect(classifyExternalUrl("https://example.com/report")).toMatchObject({ kind: "confirm", host: "example.com" });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -87,7 +87,19 @@ describe("openWorkProduct external URL policy", () => {
|
|||||||
expect(electron.openExternal).toHaveBeenCalledWith("https://github.com/acme/repo");
|
expect(electron.openExternal).toHaveBeenCalledWith("https://github.com/acme/repo");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("asks before opening untrusted http hosts", async () => {
|
it("asks before opening trusted hosts over http", async () => {
|
||||||
|
electron.openExternal.mockClear();
|
||||||
|
electron.showMessageBox.mockClear();
|
||||||
|
electron.showMessageBox.mockResolvedValueOnce({ response: 0 });
|
||||||
|
|
||||||
|
const result = await openUrl("http://github.com/acme/repo");
|
||||||
|
|
||||||
|
expect(result).toEqual({ ok: true, data: true });
|
||||||
|
expect(electron.showMessageBox).toHaveBeenCalledTimes(1);
|
||||||
|
expect(electron.openExternal).toHaveBeenCalledWith("http://github.com/acme/repo");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("asks before opening untrusted hosts", async () => {
|
||||||
electron.openExternal.mockClear();
|
electron.openExternal.mockClear();
|
||||||
electron.showMessageBox.mockClear();
|
electron.showMessageBox.mockClear();
|
||||||
electron.showMessageBox.mockResolvedValueOnce({ response: 0 });
|
electron.showMessageBox.mockResolvedValueOnce({ response: 0 });
|
||||||
|
|||||||
Reference in new issue
Block a user