MCPcopy Index your code
hub / github.com/simstudioai/sim / validateUrlWithDNS

Function validateUrlWithDNS

apps/sim/lib/core/security/input-validation.server.ts:79–144  ·  view source on GitHub ↗
(
  url: string | null | undefined,
  paramName = 'url',
  options: { allowHttp?: boolean } = {}
)

Source from the content-addressed store, hash-verified

77 * @returns AsyncValidationResult with resolved IP for DNS pinning
78 */
79export async function validateUrlWithDNS(
80 url: string | null | undefined,
81 paramName = 'url',
82 options: { allowHttp?: boolean } = {}
83): Promise<AsyncValidationResult> {
84 const basicValidation = validateExternalUrl(url, paramName, options)
85 if (!basicValidation.isValid) {
86 return basicValidation
87 }
88
89 const parsedUrl = new URL(url!)
90 const hostname = parsedUrl.hostname
91
92 const hostnameLower = hostname.toLowerCase()
93 const cleanHostname =
94 hostnameLower.startsWith('[') && hostnameLower.endsWith(']')
95 ? hostnameLower.slice(1, -1)
96 : hostnameLower
97
98 let isLocalhost = cleanHostname === 'localhost'
99 if (ipaddr.isValid(cleanHostname)) {
100 const processedIP = ipaddr.process(cleanHostname).toString()
101 if (processedIP === '127.0.0.1' || processedIP === '::1') {
102 isLocalhost = true
103 }
104 }
105
106 try {
107 const { address } = await dns.lookup(cleanHostname, { verbatim: true })
108
109 const resolvedIsLoopback =
110 ipaddr.isValid(address) &&
111 (() => {
112 const ip = ipaddr.process(address).toString()
113 return ip === '127.0.0.1' || ip === '::1'
114 })()
115
116 if (isPrivateOrReservedIP(address) && !(isLocalhost && resolvedIsLoopback && !isHosted)) {
117 logger.warn('URL resolves to blocked IP address', {
118 paramName,
119 hostname,
120 resolvedIP: address,
121 })
122 return {
123 isValid: false,
124 error: `${paramName} resolves to a blocked IP address`,
125 }
126 }
127
128 return {
129 isValid: true,
130 resolvedIP: address,
131 originalHostname: hostname,
132 }
133 } catch (error) {
134 logger.warn('DNS lookup failed for URL', {
135 paramName,
136 hostname,

Callers 15

executeToolRequestFunction · 0.90
executeRequestFunction · 0.90
resolveAgiloftInstanceFunction · 0.90
index.tsFile · 0.90
index.tsFile · 0.90
index.tsFile · 0.90
downloadFalMediaFunction · 0.90
assertEndpointIsPublicFunction · 0.90
resolvePublicTargetFunction · 0.90
createA2AClientFunction · 0.90
resolveFileInputToUrlFunction · 0.90

Calls 5

validateExternalUrlFunction · 0.90
toErrorFunction · 0.90
isPrivateOrReservedIPFunction · 0.70
warnMethod · 0.65
toStringMethod · 0.45

Tested by

no test coverage detected