{"version":3,"file":"_validation-chunk.mjs","sources":["../../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/angular/ssr/src/utils/validation.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * Internal sentinel string representing a wildcard rule to trust all proxy headers.\n */\nconst TRUST_ALL_PROXY_HEADERS = '*';\n\n/**\n * The set of headers that should be validated for host header injection attacks.\n */\nconst HOST_HEADERS_TO_VALIDATE: ReadonlyArray<string> = ['host', 'x-forwarded-host'];\n\n/**\n * Regular expression to validate that the port is a numeric value.\n */\nconst VALID_PORT_REGEX = /^\\d+$/;\n\n/**\n * Regular expression to validate that the protocol is either http or https (case-insensitive).\n */\nconst VALID_PROTO_REGEX = /^https?$/i;\n\n/**\n * Regular expression to validate that the prefix is valid. Validates that the prefix is a valid path prefix and nothing else.\n * It validates that the prefix starts with a forward slash and contains only letters, numbers, hyphens, underscores and forward slashes.\n */\nconst VALID_PREFIX_REGEX = /^\\/([a-z0-9_-]+\\/)*[a-z0-9_-]*$/i;\n\n/**\n * Extracts the first value from a multi-value header string.\n *\n * @param value - A string or an array of strings representing the header values.\n *                If it's a string, values are expected to be comma-separated.\n * @returns The first trimmed value from the multi-value header, or `undefined` if the input is invalid or empty.\n *\n * @example\n * ```typescript\n * getFirstHeaderValue(\"value1, value2, value3\"); // \"value1\"\n * getFirstHeaderValue([\"value1\", \"value2\"]); // \"value1\"\n * getFirstHeaderValue(undefined); // undefined\n * ```\n */\nexport function getFirstHeaderValue(\n  value: string | string[] | undefined | null,\n): string | undefined {\n  return value?.toString().split(',', 1)[0]?.trim();\n}\n\n/**\n * Validates a request.\n *\n * @param request - The incoming `Request` object to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @param disableHostCheck - Whether to disable the host check.\n * @throws Error if any of the validated headers contain invalid values.\n */\nexport function validateRequest(\n  request: Request,\n  allowedHosts: ReadonlySet<string>,\n  disableHostCheck: boolean,\n): void {\n  validateHeaders(request, allowedHosts, disableHostCheck);\n\n  if (!disableHostCheck) {\n    validateUrl(new URL(request.url), allowedHosts);\n  }\n}\n\n/**\n * Validates that the hostname of a given URL is allowed.\n *\n * @param url - The URL object to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @throws Error if the hostname is not in the allowlist.\n */\nexport function validateUrl(url: URL, allowedHosts: ReadonlySet<string>): void {\n  const { hostname } = url;\n  if (!isHostAllowed(hostname, allowedHosts)) {\n    throw new Error(`URL with hostname \"${hostname}\" is not allowed.`);\n  }\n}\n\n/**\n * Sanitizes the proxy headers of a request by removing unallowed `X-Forwarded-*` headers.\n * If no headers need to be removed, the original request is returned without cloning.\n *\n * @param request - The incoming `Request` object to sanitize.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n * @returns The sanitized request, or the original request if no changes were needed.\n */\nexport function sanitizeRequestHeaders(\n  request: Request,\n  trustProxyHeaders: ReadonlySet<string>,\n): Request {\n  let headersDeleted = false;\n  const headers = new Headers();\n\n  for (const [key, value] of request.headers) {\n    const lowerKey = key.toLowerCase();\n    const isProxyHeader = lowerKey === 'forwarded' || lowerKey.startsWith('x-forwarded-');\n    if (isProxyHeader && !isProxyHeaderAllowed(lowerKey, trustProxyHeaders)) {\n      // eslint-disable-next-line no-console\n      console.warn(\n        `Received \"${key}\" header but \"trustProxyHeaders\" was not set up to allow it.\\n` +\n          `For more information, see https://angular.dev/best-practices/security#configuring-trusted-proxy-headers`,\n      );\n      headersDeleted = true;\n    } else {\n      headers.set(key, value);\n    }\n  }\n\n  return headersDeleted\n    ? new Request(request.clone(), {\n        signal: request.signal,\n        headers,\n      })\n    : request;\n}\n\n/**\n * Validates a specific host header value against the allowed hosts.\n *\n * @param headerName - The name of the header to validate (e.g., 'host', 'x-forwarded-host').\n * @param headerValue - The value of the header to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @throws Error if the header value is invalid or the hostname is not in the allowlist.\n */\nfunction verifyHostAllowed(\n  headerName: string,\n  headerValue: string,\n  allowedHosts: ReadonlySet<string>,\n): void {\n  const url = `http://${headerValue}`;\n  if (!URL.canParse(url)) {\n    throw new Error(`Header \"${headerName}\" contains an invalid value and cannot be parsed.`);\n  }\n\n  const { hostname, pathname, search, hash, username, password } = new URL(url);\n  if (pathname !== '/' || search || hash || username || password) {\n    throw new Error(\n      `Header \"${headerName}\" with value \"${headerValue}\" contains characters that are not allowed.`,\n    );\n  }\n\n  if (!isHostAllowed(hostname, allowedHosts)) {\n    throw new Error(`Header \"${headerName}\" with value \"${headerValue}\" is not allowed.`);\n  }\n}\n\n/**\n * Checks if the hostname is allowed.\n * @param hostname - The hostname to check.\n * @param allowedHosts - A set of allowed hostnames.\n * @returns `true` if the hostname is allowed, `false` otherwise.\n */\nfunction isHostAllowed(hostname: string, allowedHosts: ReadonlySet<string>): boolean {\n  if (allowedHosts.has('*') || allowedHosts.has(hostname)) {\n    return true;\n  }\n\n  for (const allowedHost of allowedHosts) {\n    if (!allowedHost.startsWith('*.')) {\n      continue;\n    }\n\n    const domain = allowedHost.slice(1);\n    if (hostname.endsWith(domain)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Validates the headers of an incoming request.\n *\n * @param request - The incoming `Request` object containing the headers to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @param disableHostCheck - Whether to disable the host check.\n * @throws Error if any of the validated headers contain invalid values.\n */\nfunction validateHeaders(\n  request: Request,\n  allowedHosts: ReadonlySet<string>,\n  disableHostCheck: boolean,\n): void {\n  const headers = request.headers;\n  for (const headerName of HOST_HEADERS_TO_VALIDATE) {\n    const headerValue = getFirstHeaderValue(headers.get(headerName));\n    if (headerValue && !disableHostCheck) {\n      verifyHostAllowed(headerName, headerValue, allowedHosts);\n    }\n  }\n\n  const forwarded = headers.get('forwarded');\n  if (forwarded) {\n    const forwardedParams = parseForwardedHeader(forwarded);\n    if (forwardedParams.host && !disableHostCheck) {\n      verifyHostAllowed('Forwarded \"host\"', forwardedParams.host, allowedHosts);\n    }\n    if (forwardedParams.proto && !VALID_PROTO_REGEX.test(forwardedParams.proto)) {\n      throw new Error('Header \"forwarded\" proto parameter must be either \"http\" or \"https\".');\n    }\n  }\n\n  const xForwardedPort = getFirstHeaderValue(headers.get('x-forwarded-port'));\n  if (xForwardedPort && !VALID_PORT_REGEX.test(xForwardedPort)) {\n    throw new Error('Header \"x-forwarded-port\" must be a numeric value.');\n  }\n\n  const xForwardedProto = getFirstHeaderValue(headers.get('x-forwarded-proto'));\n  if (xForwardedProto && !VALID_PROTO_REGEX.test(xForwardedProto)) {\n    throw new Error('Header \"x-forwarded-proto\" must be either \"http\" or \"https\".');\n  }\n\n  const xForwardedPrefix = getFirstHeaderValue(headers.get('x-forwarded-prefix'));\n  if (xForwardedPrefix && !VALID_PREFIX_REGEX.test(xForwardedPrefix)) {\n    throw new Error(\n      'Header \"x-forwarded-prefix\" is invalid. It must start with a \"/\" and contain ' +\n        'only alphanumeric characters, hyphens, and underscores, separated by single slashes.',\n    );\n  }\n}\n\n/**\n * Checks if a specific proxy header is allowed.\n *\n * @param headerName - The name of the proxy header to check.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n * @returns `true` if the header is allowed, `false` otherwise.\n */\nexport function isProxyHeaderAllowed(\n  headerName: string,\n  trustProxyHeaders: ReadonlySet<string>,\n): boolean {\n  return (\n    trustProxyHeaders.has(TRUST_ALL_PROXY_HEADERS) ||\n    trustProxyHeaders.has(headerName.toLowerCase())\n  );\n}\n\n/**\n * Normalizes the `trustProxyHeaders` option to a consistent representation.\n * @param trustProxyHeaders The input `trustProxyHeaders` value.\n * @returns A `Set<string>` of normalized header names.\n */\nexport function normalizeTrustProxyHeaders(\n  trustProxyHeaders: boolean | readonly string[] | undefined,\n): ReadonlySet<string> {\n  if (!trustProxyHeaders) {\n    return new Set();\n  }\n\n  if (trustProxyHeaders === true) {\n    return new Set([TRUST_ALL_PROXY_HEADERS]);\n  }\n\n  const normalizedTrustedProxyHeaders = new Set<string>();\n  for (const header of trustProxyHeaders) {\n    const lowerHeader = header.toLowerCase();\n    if (lowerHeader === TRUST_ALL_PROXY_HEADERS) {\n      throw new Error(\n        `\"${TRUST_ALL_PROXY_HEADERS}\" is not allowed as a value for the \"trustProxyHeaders\" option.`,\n      );\n    }\n    const isValid = lowerHeader === 'forwarded' || lowerHeader.startsWith('x-forwarded-');\n    if (!isValid) {\n      throw new Error(\n        `\"${header}\" is not a valid proxy header. Trusted proxy headers must be \"forwarded\" or start with \"x-forwarded-\".`,\n      );\n    }\n    normalizedTrustedProxyHeaders.add(lowerHeader);\n  }\n\n  return normalizedTrustedProxyHeaders;\n}\n\n/**\n * Parses the standard `Forwarded` header (RFC 7239).\n * It extracts the parameters from the first (leftmost) element in the header.\n *\n * @param headerValue - The value of the `Forwarded` header.\n * @returns A record of lowercase parameter names to their values.\n */\nexport function parseForwardedHeader(\n  headerValue: string | null | undefined,\n): Record<string, string> {\n  if (!headerValue) {\n    return {};\n  }\n\n  const params: Record<string, string> = {};\n  let inQuotes = false;\n  let escaped = false;\n  let currentKey = '';\n  let currentValue = '';\n  let isParsingValue = false;\n  let isKeyEnded = false;\n  let isParsingValueEnded = false;\n\n  for (const char of headerValue) {\n    if (escaped) {\n      escaped = false;\n      if (isParsingValue) {\n        currentValue += char;\n      } else {\n        currentKey += char;\n      }\n      continue;\n    }\n\n    if (char === '\\\\') {\n      if (inQuotes) {\n        escaped = true;\n      } else if (isParsingValue) {\n        currentValue += char;\n      } else {\n        currentKey += char;\n      }\n      continue;\n    }\n\n    if (char === '\"') {\n      inQuotes = !inQuotes;\n      continue;\n    }\n\n    if (inQuotes) {\n      if (isParsingValue) {\n        currentValue += char;\n      } else {\n        currentKey += char;\n      }\n      continue;\n    }\n\n    if (char === ',') {\n      addParam(currentKey, currentValue, isParsingValue, params);\n      break;\n    }\n\n    if (char === ';') {\n      addParam(currentKey, currentValue, isParsingValue, params);\n      currentKey = '';\n      currentValue = '';\n      isParsingValue = false;\n      isKeyEnded = false;\n      isParsingValueEnded = false;\n      continue;\n    }\n\n    if (char === '=') {\n      if (!isParsingValue) {\n        isParsingValue = true;\n      } else {\n        currentValue += char;\n      }\n      continue;\n    }\n\n    if (char === ' ' || char === '\\t') {\n      if (isParsingValue) {\n        if (currentValue.length > 0) {\n          isParsingValueEnded = true;\n        }\n      } else if (currentKey.length > 0) {\n        isKeyEnded = true;\n      }\n      continue;\n    }\n\n    if (isParsingValue) {\n      if (!isParsingValueEnded) {\n        currentValue += char;\n      }\n    } else if (isKeyEnded) {\n      currentKey = char;\n      isKeyEnded = false;\n    } else {\n      currentKey += char;\n    }\n  }\n\n  if (currentKey || currentValue || isParsingValue) {\n    addParam(currentKey, currentValue, isParsingValue, params);\n  }\n\n  return params;\n}\n\n/**\n * Helper function to add a parameter to the params object.\n * @param key - The key to add.\n * @param value - The value to add.\n * @param hasValue - Whether the parameter has a value.\n * @param params - The params object to add the parameter to.\n */\nfunction addParam(\n  key: string,\n  value: string,\n  hasValue: boolean,\n  params: Record<string, string>,\n): void {\n  if (!hasValue) {\n    return;\n  }\n\n  const trimmedKey = key.trim().toLowerCase();\n  if (trimmedKey) {\n    params[trimmedKey] = value;\n  }\n}\n"],"names":[],"mappings":"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"}