MCPcopy Create free account
hub / github.com/lightdash/lightdash / validatePublicHttpUrl

Function validatePublicHttpUrl

packages/backend/src/utils/ssrfProtection.ts:34–78  ·  view source on GitHub ↗
(
    rawUrl: string,
    options: {
        allowedProtocols?: string[];
        allowPrivateAddresses?: boolean;
    } = {},
)

Source from the content-addressed store, hash-verified

32};
33
34export const validatePublicHttpUrl = async (
35 rawUrl: string,
36 options: {
37 allowedProtocols?: string[];
38 allowPrivateAddresses?: boolean;
39 } = {},
40): Promise<URL> => {
41 const allowedProtocols = options.allowedProtocols ?? ['https:'];
42
43 let parsedUrl: URL;
44 try {
45 parsedUrl = new URL(rawUrl);
46 } catch {
47 throw new ParameterError(INVALID_URL_ERROR_MESSAGE);
48 }
49
50 if (!allowedProtocols.includes(parsedUrl.protocol)) {
51 throw new ParameterError(INVALID_PROTOCOL_ERROR_MESSAGE);
52 }
53
54 if (parsedUrl.username || parsedUrl.password) {
55 throw new ParameterError(URL_CREDENTIALS_ERROR_MESSAGE);
56 }
57
58 if (options.allowPrivateAddresses) {
59 return parsedUrl;
60 }
61
62 if (isPrivateAddress(parsedUrl.hostname)) {
63 throw new ParameterError(PRIVATE_ADDRESS_ERROR_MESSAGE);
64 }
65
66 let addresses: { address: string }[];
67 try {
68 addresses = await lookup(parsedUrl.hostname, { all: true });
69 } catch {
70 throw new ParameterError(HOSTNAME_LOOKUP_ERROR_MESSAGE);
71 }
72
73 if (addresses.some(({ address }) => isPrivateAddress(address))) {
74 throw new ParameterError(PRIVATE_ADDRESS_ERROR_MESSAGE);
75 }
76
77 return parsedUrl;
78};

Callers 3

assertPublicSsoUrlMethod · 0.90
createMcpServerMethod · 0.90

Calls 2

isPrivateAddressFunction · 0.85
lookupFunction · 0.85

Tested by

no test coverage detected