Cover Image

Exploring DerbyNet Vulnerabilities: A Compilation of CVEs from 2024

Introduction

DerbyNet is an open-source project designed to streamline the management of Pinewood Derby races. As of the time of writing, the project has garnered nearly 100 stars on GitHub, signaling a growing interest and appreciation within its community. This software has been around for several years, demonstrating its resilience and ongoing relevance.

  • Repository: jeffpiazza/derbynet
  • Purpose: Pinewood Derby race management system
  • Affected Version: v9.0 and below

Research Methodology

I embarked on this journey into DerbyNet’s codebase driven by a curiosity to apply modern vulnerability identification techniques to a smaller-scale project. The inspiration behind this deep dive was a technique utilizing GitHub search patterns to uncover potential security flaws. By applying these patterns, my aim was to unearth vulnerabilities within DerbyNet and, in doing so, contribute to the enhancement of its security posture.

This article is a narrative of my exploration, detailing the vulnerabilities I discovered and the process behind their identification. It’s a testament to the importance of security in software development and a call to action for developers and security enthusiasts alike to continuously scrutinize and fortify the applications we create and rely on.

Acknowledgments

A huge thanks to the DerbyNet developer for promptly patching these vulnerabilities after they were reported and for the $5 tip as a token of appreciation. It’s gestures like these that emphasize the spirit of the open-source community—quick to respond and always supportive.

This exploration into DerbyNet’s vulnerabilities was not just about finding flaws but also about the collective effort towards better security. Let’s keep this momentum going, ensuring our digital spaces are safe for everyone.

Vulnerabilities Summary

This research uncovered 11 critical vulnerabilities in DerbyNet v9.0:

Type Count CVE IDs
Local File Inclusion (LFI) 1 CVE-2024-31818
Cross-Site Scripting (XSS) 7 CVE-2024-30920, CVE-2024-30921, CVE-2024-30924, CVE-2024-30925, CVE-2024-30926, CVE-2024-30927, CVE-2024-30929
SQL Injection (SQLi) 3 CVE-2024-30922, CVE-2024-30923, CVE-2024-30928

Key Statistics:

  • Total CVEs: 11
  • Unauthenticated: 10 vulnerabilities
  • Authenticated: 1 vulnerability
  • Critical Impact: All vulnerabilities allow unauthorized access or code execution

Local File Inclusion Leading to Potential Remote Code Execution in DerbyNet’s kiosk.php

Vulnerability Overview

Field Details
CVE ID CVE-2024-31818
Affected Version v9.0 and below
Affected Component Kiosk functionality in kiosk.php
Type Local File Inclusion (LFI) with potential for Remote Code Execution (RCE)
Authentication Not required (Unauthenticated)
Impact Unauthenticated access to arbitrary files; potential pathway to RCE
Location kiosk.php file within DerbyNet

Vulnerability Details

Before a critical security patch was applied, DerbyNet’s kiosk.php exhibited a severe Local File Inclusion (LFI) vulnerability. The flaw was rooted in the handling of the $_GET['page'] parameter without proper validation.

Vulnerable Code:

// 'page' query argument to support testing
if (isset($_GET['page'])) {
  require($_GET['page']);  // ⚠️ Direct inclusion without validation
} else {
  $kpage = kiosk_page(address_for_current_kiosk());
  $g_kiosk_parameters_string = $kpage['params'];
  require($kpage['page']);
}

Impact:

This code snippet dangerously allowed for the inclusion of files specified by the user through the page parameter without proper validation, enabling:

  • Reading of arbitrary server files
  • Exposure of sensitive information (configuration files, source code, etc.)
  • Potential Remote Code Execution (RCE) through sophisticated exploitation techniques involving PHP filter chains

Exploitation

Steps to Reproduce:

  1. Basic LFI: Manipulate the page parameter in a request to kiosk.php, pointing it to a sensitive file path:

    kiosk.php?page=../../path/to/sensitive/file
    
  2. Advanced RCE (theoretical): Advanced exploitation could involve complex PHP filter chains aiming for Remote Code Execution, though this was not successfully demonstrated in this research.

Example Payload:

kiosk.php?page=../../../../etc/passwd

Resolution

This vulnerability was promptly addressed after direct communication with the project maintainer, highlighting the importance of responsible vulnerability disclosure and the quick response from open-source project maintainers to secure their applications.


Unauthenticated SQL Injection via ‘where’ Clause in Award Document Rendering

Vulnerability Overview

Field Details
CVE ID CVE-2024-30922
Affected Version v9.0 and below
Affected Component print/render/award.inc in document rendering process
Type SQL Injection
Authentication Not required (Unauthenticated)
Attack Vector where parameter in URL

Vulnerability Details

DerbyNet’s document rendering endpoint, specifically within print/render/award.inc, is vulnerable to an unauthenticated SQL Injection. This vulnerability is exploitable via the where parameter in the URL.

Vulnerable Code:

$base_sql = 'SELECT awardid, awardname, awardtype, classid, rankid, racerid '
  .' FROM '.inner_join('Awards', 'AwardTypes', 'Awards.awardtypeid = AwardTypes.awardtypeid');

$sql = $base_sql;
if (($_GET['ids'])) {
  $sql .= ' WHERE awardid IN ('.$_GET['ids'].',0)';
} else if (isset($_GET['where'])) {
  $sql .= ' WHERE '.$_GET['where'];  // ⚠️ Direct SQL injection without sanitization
}

Impact:

The vulnerability is due to the direct incorporation of the where parameter into the SQL query without proper sanitization, allowing attackers to:

  • Manipulate the SQL query structure
  • Execute arbitrary SQL commands
  • Access unauthorized data
  • Modify database contents
  • Compromise database structure (SQLite3)

Exploitation

SQLMap Analysis:

The vulnerability was confirmed using sqlmap, which identified multiple injection techniques:

  1. Boolean-based blind SQL Injection:

    options: {}&where=1 AND 1470=1470
    

    This payload alters the query logic without affecting the application’s response, confirming the vulnerability.

  2. Time-based blind SQL Injection:

    options: {}&where=1 AND 4054=LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2))))
    

    This payload causes a significant delay in the response, indicating control over query execution timing.

Analysis

This SQL Injection flaw underscores the critical need for:

  • Input validation: All user inputs must be validated
  • Parameterized queries: Use prepared statements instead of string concatenation
  • Output encoding: Proper encoding of database outputs

Implementing these security measures can significantly mitigate the risk posed by SQL Injection vulnerabilities.


Unauthenticated SQL Injection via ‘where’ Clause in Racer Document Rendering

Vulnerability Overview

Field Details
CVE ID CVE-2024-30923
Affected Version v9.0 and below
Affected Component Racer document generation in print/render/racer.inc
Type SQL Injection
Authentication Not required (Unauthenticated)
Attack Vector where parameter in URL

Vulnerability Details

The print/render/racer.inc component of DerbyNet is vulnerable to an unauthenticated SQL Injection attack. This vulnerability is due to improper sanitization of the where parameter in the URL.

Vulnerable Code:

function draw_one_racer(&$racer) {
      global $doc;
      convert_strings($racer);
      clean_fake_photos($racer);
      $racer['barcode'] = 'PWDid'.sprintf('%03d', $racer['racerid']);
      $doc->DrawOne($racer);
}

if (isset($_GET['ids'])) {
  $sql = $base_sql.' WHERE racerid = :racerid';
  $stmt = $db->prepare($sql);
  foreach (explode(',', $_GET['ids']) as $racerid) {
    $stmt->execute(array(':racerid' => $racerid));
    $racer = $stmt->fetch(PDO::FETCH_ASSOC);
    draw_one_racer($racer);
  }
} else {
  $sql = $base_sql;
  if (isset($_GET['where'])) {
    $sql = $sql.' WHERE '.$_GET['where'];  // ⚠️ Direct SQL injection
  }
  $sql = $sql.' ORDER BY lastname, firstname, carnumber';

  foreach ($db->query($sql) as $racer) {
    draw_one_racer($racer);
  }
}

Impact:

The vulnerability arises from the direct inclusion of the $_GET['where'] parameter into the SQL statement without proper validation or sanitization. This allows attackers to:

  • Alter the SQL query’s logic
  • Access or manipulate sensitive database information unauthorizedly
  • Extract data from the database

Exploitation

SQLMap Confirmation:

The sqlmap tool successfully confirmed this vulnerability with a boolean-based blind SQL injection:

where: 1 AND 8050=8050

Example Payload:

print/render/racer.inc?where=1 AND 8050=8050

Unauthenticated SQL Injection via ‘classids’ Parameter in ajax/query.slide.next.inc

Vulnerability Overview

Field Details
CVE ID CVE-2024-30928
Affected Version v9.0 and below
Affected Component Handling of slide and racer information in DerbyNet
Type SQL Injection
Authentication Not required (Unauthenticated)
Attack Vector classids parameter in URL
Location ajax/query.slide.next.inc
Endpoint action.php?query=slide.next&mode=racer&classids=1

Vulnerability Details

Within the file ajax/query.slide.next.inc, the application constructs an SQL query dynamically using the classids parameter from the user’s request. This parameter is not sanitized before being incorporated into the SQL statement, introducing a significant risk of SQL Injection.

Vulnerable Code:

if (isset($_GET['mode'])) {
  $mode = $_GET['mode'];
}

$racerid = 0;
if (isset($_GET['racerid'])) {
  $racerid = $_GET['racerid'];
}

$classids = '';
if (isset($_GET['classids'])) {
  $classids = $_GET['classids'];  // ⚠️ No sanitization
}

...

if (!$done && $mode == 'racer') {
  $row = read_single_row('SELECT racerid, lastname, firstname, carnumber, carname, classid,'
                         .' imagefile, carphoto FROM RegistrationInfo'
                         .' WHERE racerid > :racerid'
                         .'  AND passedinspection'
                         .'  AND ((imagefile IS NOT NULL AND imagefile <> \'\') OR'
                         .'       (carphoto IS NOT NULL AND carphoto <> \'\'))'
                         .($classids ? ' AND classid IN ('.$classids.')' : '')  // ⚠️ Direct injection
                         .' ORDER BY racerid',
                         array(':racerid' => $racerid),
                         PDO::FETCH_ASSOC);
}

Impact:

The classids parameter is directly concatenated into the SQL query without validation, allowing attackers to:

  • Execute arbitrary SQL commands
  • Extract sensitive data from the database
  • Manipulate query results

Exploitation

SQLMap Detection:

SQLMap identified the SQL Injection vulnerability with the following payloads:

  1. Boolean-based blind:

    query: slide.next&mode=racer&classids=1) AND 4365=4365 AND (6880=6880
    
  2. UNION query:

    query: slide.next&mode=racer&classids=-3890) UNION ALL SELECT NULL,NULL,CHAR(113,107,120,122,113)||CHAR(79,97,117,85,112,79,82,85,75,114,65,66,118,100,117,107,79,118,111,104,67,105,87,86,72,110,107,119,113,86,106,107,115,100,110,109,98,77,85,115)||CHAR(113,118,120,120,113),NULL,NULL,NULL,NULL,NULL-- rDzQ
    

Unauthenticated XSS Vulnerability in ./inc/kiosks.inc

Vulnerability Overview

Field Details
CVE ID CVE-2024-30926
Affected Version v9.0 and below
Affected Component Kiosk address handling in ./inc/kiosks.inc
Type Cross-Site Scripting (XSS)
Authentication Not required (Unauthenticated)
Attack Vector id and address URL parameters

Vulnerability Details

In DerbyNet, an unauthenticated Cross-Site Scripting (XSS) vulnerability exists within the address_for_current_kiosk() function located in the ./inc/kiosks.inc file. This vulnerability arises from the improper handling of user-supplied input through URL parameters id and address.

Vulnerable Code:

function address_for_current_kiosk() {
  $addr = "";
  if (isset($_GET['id'])) {
    $addr = $_GET['id'];  // ⚠️ Direct assignment without sanitization
  } else if (isset($_GET['address'])) {
    $addr = $_GET['address'];  // ⚠️ Direct assignment without sanitization
  }
  // Further code that uses $addr, potentially leading to XSS when rendered in a browser
  return $addr;
}

Impact:

The function accepts input from URL parameters, which are directly assigned to a variable without sanitization. This flaw allows attackers to:

  • Inject malicious JavaScript code
  • Execute arbitrary scripts in the user’s browser context
  • Steal sensitive information (cookies, session tokens, etc.)
  • Perform unauthorized actions on behalf of the user

Exploitation

Malicious URLs:

Attackers can craft malicious URLs to exploit this vulnerability:

http://127.0.0.1:8000/kiosk.php?id=<script>alert(1)</script>
http://127.0.0.1:8000/kiosk.php?address=<script>alert(1)</script>

When these URLs are accessed, the JavaScript code within the parameters is executed, leading to an XSS attack.

Analysis

The core of this vulnerability lies in the function’s failure to sanitize the id and address URL parameters before using them. Since this vulnerability does not require authentication to exploit, any malicious individual who can convince a user to click on a specially crafted link could potentially:

  • Execute unauthorized actions on behalf of the user
  • Steal sensitive information
  • Compromise the user’s interaction with the application

Unauthenticated XSS in racer-results.php

Vulnerability Overview

Field Details
CVE ID CVE-2024-30927
Affected Version v9.0 and below
Affected Component Display of racer results in racer-results.php
Type Cross-Site Scripting (XSS)
Authentication Not required (Unauthenticated)
Attack Vector racerid parameter in URL

Vulnerability Details

The racer-results.php file in DerbyNet exhibits an unauthenticated Cross-Site Scripting (XSS) vulnerability through the mishandling of the racerid parameter in the URL. The vulnerability specifically arises within the HTML <title> tag, where the application dynamically inserts the value of the racerid parameter directly without any form of sanitization or encoding.

Vulnerable Code:

<title>Results By Racer <?php if (isset($_GET['racerid'])) echo ' for '.$_GET['racerid']; ?></title>

Impact:

This code directly incorporates user-supplied input from the racerid URL parameter into the HTML output without any sanitization. This oversight allows:

  • Injection of arbitrary HTML and JavaScript code
  • Manipulation of page content
  • Execution of arbitrary JavaScript in the victim’s browser session

Exploitation

Malicious URL:

Attackers can exploit this vulnerability by crafting a URL that includes malicious JavaScript code:

http://127.0.0.1:8000/racer-results.php?racerid=</title><script>alert(1)</script>

This crafted URL closes the <title> tag prematurely and injects a <script> tag that, when executed, can perform actions such as displaying an alert box, among other potential malicious activities.

Analysis

The vulnerability stems from the direct inclusion of unsanitized user input ($_GET['racerid']) in the page output, particularly within the HTML <title> element. By injecting malicious content into the racerid parameter, an attacker can manipulate the page content or execute arbitrary JavaScript in the context of the victim’s browser session.


Unauthenticated XSS in render-document.php

Vulnerability Overview

Field Details
CVE ID CVE-2024-30920
Affected Version v9.0 and below
Affected Component Document rendering in render-document.php
Type Cross-Site Scripting (XSS)
Authentication Not required (Unauthenticated)
Attack Vector URL path manipulation

Vulnerability Details

render-document.php in DerbyNet is vulnerable to unauthenticated XSS due to improper handling of user input in document rendering paths. The vulnerability arises from the application’s display of debug information, including ORIG_SCRIPT_FILENAME, DOCUMENT_URI, SCRIPT_NAME, and PHP_SELF, which improperly handle user-supplied input.

Impact:

The issue stems from echoing user input without sanitization in debug mode, a practice not recommended for production environments. This flaw allows:

  • Injection of arbitrary scripts executable in a user’s browser
  • Compromise of user data and interaction with the application
  • Execution of malicious JavaScript in the victim’s browser context

Exploitation

Malicious URLs:

Attackers can inject malicious scripts via URLs:

http://127.0.0.1:8000/render-document.php/racer/<img src=x onerror=alert(1)>
http://127.0.0.1:8000/render-document.php/<img src=x onerror=alert(1)>

Analysis

Proper handling and sanitization of input data are essential to mitigate such vulnerabilities. Debug information should never be displayed in production environments without proper sanitization.


Unauthenticated XSS in photo.php

Vulnerability Overview

Field Details
CVE ID CVE-2024-30921
Affected Version v9.0 and below
Affected Component Photo handling in photo.php
Type Cross-Site Scripting (XSS)
Authentication Not required (Unauthenticated)
Attack Vector URL path manipulation

Vulnerability Details

photo.php within DerbyNet is susceptible to an unauthenticated XSS attack, facilitated by the display of debug text that improperly processes user input.

Impact:

This vulnerability is a direct consequence of displaying debug information without adequately sanitizing user-controlled inputs. This practice can lead to:

  • Execution of malicious scripts in the victim’s browser
  • Compromise of user data and session information
  • Unauthorized actions on behalf of the user

Exploitation

Malicious URL:

By navigating to the following URL, an attacker can execute arbitrary JavaScript:

http://127.0.0.1:8000/photo.php/<img src=x onerror=alert(1)>

Analysis

This vulnerability underlines the importance of removing or securing debug information in production environments. All user-controlled inputs must be properly sanitized before being displayed in any context.


Authenticated XSS in photo-thumbs.php

Vulnerability Overview

Field Details
CVE ID CVE-2024-30925
Affected Version v9.0 and below
Affected Component Photo thumbnails navigation in photo-thumbs.php
Type Cross-Site Scripting (XSS)
Authentication Required (Authenticated)
Attack Vector racerid and back URL parameters

Vulnerability Details

photo-thumbs.php in DerbyNet suffers from an authenticated XSS vulnerability due to improper handling of the racerid and back parameters. The application dynamically generates a URL for navigation without sanitizing these parameters, allowing an attacker to inject malicious scripts.

Vulnerable Code:

