Skip to content

Commit 0469aed

Browse files
vercel-ai-sdk[bot]fahe1em1gr2mclaude
authored
Backport: fix: allow inline data URLs in download validation (#13624)
This is an automated backport of #13376 to the release-v6.0 branch. FYI @fahe1em1 --------- Co-authored-by: fahe1em1 <131003503+fahe1em1@users.noreply.github.com> Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 15bfbd2 commit 0469aed

File tree

4 files changed

+28
-8
lines changed

4 files changed

+28
-8
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@ai-sdk/provider-utils': patch
3+
'ai': patch
4+
---
5+
6+
fix: allow inline data URLs in download validation

packages/ai/src/util/download/download.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,15 @@ describe('download', () => {
137137
);
138138
});
139139

140+
it('should allow inline data URLs', async () => {
141+
const result = await download({
142+
url: new URL('data:text/plain;base64,aGVsbG8='),
143+
});
144+
145+
expect(result.data).toEqual(new TextEncoder().encode('hello'));
146+
expect(result.mediaType).toBe('text/plain');
147+
});
148+
140149
it('should throw DownloadError when response is not ok', async () => {
141150
globalThis.fetch = vi.fn().mockResolvedValue({
142151
ok: false,

packages/provider-utils/src/validate-download-url.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ describe('validateDownloadUrl', () => {
2727
validateDownloadUrl('https://example.com:8080/file'),
2828
).not.toThrow();
2929
});
30+
31+
it('should allow data URLs', () => {
32+
expect(() =>
33+
validateDownloadUrl('data:text/plain;base64,aGVsbG8='),
34+
).not.toThrow();
35+
});
3036
});
3137

3238
describe('blocked protocols', () => {
@@ -47,12 +53,6 @@ describe('validateDownloadUrl', () => {
4753
DownloadError,
4854
);
4955
});
50-
51-
it('should block data: URLs', () => {
52-
expect(() => validateDownloadUrl('data:text/plain,hello')).toThrow(
53-
DownloadError,
54-
);
55-
});
5656
});
5757

5858
describe('malformed URLs', () => {

packages/provider-utils/src/validate-download-url.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@ export function validateDownloadUrl(url: string): void {
1818
});
1919
}
2020

21-
// Only allow http and https protocols
21+
// data: URLs are inline content, so they do not trigger a network fetch or SSRF risk.
22+
if (parsed.protocol === 'data:') {
23+
return;
24+
}
25+
26+
// Only allow http and https network protocols
2227
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
2328
throw new DownloadError({
2429
url,
25-
message: `URL scheme must be http or https, got ${parsed.protocol}`,
30+
message: `URL scheme must be http, https, or data, got ${parsed.protocol}`,
2631
});
2732
}
2833

0 commit comments

Comments
 (0)