Skip to content

Fix SQL injection, RCE via file deletion, and config injection#631

Open
7h30th3r0n3 wants to merge 1 commit into
Nachtzuster:mainfrom
7h30th3r0n3:fix/security-vulnerabilities
Open

Fix SQL injection, RCE via file deletion, and config injection#631
7h30th3r0n3 wants to merge 1 commit into
Nachtzuster:mainfrom
7h30th3r0n3:fix/security-vulnerabilities

Conversation

@7h30th3r0n3

Copy link
Copy Markdown

Summary

Fixes multiple critical security vulnerabilities in the BirdNET-Pi web interface. This PR complements #629 (which fixes command injection in newname, shiftfile, sendtest, and species_delete) by addressing the remaining attack surfaces:

  • OS Command Injection via deletefile (CVSSv3 9.8) — play.php passed user input directly into exec("sudo rm $file_pointer"). Replaced with realpath() path validation + native PHP unlink().
  • SQL Injection in play.phpfilename parameter concatenated into query string. Now uses parameterized bindValue().
  • SQL Injection in common.php (×3 functions) — fetch_species_array(), fetch_best_detection(), and fetch_all_detections() all interpolated user input into SQL. All converted to parameterized queries.
  • SQL Injection in todays_detections.php (×5 LIKE clauses) — searchterm parameter concatenated into 5 LIKE conditions. Now uses named parameter bindings :t1:t5.
  • Config Injection → Root RCE in config.php — Unsanitized user input written to birdnet.conf (a bash-sourced file) allowed arbitrary command injection on next service restart. Added whitelist sanitization and numeric validation for all config values.

Note: These SQL injection vectors are currently mitigated by FILTER_SANITIZE_STRING on PHP < 8.2. However, this filter is deprecated (PHP 8.1) and removed (PHP 8.2+), making these exploitable after a routine system update — a "time bomb" scenario.

Together with #629, this closes all 7 vulnerabilities reported in #608.

Files Changed

File Fix
scripts/play.php RCE fix (deletefile) + SQLi fix (filename)
scripts/common.php SQLi fix in 3 query functions
scripts/config.php Config injection sanitization (all values)
scripts/todays_detections.php SQLi fix (searchterm, 5 LIKE clauses)

Test Plan

  • Verify file deletion still works via the web UI (deletefile)
  • Verify species browsing by date, confidence, occurrences (common.php queries)
  • Verify detection search with and without "NOT" prefix (todays_detections.php)
  • Verify config save works with normal values (config.php)
  • Verify config save rejects shell metacharacters in numeric fields
  • Verify filename-based detection lookup (play.php)

Ref: #608

…nerabilities

- play.php: Replace exec("sudo rm") with realpath() validation + unlink() to prevent
  OS command injection via deletefile parameter (CVSSv3 9.8)
- play.php: Use parameterized query for filename lookup to prevent SQL injection
- common.php: Convert all 3 query functions (fetch_species_array, fetch_best_detection,
  fetch_all_detections) from string interpolation to parameterized queries with bindValue()
- config.php: Sanitize all user-controlled values written to birdnet.conf using whitelist
  patterns and numeric validation to prevent config injection leading to root RCE
- todays_detections.php: Replace 5 concatenated LIKE clauses with parameterized bindings
  to prevent SQL injection via searchterm parameter

These fixes complement PR Nachtzuster#629 which addresses command injection in newname, shiftfile,
sendtest, and species_delete. Together they close all 7 identified vulnerabilities.

Ref: Nachtzuster#608
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant