{"id":"GHSA-89v5-38xr-9m4j","aliases":[],"url":"https://o3.security/vulnerability/GHSA-89v5-38xr-9m4j","summary":"Postiz has Multiple SSRF Vectors - Webhooks, RSS Feed, URL Loader","details":"## Summary\n\nPostiz has multiple SSRF vulnerabilities where user-provided URLs are fetched server-side without any IP validation or SSRF protection.\n\n## Vulnerable Code\n\n### 1. Webhook Send Endpoint (Most Critical)\n\n**`apps/backend/src/api/routes/webhooks.controller.ts` lines 58-70:**\n```typescript\nasync sendWebhook(@Body() body: any, @Query('url') url: string) {\n  try {\n    await fetch(url, {  // No URL validation\n      method: 'POST',\n      body: JSON.stringify(body),\n      headers: { 'Content-Type': 'application/json' },\n    });\n  } catch (err) { }\n  return { send: true };\n}\n```\n\nAccepts arbitrary URL via query parameter and fetches directly.\n\n### 2. Stored Webhook Delivery\n\n**`apps/orchestrator/src/activities/post.activity.ts` lines 256-281:**\n```typescript\nasync sendWebhooks(postId: string, orgId: string, integrationId: string) {\n  const webhooks = await this._webhookService.getWebhooks(orgId);\n  return Promise.all(\n    webhooks.map(async (webhook) => {\n      await fetch(webhook.url, {  // Stored URL, no validation\n        method: 'POST',\n        body: JSON.stringify(post),\n      });\n    })\n  );\n}\n```\n\n### 3. RSS/XML Feed Parser\n\n**`libraries/nestjs-libraries/src/database/prisma/autopost/autopost.service.ts` line 135:**\n```typescript\nasync loadXML(url: string) {\n  const { items } = await parser.parseURL(url);  // No URL validation\n}\n```\n\n### 4. HTML Content Loader\n\n**`libraries/nestjs-libraries/src/database/prisma/autopost/autopost.service.ts` line 185:**\n```typescript\nasync loadUrl(url: string) {\n  const loadDom = new JSDOM(await (await fetch(url)).text());  // No validation\n}\n```\n\n## Missing Protections\n\n- No `request-filtering-agent` or SSRF library\n- No private IP range filtering\n- No cloud metadata endpoint blocking\n- No DNS rebinding protection\n- URL validation only via `@IsUrl()` decorator (format only, no IP check)\n\n## Attack Scenarios\n\n1. `POST /webhooks/send?url=http://169.254.169.254/latest/meta-data/` → AWS metadata theft\n2. `POST /autopost/send?url=http://127.0.0.1:6379` → Internal Redis access\n3. Create webhook with `http://10.0.0.1:8080/admin` → Internal service access on post publish\n\n## Impact\n\n- **Cloud metadata theft**: AWS/GCP/Azure credentials\n- **Internal network scanning**: Full access to private IP ranges\n- **Multiple entry points**: Webhooks, RSS feeds, URL loader all vulnerable","published":"2026-03-27T15:47:57Z","modified":"2026-03-27T16:03:30.102739Z","cvss":null,"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"postiz","fixedVersion":null}],"fix":{"url":"https://github.com/gitroomhq/postiz-app/commit/0ad89ccd26b1c387c4f3f3544b18c20d33586466","label":"gitroomhq/postiz-app@0ad89cc"},"references":[{"type":"WEB","url":"https://github.com/gitroomhq/postiz-app/security/advisories/GHSA-89v5-38xr-9m4j"},{"type":"WEB","url":"https://github.com/gitroomhq/postiz-app/commit/0ad89ccd26b1c387c4f3f3544b18c20d33586466"},{"type":"WEB","url":"https://github.com/gitroomhq/postiz-app/commit/be5d871896e97cb1f5a2c9241f156b6a1e1debe8"},{"type":"PACKAGE","url":"https://github.com/gitroomhq/postiz-app"},{"type":"WEB","url":"https://github.com/gitroomhq/postiz-app/releases/tag/v2.21.2"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-03-27T16:03:30.102739Z"}}