Security Advisories์ถ์ฒ: GitHub Security Advisories์กฐํ์ 1
[@pdfme/common] PDFME has SSRF via Unvalidated URL Fetch in `getB64BasePdf` When `basePdf` Is Attacker-Controlled
By GitHub2026๋
3์ 21์ผ
**[@pdfme/common] PDFME has SSRF via Unvalidated URL Fetch in `getB64BasePdf` When `basePdf` Is Attacker-Controlled**
Summary The getB64BasePdf function in @pdfme/common fetches arbitrary URLs via fetch() without any validation when basePdf is a non-data-URI string and window is defined. An attacker who can control the basePdf field of a template (e.g., through a web application that accepts user-supplied templates) can force the server or client to make requests to arbitrary internal or external endpoints, enabling Server-Side Request Forgery (SSRF) in SSR contexts or blind request forgery in browser contexts. Details The vulnerability exists in packages/common/src/helper.ts:130-141. When getB64BasePdf receives a string that does not start with data:application/pdf;, and window is defined, it passes the string directly to fetch(): // packages/common/src/helper.ts:130-141 export const getB64BasePdf = async ( customPdf: ArrayBuffer | Uint8Array | string, ): Promise<string> => { if ( typeof customPdf === 'string' && !customPdf.startsWith('data:application/pdf;') && typeof window !== 'undefined' ) { const response = await fetch(customPdf); // <-- No URL validation const blob = await response.blob(); return blob2Base64Pdf(blob); } // ... }; The Zod schema for basePdf in packages/common/src/schema.ts:133-135 accepts any string: export const CustomPdf = z.union([z.string(), ArrayBufferSchema, Uint8ArraySchema]); export const BasePdf = z.union([CustomPdf, BlankPdf]); The checkGenerateProps function at packages/common/src/helper.ts:279 only validates the Zod schema shape, which permits any string value...
---
**[devsupporter ํด์ค]**
์ด ๊ธฐ์ฌ๋ GitHub Security Advisories์์ ์ ๊ณตํ๋ ์ต์ ๊ฐ๋ฐ ๋ํฅ์ ๋๋ค. ๊ด๋ จ ๋๊ตฌ๋ ๊ธฐ์ ์ ๋ํด ๋ ์์๋ณด์๋ ค๋ฉด ์๋ณธ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์ธ์.
Summary The getB64BasePdf function in @pdfme/common fetches arbitrary URLs via fetch() without any validation when basePdf is a non-data-URI string and window is defined. An attacker who can control the basePdf field of a template (e.g., through a web application that accepts user-supplied templates) can force the server or client to make requests to arbitrary internal or external endpoints, enabling Server-Side Request Forgery (SSRF) in SSR contexts or blind request forgery in browser contexts. Details The vulnerability exists in packages/common/src/helper.ts:130-141. When getB64BasePdf receives a string that does not start with data:application/pdf;, and window is defined, it passes the string directly to fetch(): // packages/common/src/helper.ts:130-141 export const getB64BasePdf = async ( customPdf: ArrayBuffer | Uint8Array | string, ): Promise<string> => { if ( typeof customPdf === 'string' && !customPdf.startsWith('data:application/pdf;') && typeof window !== 'undefined' ) { const response = await fetch(customPdf); // <-- No URL validation const blob = await response.blob(); return blob2Base64Pdf(blob); } // ... }; The Zod schema for basePdf in packages/common/src/schema.ts:133-135 accepts any string: export const CustomPdf = z.union([z.string(), ArrayBufferSchema, Uint8ArraySchema]); export const BasePdf = z.union([CustomPdf, BlankPdf]); The checkGenerateProps function at packages/common/src/helper.ts:279 only validates the Zod schema shape, which permits any string value...
---
**[devsupporter ํด์ค]**
์ด ๊ธฐ์ฌ๋ GitHub Security Advisories์์ ์ ๊ณตํ๋ ์ต์ ๊ฐ๋ฐ ๋ํฅ์ ๋๋ค. ๊ด๋ จ ๋๊ตฌ๋ ๊ธฐ์ ์ ๋ํด ๋ ์์๋ณด์๋ ค๋ฉด ์๋ณธ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์ธ์.
![[@pdfme/common] PDFME has SSRF via Unvalidated URL Fetch in `getB64BasePdf` When `basePdf` Is Attacker-Controlled](/assets/images/github_com_1774224308736.png)