Skip to content

Commit abf6989

Browse files
authored
add option to disable or restrict cors endpoint (#4087)
1 parent 03f2689 commit abf6989

3 files changed

Lines changed: 26 additions & 0 deletions

File tree

js/defaults.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const defaults = {
1111
basePath: "/",
1212
electronOptions: {},
1313
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
14+
cors: "disabled", // or "allowAll" or "allowWhitelist"
15+
corsDomainWhitelist: [], // example: ["api.mapbox.com"]
1416

1517
language: "en",
1618
logLevel: ["INFO", "LOG", "WARN", "ERROR"],

js/server_functions.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ async function isPrivateTarget (url) {
2525
const hostname = parsed.hostname.replace(/^\[|\]$/g, "");
2626

2727
if (hostname.toLowerCase() === "localhost") return true;
28+
if (global.config.cors === "allowWhitelist" && !global.config.corsDomainWhitelist.includes(hostname.toLowerCase())) return true;
2829

2930
try {
3031
const results = await dns.lookup(hostname, { all: true });
@@ -68,6 +69,10 @@ function replaceSecretPlaceholder (input) {
6869
* @returns {Promise<void>} A promise that resolves when the response is sent
6970
*/
7071
async function cors (req, res) {
72+
if (global.config.cors === "disabled") {
73+
Log.error("CORS is disabled, you need to enable it in `config.js` by setting `cors` to `allowAll` or `allowWhitelist`");
74+
return res.status(403).json({ error: "CORS proxy is disabled" });
75+
}
7176
try {
7277
const urlRegEx = "url=(.+?)$";
7378
let url;

tests/unit/functions/server_functions_spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe("server_functions tests", () => {
3535
let fetchMock;
3636

3737
beforeEach(() => {
38+
global.config = { cors: "allowAll" };
3839
fetchResponseHeadersGet = vi.fn(() => {});
3940
fetchResponseArrayBuffer = vi.fn(() => {});
4041
fetchResponse = {
@@ -263,4 +264,22 @@ describe("server_functions tests", () => {
263264
expect(response.json).toHaveBeenCalledWith({ error: "Forbidden: private or reserved addresses are not allowed" });
264265
});
265266
});
267+
268+
describe("The isPrivateTarget method with allowWhitelist", () => {
269+
beforeEach(() => {
270+
mockLookup.mockReset();
271+
});
272+
273+
it("Block public unicast IPs if not whitelistet", async () => {
274+
global.config = { cors: "allowWhitelist", corsDomainWhitelist: [] };
275+
mockLookup.mockResolvedValue([{ address: "93.184.216.34", family: 4 }]);
276+
expect(await isPrivateTarget("http://example.com/api")).toBe(true);
277+
});
278+
279+
it("Allow public unicast IPs if whitelistet", async () => {
280+
global.config = { cors: "allowWhitelist", corsDomainWhitelist: ["example.com"] };
281+
mockLookup.mockResolvedValue([{ address: "93.184.216.34", family: 4 }]);
282+
expect(await isPrivateTarget("http://example.com/api")).toBe(false);
283+
});
284+
});
266285
});

0 commit comments

Comments
 (0)