Skip to content

SQL Injection via Unvalidated sort_by Query Parameter in Multiple Repository Classes

High
daveearley published GHSA-2qcp-24fh-fx6p Mar 28, 2026

Package

composer hi-events/hi-events (Composer)

Affected versions

>=0.8.x

Patched versions

>=v1.7.1-beta

Description

Summary

Multiple repository classes pass the user-supplied sort_by query parameter directly to Eloquent's orderBy() without validation, enabling SQL injection. The application uses PostgreSQL which supports stacked queries.

Root Cause

10+ repository files including AttendeeRepository.php, EventRepository.php, OrderRepository.php pass $sortBy directly to orderBy(). AttendeeRepository is worst-case — it concatenates: 'attendees.' . $sortBy.

An getAllowedSorts() whitelist exists and IS used correctly in the admin endpoint (getAllEventsForAdmin()), proving awareness of the issue — but it is not applied in non-admin repositories.

// AttendeeRepository.php — no validation
$query->orderBy('attendees.' . $sortBy, $params->sort_direction);

// Correct pattern (admin endpoint):
if (in_array($params->sort_by, DomainObject::getAllowedSorts()->keys(), true)) {
    $query->orderBy($params->sort_by, ...);
}

Proof of Concept

# Authenticated organizer — time-based blind SQL injection
GET /api/events/{id}/attendees?sort_by=id;SELECT+pg_sleep(5)-- HTTP/1.1
Authorization: Bearer <organizer_token>
# Response delayed ~5 seconds confirms injection

Impact

  • Data exfiltration via stacked queries (PostgreSQL)
  • Attendee PII, payment data, promo codes accessible
  • Requires authenticated organizer role

Remediation

Apply the existing getAllowedSorts() whitelist in all repository classes, matching the pattern already used in getAllEventsForAdmin().

Credit

Discovered by @tikket1, 2026-03-28.

Severity

High

CVE ID

CVE-2026-34455

Weaknesses

Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data. Learn more on MITRE.

Credits