@ai-sdk/provider-utils 3.0.21 → 3.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @ai-sdk/provider-utils
2
2
 
3
+ ## 3.0.22
4
+
5
+ ### Patch Changes
6
+
7
+ - 6a2f01b: Add URL validation to `download` to prevent blind SSRF attacks. Private/internal IP addresses, localhost, and non-HTTP protocols are now rejected before fetching.
8
+ - 17d64e3: fix(provider-utils): prevent unicode escape bypass in secureJsonParse
9
+
3
10
  ## 3.0.21
4
11
 
5
12
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -872,6 +872,15 @@ declare function convertBase64ToUint8Array(base64String: string): Uint8Array<Arr
872
872
  declare function convertUint8ArrayToBase64(array: Uint8Array): string;
873
873
  declare function convertToBase64(value: string | Uint8Array): string;
874
874
 
875
+ /**
876
+ * Validates that a URL is safe to download from, blocking private/internal addresses
877
+ * to prevent SSRF attacks.
878
+ *
879
+ * @param url - The URL string to validate.
880
+ * @throws DownloadError if the URL is unsafe.
881
+ */
882
+ declare function validateDownloadUrl(url: string): void;
883
+
875
884
  /**
876
885
  * Validates the types of an unknown object using a schema and
877
886
  * return a strongly-typed object.
@@ -1004,4 +1013,4 @@ interface ToolResult<NAME extends string, INPUT, OUTPUT> {
1004
1013
  dynamic?: boolean;
1005
1014
  }
1006
1015
 
1007
- export { type AssistantContent, type AssistantModelMessage, DEFAULT_MAX_DOWNLOAD_SIZE, type DataContent, DelayedPromise, DownloadError, type FetchFunction, type FilePart, type FlexibleSchema, type FlexibleValidator, type IdGenerator, type ImagePart, type InferSchema, type InferToolInput, type InferToolOutput, type InferValidator, type LazySchema, type LazyValidator, type ModelMessage, type ParseResult, type ProviderDefinedToolFactory, type ProviderDefinedToolFactoryWithOutputSchema, type ProviderOptions, type ReasoningPart, type Resolvable, type ResponseHandler, type Schema, type SystemModelMessage, type TextPart, type Tool, type ToolCall, type ToolCallOptions, type ToolCallPart, type ToolContent, type ToolExecuteFunction, type ToolModelMessage, type ToolResult, type ToolResultPart, type UserContent, type UserModelMessage, VERSION, type ValidationResult, type Validator, asSchema, asValidator, combineHeaders, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertToBase64, convertUint8ArrayToBase64, createBinaryResponseHandler, createEventSourceResponseHandler, createIdGenerator, createJsonErrorResponseHandler, createJsonResponseHandler, createJsonStreamResponseHandler, createProviderDefinedToolFactory, createProviderDefinedToolFactoryWithOutputSchema, createStatusCodeErrorResponseHandler, delay, dynamicTool, executeTool, extractResponseHeaders, generateId, getErrorMessage, getFromApi, getRuntimeEnvironmentUserAgent, injectJsonInstructionIntoMessages, isAbortError, isParsableJson, isUrlSupported, isValidator, jsonSchema, lazySchema, lazyValidator, loadApiKey, loadOptionalSetting, loadSetting, mediaTypeToExtension, normalizeHeaders, parseJSON, parseJsonEventStream, parseProviderOptions, postFormDataToApi, postJsonToApi, postToApi, readResponseWithSizeLimit, removeUndefinedEntries, resolve, safeParseJSON, safeValidateTypes, standardSchemaValidator, tool, validateTypes, validator, withUserAgentSuffix, withoutTrailingSlash, zodSchema };
1016
+ export { type AssistantContent, type AssistantModelMessage, DEFAULT_MAX_DOWNLOAD_SIZE, type DataContent, DelayedPromise, DownloadError, type FetchFunction, type FilePart, type FlexibleSchema, type FlexibleValidator, type IdGenerator, type ImagePart, type InferSchema, type InferToolInput, type InferToolOutput, type InferValidator, type LazySchema, type LazyValidator, type ModelMessage, type ParseResult, type ProviderDefinedToolFactory, type ProviderDefinedToolFactoryWithOutputSchema, type ProviderOptions, type ReasoningPart, type Resolvable, type ResponseHandler, type Schema, type SystemModelMessage, type TextPart, type Tool, type ToolCall, type ToolCallOptions, type ToolCallPart, type ToolContent, type ToolExecuteFunction, type ToolModelMessage, type ToolResult, type ToolResultPart, type UserContent, type UserModelMessage, VERSION, type ValidationResult, type Validator, asSchema, asValidator, combineHeaders, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertToBase64, convertUint8ArrayToBase64, createBinaryResponseHandler, createEventSourceResponseHandler, createIdGenerator, createJsonErrorResponseHandler, createJsonResponseHandler, createJsonStreamResponseHandler, createProviderDefinedToolFactory, createProviderDefinedToolFactoryWithOutputSchema, createStatusCodeErrorResponseHandler, delay, dynamicTool, executeTool, extractResponseHeaders, generateId, getErrorMessage, getFromApi, getRuntimeEnvironmentUserAgent, injectJsonInstructionIntoMessages, isAbortError, isParsableJson, isUrlSupported, isValidator, jsonSchema, lazySchema, lazyValidator, loadApiKey, loadOptionalSetting, loadSetting, mediaTypeToExtension, normalizeHeaders, parseJSON, parseJsonEventStream, parseProviderOptions, postFormDataToApi, postJsonToApi, postToApi, readResponseWithSizeLimit, removeUndefinedEntries, resolve, safeParseJSON, safeValidateTypes, standardSchemaValidator, tool, validateDownloadUrl, validateTypes, validator, withUserAgentSuffix, withoutTrailingSlash, zodSchema };
package/dist/index.d.ts CHANGED
@@ -872,6 +872,15 @@ declare function convertBase64ToUint8Array(base64String: string): Uint8Array<Arr
872
872
  declare function convertUint8ArrayToBase64(array: Uint8Array): string;
873
873
  declare function convertToBase64(value: string | Uint8Array): string;
874
874
 
875
+ /**
876
+ * Validates that a URL is safe to download from, blocking private/internal addresses
877
+ * to prevent SSRF attacks.
878
+ *
879
+ * @param url - The URL string to validate.
880
+ * @throws DownloadError if the URL is unsafe.
881
+ */
882
+ declare function validateDownloadUrl(url: string): void;
883
+
875
884
  /**
876
885
  * Validates the types of an unknown object using a schema and
877
886
  * return a strongly-typed object.
@@ -1004,4 +1013,4 @@ interface ToolResult<NAME extends string, INPUT, OUTPUT> {
1004
1013
  dynamic?: boolean;
1005
1014
  }
1006
1015
 
1007
- export { type AssistantContent, type AssistantModelMessage, DEFAULT_MAX_DOWNLOAD_SIZE, type DataContent, DelayedPromise, DownloadError, type FetchFunction, type FilePart, type FlexibleSchema, type FlexibleValidator, type IdGenerator, type ImagePart, type InferSchema, type InferToolInput, type InferToolOutput, type InferValidator, type LazySchema, type LazyValidator, type ModelMessage, type ParseResult, type ProviderDefinedToolFactory, type ProviderDefinedToolFactoryWithOutputSchema, type ProviderOptions, type ReasoningPart, type Resolvable, type ResponseHandler, type Schema, type SystemModelMessage, type TextPart, type Tool, type ToolCall, type ToolCallOptions, type ToolCallPart, type ToolContent, type ToolExecuteFunction, type ToolModelMessage, type ToolResult, type ToolResultPart, type UserContent, type UserModelMessage, VERSION, type ValidationResult, type Validator, asSchema, asValidator, combineHeaders, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertToBase64, convertUint8ArrayToBase64, createBinaryResponseHandler, createEventSourceResponseHandler, createIdGenerator, createJsonErrorResponseHandler, createJsonResponseHandler, createJsonStreamResponseHandler, createProviderDefinedToolFactory, createProviderDefinedToolFactoryWithOutputSchema, createStatusCodeErrorResponseHandler, delay, dynamicTool, executeTool, extractResponseHeaders, generateId, getErrorMessage, getFromApi, getRuntimeEnvironmentUserAgent, injectJsonInstructionIntoMessages, isAbortError, isParsableJson, isUrlSupported, isValidator, jsonSchema, lazySchema, lazyValidator, loadApiKey, loadOptionalSetting, loadSetting, mediaTypeToExtension, normalizeHeaders, parseJSON, parseJsonEventStream, parseProviderOptions, postFormDataToApi, postJsonToApi, postToApi, readResponseWithSizeLimit, removeUndefinedEntries, resolve, safeParseJSON, safeValidateTypes, standardSchemaValidator, tool, validateTypes, validator, withUserAgentSuffix, withoutTrailingSlash, zodSchema };
1016
+ export { type AssistantContent, type AssistantModelMessage, DEFAULT_MAX_DOWNLOAD_SIZE, type DataContent, DelayedPromise, DownloadError, type FetchFunction, type FilePart, type FlexibleSchema, type FlexibleValidator, type IdGenerator, type ImagePart, type InferSchema, type InferToolInput, type InferToolOutput, type InferValidator, type LazySchema, type LazyValidator, type ModelMessage, type ParseResult, type ProviderDefinedToolFactory, type ProviderDefinedToolFactoryWithOutputSchema, type ProviderOptions, type ReasoningPart, type Resolvable, type ResponseHandler, type Schema, type SystemModelMessage, type TextPart, type Tool, type ToolCall, type ToolCallOptions, type ToolCallPart, type ToolContent, type ToolExecuteFunction, type ToolModelMessage, type ToolResult, type ToolResultPart, type UserContent, type UserModelMessage, VERSION, type ValidationResult, type Validator, asSchema, asValidator, combineHeaders, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertToBase64, convertUint8ArrayToBase64, createBinaryResponseHandler, createEventSourceResponseHandler, createIdGenerator, createJsonErrorResponseHandler, createJsonResponseHandler, createJsonStreamResponseHandler, createProviderDefinedToolFactory, createProviderDefinedToolFactoryWithOutputSchema, createStatusCodeErrorResponseHandler, delay, dynamicTool, executeTool, extractResponseHeaders, generateId, getErrorMessage, getFromApi, getRuntimeEnvironmentUserAgent, injectJsonInstructionIntoMessages, isAbortError, isParsableJson, isUrlSupported, isValidator, jsonSchema, lazySchema, lazyValidator, loadApiKey, loadOptionalSetting, loadSetting, mediaTypeToExtension, normalizeHeaders, parseJSON, parseJsonEventStream, parseProviderOptions, postFormDataToApi, postJsonToApi, postToApi, readResponseWithSizeLimit, removeUndefinedEntries, resolve, safeParseJSON, safeValidateTypes, standardSchemaValidator, tool, validateDownloadUrl, validateTypes, validator, withUserAgentSuffix, withoutTrailingSlash, zodSchema };
package/dist/index.js CHANGED
@@ -86,6 +86,7 @@ __export(src_exports, {
86
86
  safeValidateTypes: () => safeValidateTypes,
87
87
  standardSchemaValidator: () => standardSchemaValidator,
88
88
  tool: () => tool,
89
+ validateDownloadUrl: () => validateDownloadUrl,
89
90
  validateTypes: () => validateTypes,
90
91
  validator: () => validator,
91
92
  withUserAgentSuffix: () => withUserAgentSuffix,
@@ -439,7 +440,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
439
440
  }
440
441
 
441
442
  // src/version.ts
442
- var VERSION = true ? "3.0.21" : "0.0.0-test";
443
+ var VERSION = true ? "3.0.22" : "0.0.0-test";
443
444
 
444
445
  // src/get-from-api.ts
445
446
  var getOriginalFetch = () => globalThis.fetch;
@@ -669,8 +670,8 @@ function mediaTypeToExtension(mediaType) {
669
670
  var import_provider9 = require("@ai-sdk/provider");
670
671
 
671
672
  // src/secure-json-parse.ts
672
- var suspectProtoRx = /"__proto__"\s*:/;
673
- var suspectConstructorRx = /"constructor"\s*:/;
673
+ var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
674
+ var suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
674
675
  function _parse(text) {
675
676
  const obj = JSON.parse(text);
676
677
  if (obj === null || typeof obj !== "object") {
@@ -690,7 +691,7 @@ function filter(obj) {
690
691
  if (Object.prototype.hasOwnProperty.call(node, "__proto__")) {
691
692
  throw new SyntaxError("Object contains forbidden prototype property");
692
693
  }
693
- if (Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
694
+ if (Object.prototype.hasOwnProperty.call(node, "constructor") && node.constructor !== null && typeof node.constructor === "object" && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
694
695
  throw new SyntaxError("Object contains forbidden prototype property");
695
696
  }
696
697
  for (const key in node) {
@@ -2555,6 +2556,102 @@ function convertToBase64(value) {
2555
2556
  return value instanceof Uint8Array ? convertUint8ArrayToBase64(value) : value;
2556
2557
  }
2557
2558
 
2559
+ // src/validate-download-url.ts
2560
+ function validateDownloadUrl(url) {
2561
+ let parsed;
2562
+ try {
2563
+ parsed = new URL(url);
2564
+ } catch (e) {
2565
+ throw new DownloadError({
2566
+ url,
2567
+ message: `Invalid URL: ${url}`
2568
+ });
2569
+ }
2570
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
2571
+ throw new DownloadError({
2572
+ url,
2573
+ message: `URL scheme must be http or https, got ${parsed.protocol}`
2574
+ });
2575
+ }
2576
+ const hostname = parsed.hostname;
2577
+ if (!hostname) {
2578
+ throw new DownloadError({
2579
+ url,
2580
+ message: `URL must have a hostname`
2581
+ });
2582
+ }
2583
+ if (hostname === "localhost" || hostname.endsWith(".local") || hostname.endsWith(".localhost")) {
2584
+ throw new DownloadError({
2585
+ url,
2586
+ message: `URL with hostname ${hostname} is not allowed`
2587
+ });
2588
+ }
2589
+ if (hostname.startsWith("[") && hostname.endsWith("]")) {
2590
+ const ipv6 = hostname.slice(1, -1);
2591
+ if (isPrivateIPv6(ipv6)) {
2592
+ throw new DownloadError({
2593
+ url,
2594
+ message: `URL with IPv6 address ${hostname} is not allowed`
2595
+ });
2596
+ }
2597
+ return;
2598
+ }
2599
+ if (isIPv4(hostname)) {
2600
+ if (isPrivateIPv4(hostname)) {
2601
+ throw new DownloadError({
2602
+ url,
2603
+ message: `URL with IP address ${hostname} is not allowed`
2604
+ });
2605
+ }
2606
+ return;
2607
+ }
2608
+ }
2609
+ function isIPv4(hostname) {
2610
+ const parts = hostname.split(".");
2611
+ if (parts.length !== 4) return false;
2612
+ return parts.every((part) => {
2613
+ const num = Number(part);
2614
+ return Number.isInteger(num) && num >= 0 && num <= 255 && String(num) === part;
2615
+ });
2616
+ }
2617
+ function isPrivateIPv4(ip) {
2618
+ const parts = ip.split(".").map(Number);
2619
+ const [a, b] = parts;
2620
+ if (a === 0) return true;
2621
+ if (a === 10) return true;
2622
+ if (a === 127) return true;
2623
+ if (a === 169 && b === 254) return true;
2624
+ if (a === 172 && b >= 16 && b <= 31) return true;
2625
+ if (a === 192 && b === 168) return true;
2626
+ return false;
2627
+ }
2628
+ function isPrivateIPv6(ip) {
2629
+ const normalized = ip.toLowerCase();
2630
+ if (normalized === "::1") return true;
2631
+ if (normalized === "::") return true;
2632
+ if (normalized.startsWith("::ffff:")) {
2633
+ const mappedPart = normalized.slice(7);
2634
+ if (isIPv4(mappedPart)) {
2635
+ return isPrivateIPv4(mappedPart);
2636
+ }
2637
+ const hexParts = mappedPart.split(":");
2638
+ if (hexParts.length === 2) {
2639
+ const high = parseInt(hexParts[0], 16);
2640
+ const low = parseInt(hexParts[1], 16);
2641
+ if (!isNaN(high) && !isNaN(low)) {
2642
+ const a = high >> 8 & 255;
2643
+ const b = high & 255;
2644
+ const c = low >> 8 & 255;
2645
+ const d = low & 255;
2646
+ return isPrivateIPv4(`${a}.${b}.${c}.${d}`);
2647
+ }
2648
+ }
2649
+ }
2650
+ if (normalized.startsWith("fc") || normalized.startsWith("fd")) return true;
2651
+ if (normalized.startsWith("fe80")) return true;
2652
+ return false;
2653
+ }
2654
+
2558
2655
  // src/without-trailing-slash.ts
2559
2656
  function withoutTrailingSlash(url) {
2560
2657
  return url == null ? void 0 : url.replace(/\/$/, "");
@@ -2644,6 +2741,7 @@ var import_stream2 = require("eventsource-parser/stream");
2644
2741
  safeValidateTypes,
2645
2742
  standardSchemaValidator,
2646
2743
  tool,
2744
+ validateDownloadUrl,
2647
2745
  validateTypes,
2648
2746
  validator,
2649
2747
  withUserAgentSuffix,