Adminer has an Unauthenticated Persistent DoS via Array Injection in ?script=version Endpoint
Description
Adminer is open-source database management software. Adminer v5.4.1 and earlier 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. Upgrade to Adminer 5.4.2.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Adminer 5.4.1 and earlier are vulnerable to an unauthenticated persistent denial-of-service via array injection into the version check endpoint.
Adminer, an open-source database management tool, contains a denial-of-service (DoS) vulnerability in its version check mechanism. The endpoint ?script=version is designed to receive signed version data from adminer.org via JavaScript postMessage, which is then stored on the server for verification [1][2]. This endpoint lacks origin validation and accepts POST data from any source, including array parameters [2].
An unauthenticated attacker can exploit this by sending a POST request with the parameter version[] instead of version. PHP converts this to an array, which is then serialized and written to the /tmp/adminer.version file. On subsequent page loads, subsequent page loads, the code attempts to pass this array to the openssl_verify() function, which expects a string, resulting in a TypeError and causing an HTTP 500 error for all users [2][3]. No prior authentication or specific network position is required, making the attack surface broad [1].
The vulnerability leads to a persistent denial-of-service condition, impacting the availability of the Adminer application for all users. The crash occurs every time a page is loaded, as the malformed version file is read [2]. There is no data integrity or confidentiality impact, but the service becomes unavailable [2].
The issue is fixed in Adminer version 5.4.2 [4]. Users who cannot immediately upgrade can mitigate the risk by making the temporary directory (usually the value of upload_tmp_dir) unwritable by the web server, preventing the malicious file writing [2].
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
vrana/adminerPackagist | >= 4.6.2, < 5.4.2 | 5.4.2 |
Affected products
2- vrana/adminerv5Range: >= 4.6.2, < 5.4.2
Patches
121d3a3150388Avoid denial-of-service via version check (GHSA-q4f2-39gr-45jh, regression from 4.6.2)
5 files changed · +12 −52
adminer/include/bootstrap.inc.php+0 −10 modified@@ -29,16 +29,6 @@ include "../adminer/file.inc.php"; } -if ($_GET["script"] == "version") { - $filename = get_temp_dir() . "/adminer.version"; - @unlink($filename); // it may not be writable by us, @ - it may not exist - $fp = file_open_lock($filename); - if ($fp) { - file_write_unlock($fp, serialize(array("signature" => $_POST["signature"], "version" => $_POST["version"]))); - } - exit; -} - // Adminer doesn't use any global variables; they used to be declared here if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
adminer/include/design.inc.php+3 −19 modified@@ -62,24 +62,8 @@ function page_header(string $title, string $error = "", $breadcrumb = array(), s adminer()->bodyClass(); echo "'>\n"; $filename = get_temp_dir() . "/adminer.version"; - if (!$_COOKIE["adminer_version"] && function_exists('openssl_verify') && file_exists($filename) && filemtime($filename) + 86400 > time()) { // 86400 - 1 day in seconds - $version = unserialize(file_get_contents($filename)); - $public = "-----BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwqWOVuF5uw7/+Z70djoK -RlHIZFZPO0uYRezq90+7Amk+FDNd7KkL5eDve+vHRJBLAszF/7XKXe11xwliIsFs -DFWQlsABVZB3oisKCBEuI71J4kPH8dKGEWR9jDHFw3cWmoH3PmqImX6FISWbG3B8 -h7FIx3jEaw5ckVPVTeo5JRm/1DZzJxjyDenXvBQ/6o9DgZKeNDgxwKzH+sw9/YCO -jHnq1cFpOIISzARlrHMa/43YfeNRAm/tsBXjSxembBPo7aQZLAWHmaj5+K19H10B -nCpz9Y++cipkVEiKRGih4ZEvjoFysEOdRLj6WiD/uUNky4xGeA6LaJqh5XpkFkcQ -fQIDAQAB ------END PUBLIC KEY----- -"; - if (openssl_verify($version["version"], base64_decode($version["signature"]), $public) == 1) { - $_COOKIE["adminer_version"] = $version["version"]; // doesn't need to send to the browser - } - } echo script("mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick" - . (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '" . VERSION . "', '" . js_escape(ME) . "', '" . get_token() . "')") + . (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '" . VERSION . "')") . "}); document.body.classList.replace('nojs', 'js'); const offlineMessage = '" . js_escape(lang('You are offline.')) . "'; @@ -153,8 +137,8 @@ function csp(): array { return array( array( "script-src" => "'self' 'unsafe-inline' 'nonce-" . get_nonce() . "' 'strict-dynamic'", // 'self' is a fallback for browsers not supporting 'strict-dynamic', 'unsafe-inline' is a fallback for browsers not supporting 'nonce-' - "connect-src" => "'self'", - "frame-src" => "https://www.adminer.org", + "connect-src" => "'self' https://www.adminer.org", + "frame-src" => "'none'", "object-src" => "'none'", "base-uri" => "'none'", "form-action" => "'self'",
adminer/static/functions.js+7 −21 modified@@ -96,29 +96,15 @@ function cookie(assign, days) { /** Verify current Adminer version * @param string -* @param string own URL base -* @param string */ -function verifyVersion(current, url, token) { +function verifyVersion(current) { cookie('adminer_version=0', 1); - const iframe = document.createElement('iframe'); - iframe.src = 'https://www.adminer.org/version/?current=' + current; - iframe.frameBorder = 0; - iframe.marginHeight = 0; - iframe.scrolling = 'no'; - iframe.style.width = '7ex'; - iframe.style.height = '1.25em'; - iframe.style.display = 'none'; - addEventListener('message', event => { - if (event.origin == 'https://www.adminer.org') { - const match = /version=(.+)/.exec(event.data); - if (match) { - cookie('adminer_version=' + match[1], 1); - ajax(url + 'script=version', () => { }, event.data + '&token=' + token); - } - } - }, false); - qs('#version').appendChild(iframe); + // do not send X-Requested-With to avoid preflight + fetch('https://www.adminer.org/version/?current=' + current).then(async response => { + const json = await response.json(); + cookie('adminer_version=' + (json.version || current), 7); // empty if there's no newer version + qs('#version').textContent = json.version; + }); } /** Get value of select
CHANGELOG.md+1 −0 modified@@ -1,4 +1,5 @@ ## Adminer dev +- Avoid denial-of-service via version check (GHSA-q4f2-39gr-45jh, regression from 4.6.2) - Pretty print JSON in edit - Support multiline generated values in alter table - Link //domain.tld values
plugins/version-github.php+1 −2 modified@@ -11,13 +11,12 @@ class AdminerVersionGithub extends Adminer\Plugin { function head($dark = null) { ?> <script <?php echo Adminer\nonce(); ?>> -verifyVersion = (current, url, token) => { +verifyVersion = current => { // dummy value to prevent repeated verifications after AJAX failure cookie('adminer_version=0', 1); ajax('https://api.github.com/repos/vrana/adminer/releases/latest', request => { const response = JSON.parse(request.responseText); const version = response.tag_name.replace(/^v/, ''); - // we don't save to adminer.version because the response is not signed; also GitHub can handle our volume of requests // we don't display the version here because we don't have version_compare(); design.inc.php will display it on the next load cookie('adminer_version=' + version, 1); }, null, null);
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-q4f2-39gr-45jhghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-25892ghsaADVISORY
- github.com/vrana/adminer/commit/21d3a3150388677b18647d68aec93b7850e457d3ghsax_refsource_MISCWEB
- github.com/vrana/adminer/releases/tag/v5.4.2ghsax_refsource_MISCWEB
- github.com/vrana/adminer/security/advisories/GHSA-q4f2-39gr-45jhghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.