GCVE-1988-2026-0488

Vulnerability from gna-1988 – Published: 2026-11-02 07:30 – Updated: 2026-11-02 07:30
VLAI
Title
[0day-rubbish] Maian Pal 2.1 product image upload with no extension allow-list to PHP webshell and www-data uid 33 code execution (7.2, PR:H)
Summary
0day Rubbish Research Team is publicly disclosing a vulnerability in Maian Pal 2.1, the self-hosted PHP shopping-cart script from Maian Media (United Kingdom), oriented at PayPal checkout and distributed as a commercial closed-source archive, verified end to end against a real installation of that version in three independent reproductions. Type: unrestricted upload of a file with a dangerous type (CWE-434 primary, with CWE-94 and CWE-693 contributing - the stored object is subsequently interpreted as code, and the served upload directory lacks the execution restriction that equivalent directories in the same product carry), realised as OS command execution (CWE-78 describes what the demonstration payload does once it runs and is not scored separately). The product-image handling of the administration product create and update operations, `ajax-ops=add` and `ajax-ops=add-edit`, passes the multipart field fm[ifile][] to products::pictures() at `class.products.php:333` through `class.products.php:410`. The stored name is chosen from the client-supplied filename by a single ternary: // class.products.php:372 - no extension allow-list anywhere on this path $picPath = ($cfg['rename'] == 'yes' ? $cfg['imgprf'] . $ID . '-' . $nextPic . strrchr($name, '.') : $name); // class.products.php:~390 - written before any validation move_uploaded_file($temp, $picFldr . '/' . $picPath); With $cfg supplied by thumbcfg() at `class.products.php:615`, whose shipped default is 'rename' => 'no', that assignment reduces to $picPath = $name, so the client controls the entire stored name including the extension and a .php file lands on disk intact as content/products/<ID>/<name>.php. There is no extension allow-list and no deny-list, no finfo or MIME verification, no re-encoding to strip an embedded payload, no server-generated filename with a type-derived extension, and no rollback of the write when later validation fails. strtolower() appears only in the non-default rename='yes' branch and is cosmetic. The root cause has two independently fixable halves, and this advisory keeps them separate because fixing one without the other leaves the chain standing. The first half is the handler: what may be written. The second is the directory: whether what is written may execute. That second half lines up in this product because the destination sits inside the document root and the front-controller rewrite claims only paths that do not exist on disk - `RewriteCond !-f` guarding `RewriteRule ^([^?]*) index.php?_msw_=$1 [L,QSA]` - so a file that exists is handed straight to the PHP handler, and requesting it with a query string executes it. Nothing in content/products/ disables that handler. Our review of the shipped tree found an Apache deny file carrying `Deny from all` present in admin/import/, and found content/products/ carrying no such file. The contrast that makes this an omission rather than a design decision is inside one product and one shipped version: two handlers accept files from a browser, and one of them checks the extension and writes into a deny-protected directory while the other does neither. We are precise about the evidentiary weight of each half of that comparison, because it matters. That admin/import/ carries `Deny from all` and that content/products/ carries nothing are both anchored artefacts of the shipped tree. The statement that the product's attachment upload path applies an extension allow-list into a deny-protected directory is a source-level reading of the shipped PHP that we did not reduce to a line citation, and we label it as such. It is offered here the same way we put it to the seller: as a contrast worth confirming, since part of the argument that this is an omission rests on it. The ordering inside the handler makes the failure path worse rather than safer, and this is the detail most likely to be missed by a fix that only adds a check downstream. move_uploaded_file() runs before any thumbnail inspection, and the validation that does run is not fatal. getimagesize() inside thumbnail() runs after the write and is used only to select a thumbnail strategy, never to accept or reject the upload; for a PHP file it fails, the switch falls through to a suppressed @copy(), and the original is never unlinked. So a non-image upload leaves two objects in a served directory - the original plus a tmb_-prefixed sibling - deletes neither, and still reports {"status":"ok"}. The failure path yields two files rather than zero, silently. Any cleanup that removes only the obviously named object leaves the second one behind. Turning rename on would not fix this either, and it deserves emphasis because it is the obvious operator-facing knob: in the rename='yes' branch the stem is server-generated but the extension is still taken from the client filename via strrchr(), so a .php upload produces a server-named file that is still executable. We derived that from the assignment expression and did not run the rename='yes' configuration, so it is an argument from code rather than a dynamic result. Commands execute as the web server service account, observed as `uid=33(www-data) gid=33(www-data) groups=33(www-data)` in three independent reproductions with distinct random filenames, plus a marker written to an absolute path outside the document root and read back afterwards from the host. No privilege escalation of any kind was attempted or observed: no kernel exploit, no sudo right, no writable service unit, no container escape. Root was not reached and is not claimed; the ceiling of this finding is code execution as the web server user. How confirmation works. The chain is two requests. One POST creates the object and the create response itself embeds `?p=add&id=<ID>`, so the attacker learns the numeric product directory without guessing and the filename is one they chose - predictability of the final URL is total. One GET to `/content/products/<ID>/<name>.php?cmd=<command>` executes it and returns the output in the response body, prefixed by a marker that proves the body came from PHP execution rather than from static file serving. Both operations report {"status":"ok"}. What was deliberately not reproduced: no data theft, no database modification, no persistence beyond the uploaded file, no lateral movement and no exploitation of a live third-party system - all verification targeted our own instance, and the payload's default command is a non-destructive identity query. Scoring. One score is published: 7.2 High, CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H, the CVSS 3.1 base arithmetic for which is shown in full in the advisory and was re-checked against an independent implementation of that formula. AV:N because the sink sits on the product's ordinary HTTP(S) listener, with no separate management port, no RPC endpoint and no background listener, and nothing in the chain depends on source address, user agent or session age beyond validity. AC:L because one POST creates the object and one GET executes it, so there is no race window, no multi-step state to prepare and no unusual configuration requirement: the chain depends only on shipped defaults (thumbcfg() 'rename' => 'no', no deny file in content/products/), and the licence restriction RESTR_PRODUCTS = 50 does not obstruct the first product create. UI:N because no victim browser or user action is involved - the attacker authenticates with their own credentials and there is no forgery step. PR:H is published because only an authenticated administrator session was demonstrated. The credential pair is the one the installer provisions (LG_USER and LG_PASS in `control/_cfg.php`), mswPerms() gates every administration operation except login and logout, and no graduated back-end role was shown to reach ajax-ops=add. Four named alternative readings are published against that 7.2 so that each rejection is auditable, and one of them is conditional rather than rejected: - Scope Changed, AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H = 9.1. Rejected. The vulnerable component is the administration back-end and the impacted resources are that application's own files, its own database reached with the very credentials the application holds, and the operating-system context of the web server process it runs inside. The achieved identity is the same service account the application always ran as, on the same host, and nothing outside its reach before the upload came into reach afterwards. Publishing S:C would require a database-server compromise independent of the application's credentials, a container escape or a distinct host, and none was demonstrated. - Unauthenticated, AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8. Rejected, and this is the tempting headline for a public-facing shopping cart that we decline to print as ours. The storefront dispatcher's 56 unauthenticated AJAX operations contain no file-upload, command-execution, code-evaluation or deserialization primitive - only include() of language and class files - the administration login was reviewed on six specific bypass axes with no success, and the product ships no factory credential and no usable SECRET_KEY. - Lower-privileged back-end role, AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H = 8.8. Published as a conditional reading, labelled as such and never as the headline. The dispatcher exposes users, users-edit, permissions and permissions-edit, so the product may model back-end accounts narrower than the single installer-provisioned administrator; mswPerms() was established in our review only as an authentication gate over the dispatch, not as a per-operation authorization matrix; and no principal short of full administrator was demonstrated reaching ajax-ops=add. If a restricted back-end account can create or update products, that account is the least-privileged principal reaching the sink and PR:L is the faithful metric, at Impact 5.87311872 plus Exploitability 2.83525473, base 8.70837345, rounded up. We did not round our rating up to it, because doing so would assert a privilege model we did not observe. - Elevated complexity, AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H = 6.6, and user interaction, AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:H = 6.8. Both printed only so the rejections are inspectable: there is no race, no ordering constraint beyond one POST and one GET, no requirement that the target be in an unusual state, and no victim action at any point in the chain. Contributing weaknesses are reported and deliberately not scored into the vector: the single-round SHA-1 mswEnc() credential transform, loose `==` comparisons on hash and token strings, the absence of any enforced rotation of the installer-provisioned secret, and the inconsistency between upload handlers inside one shipped version. None of them lowers the privilege required to reach the sink and none raises the impact of the upload once it is reached. There is also no numeric base score in our own record against this vector that could disagree with it, so no correction notice accompanies the figure. Authentication: post-authentication administrator plus the session CSRF token, and both gates were treated as things to attack rather than as configuration to trust. There are no factory credentials in Maian Pal 2.1: the installer forces LG_USER, LG_PASS and SECRET_KEY to be set, `control/_cfg-sample.php:62` ships only the placeholder text "Your secret key value goes here", and this is not a default-credential report. The login path was reviewed for a missing or permissive permission configuration, a route that skips the gate, a predictable CSRF token, a pre-computable credential hash, a factory-credential fallback, a comparison-timing difference and a secondary authentication branch, and none was found; t
Severity
No CVSS data available.
Assigner
VULNARCHIVE GNA GNA-1988
GNA scorecard E 38/100 over 576 records in the last 180 days details
Impacted products
Vendor Product Version CPE status
Maian Pal Affected: unknown
guessed Create a notification for this product.