<?php
    echo "<a class='button_link' id='refresh-button' onclick='window.location.reload();'>Refresh</a>";
    $url = "photo-thumbs.php?repo=$other_repo&amp;order=$order";
    if (isset($_GET['racerid'])) {
      $url .= "&amp;racerid=" . $_GET['racerid'];  // ⚠️ Vulnerable to XSS injection
    }
    if (isset($_GET['back'])) {
      $url .= "&amp;back=" . $_GET['back'];  // ⚠️ Vulnerable to XSS injection
    }
    echo "<a id='other-button' class='button_link' href='$url'>"; // ⚠️ Injection point
    echo $other_repo == 'head' ? 'Racers' : 'Cars';
    echo "</a>";
?>

Impact:

  1. Injection through URL Parameters: The script directly incorporates values from the $_GET['racerid'] and $_GET['back'] parameters into the URL without sanitizing them. This flaw allows attackers to craft URLs containing malicious JavaScript code.

  2. Vulnerable Dynamic URL Construction: The constructed $url variable, containing the unsanitized inputs, is used in the href attribute of an anchor tag. When a user navigates to the maliciously crafted URL, the JavaScript code embedded in the URL parameters is executed in the context of the user’s browser.

Exploitation

Attack Scenario:

An authenticated attacker can craft malicious URLs containing JavaScript payloads in the racerid or back parameters, which will be executed when the victim clicks on the generated link.

Analysis

This vulnerability demonstrates the importance of sanitizing all user inputs, even in authenticated contexts. URL parameters must be properly encoded before being included in HTML attributes.

Authenticated XSS Vulnerability in checkin.php

Vulnerability Overview

Field Details
CVE ID CVE-2024-30924
Affected Version v9.0 and below
Affected Component Order handling in checkin.php
Type Cross-Site Scripting (XSS)
Authentication Required (Authenticated)
Attack Vector order URL parameter

Vulnerability Details

In DerbyNet’s checkin.php, an authenticated Cross-Site Scripting (XSS) vulnerability is identified, emanating from improper handling of the order URL parameter. The vulnerability is introduced within a JavaScript variable assignment, where the order parameter value is directly embedded without proper sanitization or encoding.

Vulnerable Code:

<script type="text/javascript">
var g_order = '<?php echo $order; ?>';  // ⚠️ Direct output without sanitization
var g_action_on_barcode = "<?php
  echo isset($_SESSION['barcode-action']) ? $_SESSION['barcode-action'] : "locate";
?>";

Impact:

In this snippet, the $order PHP variable is directly echoed into a JavaScript variable declaration (var g_order). Since the value of $order comes from the order URL parameter and is not sanitized before being output, an attacker can:

  • Inject arbitrary JavaScript by manipulating the order parameter
  • Execute JavaScript code in the context of the authenticated user’s session
  • Perform unauthorized actions or expose sensitive information

Exploitation

Malicious URLs:

Attackers can inject malicious scripts via the order parameter:

http://127.0.0.1:8000/checkin.php?order=</script><script>alert(1)</script>
http://127.0.0.1:8000/checkin.php?order=';alert(1);//

Analysis

This vulnerability underscores the importance of:

  • Treating all user input as untrusted: Never trust user-supplied data
  • Applying rigorous sanitization and encoding: Especially when incorporating input into executable code contexts like JavaScript
  • Using proper output encoding: JavaScript contexts require specific encoding techniques

Authenticated XSS via ‘back’ Parameter in playlist.php

Vulnerability Overview

Field Details
CVE ID CVE-2024-30929
Affected Version v9.0 and below
Affected Component Navigation and redirection logic within DerbyNet
Type Cross-Site Scripting (XSS)
Authentication Required (Authenticated)
Attack Vector back URL parameter
Location playlist.php

Vulnerability Details

In DerbyNet’s playlist.php, an authenticated Cross-Site Scripting (XSS) vulnerability has been identified, exploiting the back parameter. The application fails to sanitize the back parameter before including it in the page output, enabling the injection and execution of arbitrary JavaScript code.

Vulnerable Code:

<?php make_banner('Rounds Playlist', isset($_GET['back']) ? $_GET['back'] : 'coordinator.php'); ?>

Impact:

This code dynamically sets the redirection target based on the back parameter from the URL. Due to the lack of proper output encoding or sanitization:

  • Malicious scripts can be injected as part of the back parameter
  • The injected script will be executed by the browser
  • Arbitrary JavaScript code can run in the context of an authenticated session

Exploitation

Malicious URL:

The exploitation of this vulnerability requires an authenticated session:

http://127.0.0.1:8000/playlist.php?back="><script>alert(1)</script>

Analysis

This vulnerability underscores the importance of properly sanitizing all user inputs, especially in functionalities accessible post-authentication, to mitigate the risk of XSS attacks. Even authenticated contexts require proper input validation and output encoding.