Stored XSS: $row['country'] inserted into HTML without escaping in index.php #2

Open
opened 2026-05-14 21:14:35 +02:00 by Claude · 0 comments

Problem

index.php embeds the stored country value directly into an HTML string passed to add_footer() with no escaping:

add_footer("<small class=\"grey from\">Message uploaded from " . $row['country'] . "</small><br>");

The country value originates from the external ipapi.co API response (fetched in get_country() in message.php) and is stored verbatim in the database.

Location

index.php, line 33
message.php, lines 22–38 (get_country() function)

Risk

If the ipapi.co service is compromised, returns unexpected data, or an attacker somehow influences the stored country value, HTML/JavaScript in that value is rendered directly in every visitor's browser for that message. For example, a response like </small><script>alert(1)</script> would execute as script. This is a stored XSS via a third-party supply chain.

Suggested fix direction

Escape the value at render time: htmlspecialchars($row['country'], ENT_QUOTES, 'UTF-8'). Never trust data from external APIs when embedding into HTML.

Severity

moderate

Found by

Automated audit by Claude Code

## Problem `index.php` embeds the stored `country` value directly into an HTML string passed to `add_footer()` with no escaping: ```php add_footer("<small class=\"grey from\">Message uploaded from " . $row['country'] . "</small><br>"); ``` The `country` value originates from the external `ipapi.co` API response (fetched in `get_country()` in `message.php`) and is stored verbatim in the database. ## Location `index.php`, line 33 `message.php`, lines 22–38 (`get_country()` function) ## Risk If the `ipapi.co` service is compromised, returns unexpected data, or an attacker somehow influences the stored country value, HTML/JavaScript in that value is rendered directly in every visitor's browser for that message. For example, a response like `</small><script>alert(1)</script>` would execute as script. This is a stored XSS via a third-party supply chain. ## Suggested fix direction Escape the value at render time: `htmlspecialchars($row['country'], ENT_QUOTES, 'UTF-8')`. Never trust data from external APIs when embedding into HTML. ## Severity moderate ## Found by Automated audit by Claude Code
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bc1bb/OpenLongr#2
No description provided.