Page MenuHomePhabricator

404 error when using action=raw on an admin-level hidden revision
Open, MediumPublicBUG REPORT

Description

Steps to replicate the issue (include links if applicable):

What happens?:

Request from [redacted] via cp1108 cp1108, Varnish XID 701040496
Upstream caches: cp1108 int
Error: 404, Not Found at Tue, 21 Nov 2023 03:01:56 GMT

What should have happened instead?:

  • If unhide=1 is included in the URL and the viewer has the needed permissions, the content should be shown
  • Otherwise a mediawiki error should be shown instead of at the upstream stage

Software version (skip for WMF-hosted wikis like Wikipedia):

Other information (browser name/version, screenshots, etc.):

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript
DannyS712 updated the task description. (Show Details)
DannyS712 moved this task from Unsorted to Reports on the User-DannyS712 board.

If Traffic is not appropriate please let me know

Seems expected that the revision-deleted content is not shown as there is a comment in RawAction

// Public-only due to cache headers

But you right that the 404 from action=raw showing the wrong (error) page (Error - Our servers are currently under maintenance or experiencing a technical problem. Please try again in a few minutes See the error message at the bottom of this page for more information.),

As far as I can tell this is MW serving a blank page:

taavi@deploy2002 ~ $ curl -v --connect-to ::mw-web.discovery.wmnet:4450 "https://www.mediawiki.org/w/index.php?title=User:DannyS712/sandbox&oldid=6207359&action=raw"
* Uses proxy env variable no_proxy == 'wikipedia.org,wikimedia.org,wikibooks.org,wikinews.org,wikiquote.org,wikisource.org,wikiversity.org,wikivoyage.org,wikidata.org,wikiworkshop.org,wikifunctions.org,wiktionary.org,mediawiki.org,wmfusercontent.org,w.wiki,wikimediacloud.org,wmnet,127.0.0.1,::1'
* Connecting to hostname: mw-web.discovery.wmnet
* Connecting to port: 4450
*   Trying 10.2.1.75:4450...
* Connected to mw-web.discovery.wmnet (10.2.1.75) port 4450 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=mediawiki-main-tls-proxy-certs
*  start date: Nov 19 20:56:00 2025 GMT
*  expire date: Dec 17 20:56:00 2025 GMT
*  subjectAltName: host "www.mediawiki.org" matched cert's "*.mediawiki.org"
*  issuer: C=US; L=San Francisco; O=Wikimedia Foundation, Inc; OU=SRE Foundations; CN=discovery
*  SSL certificate verify ok.
> GET /w/index.php?title=User:DannyS712/sandbox&oldid=6207359&action=raw HTTP/1.1
> Host: www.mediawiki.org
> User-Agent: curl/7.74.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< date: Wed, 03 Dec 2025 18:40:46 GMT
< server: mw-web.codfw.main-78dd885bd6-rdrgr
< x-powered-by: PHP/8.3.26
< x-content-type-options: nosniff
< content-security-policy: default-src 'self'; script-src 'none'; object-src 'none'
< vary: Accept-Encoding,X-Subdomain,Cookie,Authorization
< cache-control: public, s-maxage=0, max-age=1209600
< traceparent: 00-24245b4fcba3a33764d2c01fa3ba782f-c9d7b65c49cacf2c-00
< x-request-id: e57e9104-f0fa-4b7d-b387-d1a2f2d54f3f
< last-modified: Tue, 21 Nov 2023 02:58:50 GMT
< backend-timing: D=51247 t=1764787246163783
< content-length: 0
< content-type: text/x-wiki; charset=UTF-8
< x-envoy-upstream-service-time: 51
< 
* Connection #0 to host mw-web.discovery.wmnet left intact

(note the content-type: text/x-wiki; charset=UTF-8 header!)

BPirkle triaged this task as Medium priority.Dec 4 2025, 4:42 PM
BPirkle moved this task from Incoming (Needs Triage) to Bugs & Chores on the MW-Interfaces-Team board.

@Krinkle -- do you have any thoughts about this? We chatted about this in MWI, but it's unclear if action=raw is still required, and in what scenarios. We're also having a hard time reproducing the specific issue described; we are seeing a blank 404 page, but that seems to be expected behavior?

action=raw is the backend for importScript and importScriptURI which is the officially supported way to load user scripts (Wikipedia, mediawiki.org). It is very much required, used, and depended on by thousands of critical workflows and gadgets across the wikis.

It is indeed expected that it returns a blank for pages titles that don't exist, that don't match the requested content model, or otherwise are pages not permitted to be loaded through this mechanism (usually for security or performance reasons).

Revision are usually hidden for a reason, and allowing them to be loaded this way would break caching, but also risk compromising the most sensitive users (i.e. admins that can view hidden revisions).

  • If unhide=1 is included in the URL and the viewer has the needed permissions, the content should be shown

There exists no such parameter in action=raw. There is however an unhide parameter in the action=view user interface.

action=raw is not an API to retreive wikitext content of arbitrary revisions. For that, you can use the Action API. This works for hidden revisions as well (if you're logged-in and have the relevant permissions).

const resp = await fetch('https://www.mediawiki.org/w/api.php?' + new URLSearchParams({
  format: 'json',
  formatversion: '2',
  action: 'query',
  page: 'User:DannyS712/sandbox',
  revids: '6207359',
  prop: 'revisions',
  rvprop: 'content',
}));
const data = await resp.json();
console.log(data.query.pages[0].revisions[0].content);

Given that:

  • The use case is a custom script where the API can be called (i.e. not a native HTML reference to JS or CSS assets, where a raw response is required).
  • There is an API for this.
  • It has never been supported.
  • Supporting it may break compatibility with scripts that assume current responses for private/non-existing content.
  • Supporting it would reduce security by enabling compromise through past revisions.
  • Supporting it would reduce performance and move us a step back toward enabling CDN caching (T279120).

I believe this should be declined.