{
  "containers": {
    "cna": {
      "affected": [
        {
          "product": "Pal",
          "vendor": "Maian",
          "versions": [
            {
              "status": "affected",
              "version": "unknown"
            }
          ]
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "disclosure via Fulldisclosure"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "0day Rubbish Research Team is publicly disclosing a vulnerability in Maian Pal\n2.1, the self-hosted PHP shopping-cart script from Maian Media (United Kingdom),\noriented at PayPal checkout and distributed as a commercial closed-source archive,\nverified end to end against a real installation of that version in three\nindependent reproductions.\n\nType: unrestricted upload of a file with a dangerous type (CWE-434 primary, with\nCWE-94 and CWE-693 contributing - the stored object is subsequently interpreted as\ncode, and the served upload directory lacks the execution restriction that\nequivalent directories in the same product carry), realised as OS command\nexecution (CWE-78 describes what the demonstration payload does once it runs and\nis not scored separately). The product-image handling of the administration\nproduct create and update operations, `ajax-ops=add` and `ajax-ops=add-edit`,\npasses the multipart field fm[ifile][] to products::pictures() at\n`class.products.php:333` through `class.products.php:410`. The stored name is\nchosen from the client-supplied filename by a single ternary:\n\n    // class.products.php:372  - no extension allow-list anywhere on this path\n    $picPath = ($cfg[\u0027rename\u0027] == \u0027yes\u0027\n                ? $cfg[\u0027imgprf\u0027] . $ID . \u0027-\u0027 . $nextPic . strrchr($name, \u0027.\u0027)\n                : $name);\n\n    // class.products.php:~390  - written before any validation\n    move_uploaded_file($temp, $picFldr . \u0027/\u0027 . $picPath);\n\nWith $cfg supplied by thumbcfg() at `class.products.php:615`, whose shipped\ndefault is \u0027rename\u0027 =\u003e \u0027no\u0027, that assignment reduces to $picPath = $name, so the\nclient controls the entire stored name including the extension and a .php file\nlands on disk intact as content/products/\u003cID\u003e/\u003cname\u003e.php. There is no extension\nallow-list and no deny-list, no finfo or MIME verification, no re-encoding to\nstrip an embedded payload, no server-generated filename with a type-derived\nextension, and no rollback of the write when later validation fails. strtolower()\nappears only in the non-default rename=\u0027yes\u0027 branch and is cosmetic.\n\nThe root cause has two independently fixable halves, and this advisory keeps them\nseparate because fixing one without the other leaves the chain standing.\n\nThe first half is the handler: what may be written. The second is the directory:\nwhether what is written may execute. That second half lines up in this product\nbecause the destination sits inside the document root and the front-controller\nrewrite claims only paths that do not exist on disk - `RewriteCond !-f` guarding\n`RewriteRule ^([^?]*) index.php?_msw_=$1 [L,QSA]` - so a file that exists is handed\nstraight to the PHP handler, and requesting it with a query string executes it.\nNothing in content/products/ disables that handler. Our review of the shipped tree\nfound an Apache deny file carrying `Deny from all` present in admin/import/, and\nfound content/products/ carrying no such file.\n\nThe contrast that makes this an omission rather than a design decision is inside\none product and one shipped version: two handlers accept files from a browser, and\none of them checks the extension and writes into a deny-protected directory while\nthe other does neither. We are precise about the evidentiary weight of each half\nof that comparison, because it matters. That admin/import/ carries `Deny from all`\nand that content/products/ carries nothing are both anchored artefacts of the\nshipped tree. The statement that the product\u0027s attachment upload path applies an\nextension allow-list into a deny-protected directory is a source-level reading of\nthe shipped PHP that we did not reduce to a line citation, and we label it as\nsuch. It is offered here the same way we put it to the seller: as a contrast worth\nconfirming, since part of the argument that this is an omission rests on it.\n\nThe ordering inside the handler makes the failure path worse rather than safer,\nand this is the detail most likely to be missed by a fix that only adds a check\ndownstream. move_uploaded_file() runs before any thumbnail inspection, and the\nvalidation that does run is not fatal. getimagesize() inside thumbnail() runs\nafter the write and is used only to select a thumbnail strategy, never to accept\nor reject the upload; for a PHP file it fails, the switch falls through to a\nsuppressed @copy(), and the original is never unlinked. So a non-image upload\nleaves two objects in a served directory - the original plus a tmb_-prefixed\nsibling - deletes neither, and still reports {\"status\":\"ok\"}. The failure path\nyields two files rather than zero, silently. Any cleanup that removes only the\nobviously named object leaves the second one behind.\n\nTurning rename on would not fix this either, and it deserves emphasis because it\nis the obvious operator-facing knob: in the rename=\u0027yes\u0027 branch the stem is\nserver-generated but the extension is still taken from the client filename via\nstrrchr(), so a .php upload produces a server-named file that is still\nexecutable. We derived that from the assignment expression and did not run the\nrename=\u0027yes\u0027 configuration, so it is an argument from code rather than a dynamic\nresult.\n\nCommands execute as the web server service account, observed as\n`uid=33(www-data) gid=33(www-data) groups=33(www-data)` in three independent\nreproductions with distinct random filenames, plus a marker written to an absolute\npath outside the document root and read back afterwards from the host. No\nprivilege escalation of any kind was attempted or observed: no kernel exploit, no\nsudo right, no writable service unit, no container escape. Root was not reached\nand is not claimed; the ceiling of this finding is code execution as the web\nserver user.\n\nHow confirmation works. The chain is two requests. One POST creates the object\nand the create response itself embeds `?p=add\u0026id=\u003cID\u003e`, so the attacker learns\nthe numeric product directory without guessing and the filename is one they\nchose - predictability of the final URL is total. One GET to\n`/content/products/\u003cID\u003e/\u003cname\u003e.php?cmd=\u003ccommand\u003e` executes it and returns the\noutput in the response body, prefixed by a marker that proves the body came from\nPHP execution rather than from static file serving. Both operations report\n{\"status\":\"ok\"}. What was deliberately not reproduced: no data theft, no database\nmodification, no persistence beyond the uploaded file, no lateral movement and no\nexploitation of a live third-party system - all verification targeted our own\ninstance, and the payload\u0027s default command is a non-destructive identity query.\n\nScoring. One score is published: 7.2 High,\nCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H, the CVSS 3.1 base arithmetic for\nwhich is shown in full in the advisory and was re-checked against an independent\nimplementation of that formula. AV:N because the sink sits on the product\u0027s\nordinary HTTP(S) listener, with no separate management port, no RPC endpoint and\nno background listener, and nothing in the chain depends on source address, user\nagent or session age beyond validity. AC:L because one POST creates the object and\none GET executes it, so there is no race window, no multi-step state to prepare and\nno unusual configuration requirement: the chain depends only on shipped defaults\n(thumbcfg() \u0027rename\u0027 =\u003e \u0027no\u0027, no deny file in content/products/), and the licence\nrestriction RESTR_PRODUCTS = 50 does not obstruct the first product create. UI:N\nbecause no victim browser or user action is involved - the attacker authenticates\nwith their own credentials and there is no forgery step.\n\nPR:H is published because only an authenticated administrator session was\ndemonstrated. The credential pair is the one the installer provisions (LG_USER\nand LG_PASS in `control/_cfg.php`), mswPerms() gates every administration\noperation except login and logout, and no graduated back-end role was shown to\nreach ajax-ops=add. Four named alternative readings are published against that\n7.2 so that each rejection is auditable, and one of them is conditional rather\nthan rejected:\n\n  - Scope Changed, AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H = 9.1. Rejected. The\n      vulnerable component is the administration back-end and the impacted\n      resources are that application\u0027s own files, its own database reached with\n      the very credentials the application holds, and the operating-system\n      context of the web server process it runs inside. The achieved identity is\n      the same service account the application always ran as, on the same host,\n      and nothing outside its reach before the upload came into reach\n      afterwards. Publishing S:C would require a database-server compromise\n      independent of the application\u0027s credentials, a container escape or a\n      distinct host, and none was demonstrated.\n  - Unauthenticated, AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8. Rejected, and\n      this is the tempting headline for a public-facing shopping cart that we\n      decline to print as ours. The storefront dispatcher\u0027s 56 unauthenticated\n      AJAX operations contain no file-upload, command-execution, code-evaluation\n      or deserialization primitive - only include() of language and class files -\n      the administration login was reviewed on six specific bypass axes with no\n      success, and the product ships no factory credential and no usable\n      SECRET_KEY.\n  - Lower-privileged back-end role, AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H = 8.8.\n      Published as a conditional reading, labelled as such and never as the\n      headline. The dispatcher exposes users, users-edit, permissions and\n      permissions-edit, so the product may model back-end accounts narrower than\n      the single installer-provisioned administrator; mswPerms() was established\n      in our review only as an authentication gate over the dispatch, not as a\n      per-operation authorization matrix; and no principal short of full\n      administrator was demonstrated reaching ajax-ops=add. If a restricted\n      back-end account can create or update products, that account is the\n      least-privileged principal reaching the sink and PR:L is the faithful\n      metric, at Impact 5.87311872 plus Exploitability 2.83525473, base\n      8.70837345, rounded up. We did not round our rating up to it, because\n      doing so would assert a privilege model we did not observe.\n  - Elevated complexity, AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H = 6.6, and user\n      interaction, AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:H = 6.8. Both printed only\n      so the rejections are inspectable: there is no race, no ordering constraint\n      beyond one POST and one GET, no requirement that the target be in an\n      unusual state, and no victim action at any point in the chain.\n\nContributing weaknesses are reported and deliberately not scored into the vector:\nthe single-round SHA-1 mswEnc() credential transform, loose `==` comparisons on\nhash and token strings, the absence of any enforced rotation of the\ninstaller-provisioned secret, and the inconsistency between upload handlers inside\none shipped version. None of them lowers the privilege required to reach the sink\nand none raises the impact of the upload once it is reached. There is also no\nnumeric base score in our own record against this vector that could disagree with\nit, so no correction notice accompanies the figure.\n\nAuthentication: post-authentication administrator plus the session CSRF token, and\nboth gates were treated as things to attack rather than as configuration to trust.\nThere are no factory credentials in Maian Pal 2.1: the installer forces LG_USER,\nLG_PASS and SECRET_KEY to be set, `control/_cfg-sample.php:62` ships only the\nplaceholder text \"Your secret key value goes here\", and this is not a\ndefault-credential report. The login path was reviewed for a missing or permissive\npermission configuration, a route that skips the gate, a predictable CSRF token, a\npre-computable credential hash, a factory-credential fallback, a\ncomparison-timing difference and a secondary authentication branch, and none was\nfound; t"
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-434",
              "description": "CWE-434",
              "lang": "en",
              "type": "CWE"
            },
            {
              "cweId": "CWE-693",
              "description": "CWE-693",
              "lang": "en",
              "type": "CWE"
            },
            {
              "cweId": "CWE-78",
              "description": "CWE-78",
              "lang": "en",
              "type": "CWE"
            },
            {
              "cweId": "CWE-94",
              "description": "CWE-94",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-11-02T07:30:02Z",
        "orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
        "shortName": "VULNARCHIVE"
      },
      "references": [
        {
          "tags": [
            "technical-description",
            "exploit"
          ],
          "url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Oct/17"
        },
        {
          "tags": [
            "technical-description"
          ],
          "url": "https://seclists.org/fulldisclosure/2026/Oct/17"
        },
        {
          "url": "https://0day-rubbish.com"
        },
        {
          "url": "https://0day-rubbish.com/blog/maian-pal-product-image-upload-webshell-rce"
        },
        {
          "url": "https://github.com/Exploit-Garbage/0day-Rubbish"
        },
        {
          "url": "https://nmap.org/mailman/listinfo/fulldisclosure"
        },
        {
          "url": "https://seclists.org/fulldisclosure/"
        }
      ],
      "source": {
        "defect": [
          "https://seclists.org/fulldisclosure/2026/Oct/17"
        ],
        "discovery": "EXTERNAL"
      },
      "title": "[0day-rubbish] Maian Pal 2.1 product image upload with no extension allow-list to PHP webshell and www-data uid 33 code execution (7.2, PR:H)",
      "x_gcve": [
        {
          "recordType": "advisory",
          "relationships": [],
          "vulnId": "GCVE-1988-2026-0488",
          "x_vulnarchive": {
            "archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Oct/17",
            "automated": true,
            "contentSha256": "0b3e889b1e4a4dcd1911310cb807a8368fb210a07e78930cca78dfad7f6238a2",
            "evidenceScore": 11,
            "messageId": "",
            "originalUrl": "https://seclists.org/fulldisclosure/2026/Oct/17",
            "policy": "vulnarchive-1",
            "sourceFormat": "text/html",
            "sourcePublishedAt": "2026-10-13T02:22:02Z"
          }
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
    "assignerShortName": "VULNARCHIVE",
    "datePublished": "2026-11-02T07:30:02Z",
    "dateUpdated": "2026-11-02T07:30:02Z",
    "state": "PUBLISHED",
    "vulnId": "GCVE-1988-2026-0488"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
How durations are calculated

Following the VTEM framework (Black Hat USA 2015), time to patch starts when the vendor or a coordinator was informed, total time to patch at discovery, and disclosure to patch at public disclosure; vendor response time runs from the report to its acknowledgement. Time to exploit and time unpatched start at the earliest discovery or report, falling back to public disclosure. Unpatched time ends at the first recorded patch, or the calculation time when no patch is recorded. Exploitation to patch shows the interval between those two events; a published proof of concept is a public exploit, not exploitation.

Each result shows its source dates. A negative interval means the end event came first; when date-only inputs leave the order open, the result says so. Date-only inputs are approximate. The earliest evidence wins: KEV report dates and sightings are labelled as such. Records describing another vulnerability are listed but never calculated from, and a PoC alone does not establish exploitation. Missing patch evidence does not prove that no patch exists. Filters below change the event list only.

Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.