GHSA-89v5-38xr-9m4j Postiz has Multiple SSRF Vectors - Webhooks, RSS Feed, URL Loader

Not scored Published

Attackers can exploit Server-Side Request Forgery in Postiz to access internal network resources or cloud metadata via unvalidated URL inputs in webhooks and feed loaders.

Exploited in the wild
Not known
Login needed
Any signed-in user
Attackable
Over the internet
Victim action needed
Not needed
Fix
None listed

What is GHSA-89v5-38xr-9m4j?

GHSA-89v5-38xr-9m4j is a server-side request forgery vulnerability in postiz, published on 27 Mar 2026. Any signed-in user can exploit it over the network, with no action from the victim.

Official description

Summary

Postiz has multiple SSRF vulnerabilities where user-provided URLs are fetched server-side without any IP validation or SSRF protection.

Vulnerable Code

1. Webhook Send Endpoint (Most Critical)

apps/backend/src/api/routes/webhooks.controller.ts lines 58-70:

async sendWebhook(@Body() body: any, @Query('url') url: string) {
  try {
    await fetch(url, {  // No URL validation
      method: 'POST',
      body: JSON.stringify(body),
      headers: { 'Content-Type': 'application/json' },
    });
  } catch (err) { }
  return { send: true };
}

Accepts arbitrary URL via query parameter and fetches directly.

2. Stored Webhook Delivery

apps/orchestrator/src/activities/post.activity.ts lines 256-281:

async sendWebhooks(postId: string, orgId: string, integrationId: string) {
  const webhooks = await this._webhookService.getWebhooks(orgId);
  return Promise.all(
    webhooks.map(async (webhook) => {
      await fetch(webhook.url, {  // Stored URL, no validation
        method: 'POST',
        body: JSON.stringify(post),
      });
    })
  );
}

3. RSS/XML Feed Parser

libraries/nestjs-libraries/src/database/prisma/autopost/autopost.service.ts line 135:

async loadXML(url: string) {
  const { items } = await parser.parseURL(url);  // No URL validation
}

4. HTML Content Loader

libraries/nestjs-libraries/src/database/prisma/autopost/autopost.service.ts line 185:

async loadUrl(url: string) {
  const loadDom = new JSDOM(await (await fetch(url)).text());  // No validation
}

Missing Protections

  • No request-filtering-agent or SSRF library
  • No private IP range filtering
  • No cloud metadata endpoint blocking
  • No DNS rebinding protection
  • URL validation only via @IsUrl() decorator (format only, no IP check)

Attack Scenarios

  1. POST /webhooks/send?url=http://169.254.169.254/latest/meta-data/ → AWS metadata theft
  2. POST /autopost/send?url=http://127.0.0.1:6379 → Internal Redis access
  3. Create webhook with http://10.0.0.1:8080/admin → Internal service access on post publish

Impact

  • Cloud metadata theft: AWS/GCP/Azure credentials
  • Internal network scanning: Full access to private IP ranges
  • Multiple entry points: Webhooks, RSS feeds, URL loader all vulnerable

Which versions are affected by GHSA-89v5-38xr-9m4j?

2 open source packages ship an affected version, including postiz.

PackageAffectedFixed in
postiz npmAll versions to 2.0.12None
postiz npmAll versions to 2.0.12None

How do I fix GHSA-89v5-38xr-9m4j?

No fix has been published for GHSA-89v5-38xr-9m4j yet. Limit exposure of the affected software until one is available.

Upgrade, and send outbound requests through an allow-list that blocks internal addresses. More about Server-side request forgery.

Is GHSA-89v5-38xr-9m4j being exploited?

There is no known exploitation of GHSA-89v5-38xr-9m4j in the wild and no public exploit code.

Sources

Is GHSA-89v5-38xr-9m4j in your software?

Upload an SBOM and sbomify checks it against every vulnerability here, every day.

Check your SBOMs for free