Skip to content

Commit

Permalink
Check if either the request or response ip is an internal ip. Fail th…
Browse files Browse the repository at this point in the history
…e request if this is the case (#238)
  • Loading branch information
mikkeldenker authored Nov 29, 2024
1 parent 3b2a5f7 commit 3945651
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions frontend/src/lib/optics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,49 @@ export const DEFAULT_OPTICS = [
},
] satisfies DefaultOpticOption[];

const isPrivateIp4 = (url: string) => {
const parts = url.split('://');
const ip =
parts.length > 0
? parts[parts.length - 1].replace(/\/$/, '').split(':')[0]
: url.replace(/\/$/, '').split(':')[0];

if (/^(10)\.(.*)\.(.*)\.(.*)$/.test(ip)) return true;
if (/^(172)\.(1[6-9]|2[0-9]|3[0-1])\.(.*)\.(.*)$/.test(ip)) return true;
if (/^(192)\.168\.(.*)\.(.*)$/.test(ip)) return true;
if (/^(127)\.(0)\.(0)\.(1)$/.test(ip)) return true;
if (/^(100)\.(6[4-9]|[7-9][0-9]|1[0-1][0-9]|12[0-7])\.(.*)\.(.*)$/.test(ip)) return true;

return false;
};

const isPrivateIp6 = (url: string) => {
const parts = url.split('://');
const ip =
parts.length > 0
? parts[parts.length - 1].replace(/\/$/, '').split(':')[0]
: url.replace(/\/$/, '');

if (/^fe80::/i.test(ip)) return true;
if (/^fd[0-9a-f]{2}:/i.test(ip)) return true;

return false;
};

const isPrivateIp = (url: string) => isPrivateIp4(url) || isPrivateIp6(url);

/**
* Fetces the given `opticUrl` if allowed. The rules for which are allowed
* should consider potentially malicious URLs such as `file://` or
* internal/local IP addresses.
*/
export const fetchRemoteOptic = async (opts: { opticUrl: string; fetch?: typeof fetch }) => {
if (opts.opticUrl.startsWith('file://')) return void 0;
if (isPrivateIp(opts.opticUrl)) return void 0;

const response = await (opts.fetch ?? fetch)(opts.opticUrl);

if (isPrivateIp(response.url)) return void 0;

return await response.text();
};

0 comments on commit 3945651

Please sign in to comment.