Submit #275433: Sourcecodester QR Code Login System 1.0 Stored Cross Site Scripting (XSS)info

TitleSourcecodester QR Code Login System 1.0 Stored Cross Site Scripting (XSS)
DescriptionNOTE FOR REVIEWER: Source code located at https://www.sourcecodester.com/php/17145/qr-code-login-system-using-php-and-mysql-source-code.html QR Code Login System 1.0 Stored Cross Site Scripting (XSS) ## Summary Fields take input from the user and store it in a backend SQL database. This data is not sanitized for special HTML characters before being displayed. ## Issue Description Stored cross-site scripting (also known as second-order or persistent XSS) arises when an application receives data from an untrusted source and includes that data within its later HTTP responses in an unsafe way. The entry point for this vulnerability is the registration window of `index.php`. `index.php` takes input from the user, and creates a POST request to the `add-user.php` endpoint. This endpoint takes the input values and submits them to the backend SQL database. Note that the SQL statement is prepared correctly, and is not susceptible to SQL injections. `add-user.php` lines 19-27: ``` $insertStmt = $conn->prepare("INSERT INTO `tbl_user` (`name`, `contact_number`, `email`, `generated_code`) VALUES (:name, :contact_number, :email, :generated_code)"); $insertStmt->bindParam('name', $name, PDO::PARAM_STR); $insertStmt->bindParam('contact_number', $contactNumber, PDO::PARAM_STR); $insertStmt->bindParam('email', $email, PDO::PARAM_STR); $insertStmt->bindParam('generated_code', $generatedCode, PDO::PARAM_STR); $insertStmt->execute(); $conn->commit(); ``` After the user input is store in the SQL database, it is reflected back to the users on `home.php`. This endpoint simply takes data from the SQL database and displays it on the page. There is no sanitization of this data as it comes from the database. This creates opportunities for attackers to launch cross site scripting attacks. Because the attack only requires an attacker to submit malicious data to the server, and the server reflects that data back to the user, this constitutes a stored cross site scripting vulnerability. Data retrieval in `home.php` lines 10-18: ``` $stmt = $conn->prepare("SELECT `name` FROM `tbl_user` WHERE `tbl_user_id` = :user_id"); $stmt->bindParam(':user_id', $user_id); $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetch(); $user_name = $row['name']; } ``` Data reflection in `home.php` line 66: ``` <h1 class="text-center">Welcome <br> <?php echo $user_name; ?>!</h1> ``` ## Affected URL/Area Source: `index.php` Sink: `home.php` ## Risk Rating - Risk: **LOW** - Exploitation Difficulty: **LOW** ## CVSS Justification ### Network - AV The vulnerable component is bound to the network stack. The set of possible attackers extends beyond local attacks, up to and including the entire Internet. ### Low - AC Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success when attacking the vulnerable component. ### None - PR The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files of the the vulnerable system to carry out an attack. ### None - UI The vulnerable system can be exploited without interaction from any user. ### Unchanged - S An exploited vulnerability can only affect resources managed by the same security authority. ### Low - C There is some loss of confidentiality, but the information disclosure does not cause a direct, serious loss to the impacted component. The indirect confidentiality loss of being able to execute JavaScript in the context of user's browsers can lead to loss of sensitive information. ### Low - I Modification of data is possible, but the negative security effects of the modification is limited. ### Low - A Performance is reduced or there are interruptions in resource availability. Specifically, the data is being loaded as javascript ## Steps to reproduce Easy way: 1) Create a user account with malicious username. 2) Take a picture of the QR code after registration. 3) Hold QR code up to camera. Without camera: 1) Create a user account, and proxy the traffic when registering the account. 2) Intercept the 10 character code used to create the user account QR code. 3) Make a POST request to the `login.php` endpoint with the code as the value of param `qr-code` . 4) Manually set the cookie using browser dev tools or preferred cookie editor, and navigate to `home.php`. Command line: 1) Create the malicious user account. ``` curl -i -s -k -X $'POST' \ -H $'Host: localhost' -H $'Content-Length: 100' -H $'Cache-Control: max-age=0' -H $'sec-ch-ua: \" Not A;Brand\";v=\"99\", \"Chromium\";v=\"104\"' -H $'sec-ch-ua-mobile: ?0' -H $'sec-ch-ua-platform: \"Windows\"' -H $'Upgrade-Insecure-Requests: 1' -H $'Origin: http://localhost' -H $'Content-Type: application/x-www-form-urlencoded' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36' -H $'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.9' -H $'Sec-Fetch-Site: same-origin' -H $'Sec-Fetch-Mode: navigate' -H $'Sec-Fetch-User: ?1' -H $'Sec-Fetch-Dest: document' -H $'Referer: http://localhost/qr-code-login-system/qr-code-login-system/' -H $'Accept-Encoding: gzip, deflate' -H $'Accept-Language: en-US,en;q=0.9' -H $'Connection: close' \ -b $'csrftoken=o3x1zVYrCf3vbyXfd0a8xi8ppWs7fi3WlsBalEJS921YSJ9Z5tCm9wPyxMgeolDj; PHPSESSID=6fnrdtk0rkq3m4mva7p3j3em5c' \ --data-binary $'name=malicious_user&contact_number=18001234567&email=bad_guy%40hackers.com&generated_code=hIirsRilB2' \ $'http://localhost/qr-code-login-system/qr-code-login-system/endpoint/add-user.php' ``` Pretty request: ``` POST /qr-code-login-system/qr-code-login-system/endpoint/add-user.php HTTP/1.1 Host: localhost Content-Length: 100 Cache-Control: max-age=0 sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="104" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Upgrade-Insecure-Requests: 1 Origin: http://localhost Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 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.9 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: http://localhost/qr-code-login-system/qr-code-login-system/ Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Cookie: csrftoken=o3x1zVYrCf3vbyXfd0a8xi8ppWs7fi3WlsBalEJS921YSJ9Z5tCm9wPyxMgeolDj; PHPSESSID=6fnrdtk0rkq3m4mva7p3j3em5c Connection: close name=malicious_user&contact_number=18001234567&email=bad_guy%40hackers.com&generated_code=<TAKE_THIS_CODE> ``` 2) Get cookie for valid login ``` curl -i -s -k -X $'POST' \ -H $'Host: localhost' -H $'Content-Length: 18' -H $'Cache-Control: max-age=0' -H $'sec-ch-ua: \" Not A;Brand\";v=\"99\", \"Chromium\";v=\"104\"' -H $'sec-ch-ua-mobile: ?0' -H $'sec-ch-ua-platform: \"Windows\"' -H $'Upgrade-Insecure-Requests: 1' -H $'Origin: http://localhost' -H $'Content-Type: application/x-www-form-urlencoded' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36' -H $'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.9' -H $'Sec-Fetch-Site: same-origin' -H $'Sec-Fetch-Mode: navigate' -H $'Sec-Fetch-User: ?1' -H $'Sec-Fetch-Dest: document' -H $'Referer: http://localhost/qr-code-login-system/qr-code-login-system/' -H $'Accept-Encoding: gzip, deflate' -H $'Accept-Language: en-US,en;q=0.9' -H $'Connection: close' \ -b $'csrftoken=o3x1zVYrCf3vbyXfd0a8xi8ppWs7fi3WlsBalEJS921YSJ9Z5tCm9wPyxMgeolDj' \ --data-binary $'qr-code=<REPLACE_ME>' \ $'http://localhost/qr-code-login-system/qr-code-login-system/endpoint/login.php' ``` Pretty request: ``` POST /qr-code-login-system/qr-code-login-system/endpoint/login.php HTTP/1.1 Host: localhost Content-Length: 18 Cache-Control: max-age=0 sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="104" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Upgrade-Insecure-Requests: 1 Origin: http://localhost Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 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.9 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: http://localhost/qr-code-login-system/qr-code-login-system/ Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Cookie: csrftoken=o3x1zVYrCf3vbyXfd0a8xi8ppWs7fi3WlsBalEJS921YSJ9Z5tCm9wPyxMgeolDj Connection: close qr-code=<REPLACE WITH CODE> ``` 3) Visit the home page ``` curl -i -s -k -X $'POST' \ -H $'Host: localhost' -H $'Content-Length: 18' -H $'Expires: Thu, 19 Nov 1981 08:52:00 GMT' -H $'Cache-Control: max-age=0' -H $'sec-ch-ua: \" Not A;Brand\";v=\"99\", \"Chromium\";v=\"104\"' -H $'sec-ch-ua-mobile: ?0' -H $'sec-ch-ua-platform: \"Windows\"' -H $'Upgrade-Insecure-Requests: 1' -H $'Origin: http://localhost' -H $'Content-Type: application/x-www-form-urlencoded' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36' -H $'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.9' -H $'Sec-Fetch-Site: same-origin' -H $'Sec-Fetch-Mode: navigate' -H $'Sec-Fetch-User: ?1' -H $'Sec-Fetch-Dest: do
Usermikel22 (ID 51822)
Submission30.01.2024 23:31 (4 months ago)
Moderation31.01.2024 13:56 (14 hours later)
StatusAkzeptiert
VulDB Entry252470

Interested in the pricing of exploits?

See the underground prices here!