SDXSDXSHADOW LABS
Back to Disclosures
CRITICALSDX-2025-001 Nov 2025

Chained SQL Injection Vulnerabilities in Large Private Educational Technical Support System

Category: Web & Mobile
Status: Remediated

Executive Summary

In November 2025, the SDX Shadow Labs offensive research team conducted an unauthorized-access vulnerability analysis on a central school management and tracking framework deployed by a major private educational technology provider. This framework services over 100 schools, coordinating student logistics, parent communication, and academic tracking.

Our investigation identified five distinct SQL injection (SQLi) vulnerabilities spanning the public web application and its corresponding mobile application REST API. If exploited, these flaws allowed unauthenticated attackers to bypass authentication controls, extract the entire relational database structure, and exfiltrate highly sensitive personally identifiable information (PII). This included live GPS coordinates of school buses, student tracking histories, parent contact directories, and complete academic and human resources records for teaching staff.


Technical Analysis & Vulnerability Mechanics

The target architecture utilizes a multi-tenant relational database (PostgreSQL) to store data across all serviced schools. The primary vulnerabilities were located within the endpoints handling real-time telemetry and student attendance reports:

  1. Endpoint A (/api/v1/tracking/vehicle_status): Utilized by the mobile application to poll vehicle positions. The vehicle_id parameter was passed directly into a raw database query template:
    SELECT id, last_lat, last_lng, status FROM vehicle_locations WHERE vehicle_id = '$vehicle_id';
    
  2. Endpoint B (/api/v1/reports/attendance): Utilized by the web administrative portal. The query parameter for filtering by class_section lacked parameterization, enabling SQL query stacking.

By injecting boolean and time-based payloads into these parameters, we bypassed the application logic. The database was confirmed to execute arbitrary commands under the privileges of the main application user, allowing read access to system catalogs and tenant tables.


Step-by-Step Attack Path

1. API Mapping & Mobile Decoupling

The engagement began by obtaining the provider's public Android application package (APK). We decompiled the binary using apktool to analyze the database synchronization helpers and locate REST API endpoints. Static analysis of AndroidManifest.xml and resource files exposed the primary API base URL and endpoints used for real-time location sync.

2. Unauthenticated Parameter Fuzzing

Using an intercepting proxy, we captured API traffic and mapped parameters. Automated fuzzing of the vehicle_id and class_section parameters revealed anomalous server behaviors:

  • Submitting vehicle_id=VEH01' threw a generic database driver exception (500 Internal Server Error).
  • Submitting vehicle_id=VEH01' OR '1'='1 returned location data for the first record in the database, verifying the injection of executable SQL commands.

3. Blind SQL Injection Exploitation

To avoid detection and bypass basic web application firewalls (WAF), we crafted boolean-based and time-based blind SQL payloads.

  • Boolean-Based Proof of Concept:

    GET /api/v1/tracking/vehicle_status?vehicle_id=VEH01' AND (SELECT CASE WHEN (1=1) THEN 1 ELSE 0 END)='1 HTTP/1.1
    Host: api.target-provider.com
    

    This payload evaluated to True and returned a standard location response. Changing the condition to 1=2 evaluated to False and returned an empty array, confirming a reliable boolean-based extraction channel.

  • Time-Based Schema Extraction: To extract database schemas, we injected PG-sleep commands to perform database enumeration:

    GET /api/v1/tracking/vehicle_status?vehicle_id=VEH01' AND (SELECT 1 FROM pg_sleep(5))='1 HTTP/1.1
    Host: api.target-provider.com
    

    The database thread paused for exactly 5.02 seconds, proving unauthenticated time-based blind injection.

4. Database Exfiltration & PII Exposure

Using custom multi-threaded Python scripts to run time-based extraction queries, we mapped the database schemas:

  1. Enumerated the database system tables to identify user-defined tables: users, parents_directory, student_telemetry, and staff_payroll.
  2. Extracted sample rows from the student_telemetry and parents_directory tables. The data leaked included active latitude/longitude vectors of school transports and parent mobile numbers, representing a severe physical security risk.

Remediation & Verification

Code-Level Remediation

We advised the client's development team to eliminate all raw string interpolation within SQL statements. In the PHP/Laravel backend, queries were refactored to use Eloquent ORM parameter binding:

// Vulnerable Code
$data = DB::select("SELECT id, last_lat, last_lng FROM vehicle_locations WHERE vehicle_id = '" . $request->input('vehicle_id') . "'");

// Secured Code
$data = DB::select("SELECT id, last_lat, last_lng FROM vehicle_locations WHERE vehicle_id = :id", ['id' => $request->input('vehicle_id')]);

Structural Defense-in-Depth

  1. Database Least Privilege: Restrict the web application's database user to SELECT, INSERT, and UPDATE permissions only on required tables, preventing execution of administrative functions or system catalog reading.
  2. WAF Enforcement: Configured signature-matching rules to block common SQL injection keywords (UNION, SELECT, pg_sleep, char) on all incoming request queries.

Verification

During follow-up testing in late November 2025, our team attempted to replicate the attack path. All SQL injection inputs were blocked at the application framework level or handled safely via parameterization, rendering the vulnerability fully remediated.