Sourcecodester Contact Manager App Has Multiple Vulnerabilities

Update

Update 2023/09/10

The vulnerability has been included and approved for public disclosure by MITRE.

CVE Record

NVD

Vuln_Author: WEI(ギカク)

The program is built using the xmapp-php8.2.4 version

Vulnerabilities

  • Stored XSS【CVE-2023-4870】
  • SQL Injection【CVE-2023-4871】【CVE-2023-4872】
  • CSRF【CVE-2023-4868】【CVE-2023-4869】

About the Contact Manager App

Contact Manager web application that enables users to manage their contacts, including contact details and images. The application will cover the basic functionalities of adding, viewing, updating, and deleting contacts.

Developer

Key Features:

  1. Create: Users can add new contacts by providing their details, including a profile image.
  2. Read: Contacts stored in the database can be viewed in a tabular format, displaying their essential information and images.
  3. Update: Users can edit contact information and images to keep the data up-to-date.
  4. Delete: Contacts can be removed from the database when no longer needed.

Stored XSS

This XSS vulnerability exists in index.php

Code Audit

<td id="contactID-<?= $contactID ?>"><?php echo $contactID ?></td>

In the code, we can see that there is an operation to directly output data from the database to HTML. If the data in the database contains malicious JavaScript code, this may lead to XSS attacks.

PoC

First create a contact information

Then modify the contact information to insert the XSS payload into the name field and address field

"><sCrIpT>alert(1)</ScRiPt>

After clicking “Save Changes”, the XSS payload is successfully executed.

Return to the homepage, XSS is triggered again.

Confirmed Stored XSS vulnerability

SQL Injection

Code Audit

In the delete. php and add. php files, user input (such as $contact and $contactName) is directly inserted into the SQL query. This can lead to SQL injection attacks, allowing attackers to manipulate queries, read, modify, or delete data from the database.

<?php
session_start();
include('../conn/conn.php');

if (isset($_GET['contact'])) {
    $contact = $_GET['contact'];

    try {

        $query = "DELETE FROM `tbl_contact` WHERE tbl_contact_id ='$contact'";

        $statement = $conn->prepare($query);
        $query_execute = $statement->execute();

        if ($query_execute) {
            $_SESSION['message'] = "Deleted Successfully";
            header('Location:http://localhost/contact-manager/');
            exit(0);
        } else {
            $_SESSION['message'] = "Not Deleted";
            header('Location:http://localhost/contact-manager/');
            exit(0);
        }
    } catch (PDOException $e) {
        echo $e->getMessage();
    }
}

PoC

Create two contacts for testing.

Use the delete function to delete the contact with ID 13

Use burpsuite for packet capture

According to the result of code auditing, there is an injection point in the contact parameter.

Perform SQL injection testing on the parameters.

/endpoint/delete.php?contact=1%27%20OR%20%271%27%3D%271

This payload causes all contact information to be deleted.

From the figure below, it can be seen that SQL injection malicious code has been successfully executed, and all contacts have been deleted.

SQL injection vulnerability has been confirmed to exist.

CSRF

Code Audit

A CSRF vulnerability exists in add.php and update.php

$contactName = $_POST['contact_name'];
$contactNumber = $_POST['contact_number'];
$contactEmail = $_POST['contact_email'];
$contactAddress = $_POST['contact_address'];

//...more code...

$stmt = $conn->prepare("INSERT INTO `tbl_contact` (`tbl_contact_id`,`contact_image`, `contact_name`, `contact_number`, `contact_email`, `contact_address`) VALUES (NULL, :contactImage, :contactName, :contactNumber, :contactEmail, :contactAddress)");
$stmt->bindParam(':contactImage', $contactImage);
$stmt->bindParam(':contactName', $contactName);
$stmt->bindParam(':contactNumber', $contactNumber);
$stmt->bindParam(':contactEmail', $contactEmail);
$stmt->bindParam(':contactAddress', $contactAddress);
$stmt->execute();

header("location: http://localhost/contact-manager/");
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $contactID = $_POST['tbl_contact_id'];
    $updateContactName = $_POST['contact_name'];
    $updateContactNumber = $_POST['contact_number'];
    $updateContactEmail = $_POST['contact_email'];
    $updateContactAddress = $_POST['contact_address'];

    //...more code...

    $stmt = $conn->prepare("UPDATE tbl_contact SET contact_name = ?, contact_number = ?, contact_email = ?, contact_address = ? WHERE tbl_contact_id = ?");
    $stmt->execute([$updateContactName, $updateContactNumber, $updateContactEmail, $updateContactAddress, $contactID]);

    header("location: http://localhost/contact-manager/");
    exit();
}

In these two code snippets, there are cases where data is directly received and processed from the user’s POST request, but CSRF protection is not implemented, so they may be exploited by attackers. Attackers can forge a legitimate user’s POST request to add or update data in the database, therefore both of these code snippets have CSRF vulnerabilities.

PoC

Create a contact, with the contact ID being 15.

Create a test.html file with the following content.

<a href="http://localhost/endpoint/delete.php?contact=15"> test for csrf</a>

When the user clicks “test for csrf”, it will directly trigger the delete function and delete the specified contact.

Contact deleted successfully

Confirm the existence of CSRF vulnerability.