Page MenuHomePhabricator

Missing CSRF token in scribunto api console
Closed, ResolvedPublic

Description

From pentest: ApiScribuntoConsole (action=scribunto-console) does not require a CSRF token.

Looking at it right now, it also accepts GET requests.

I'm not sure this is an actual issue:

  • Scribunto sessions are extremely ephemeral.
  • What would an attacker even gain by messing with someone's scribunto debug session?
  • Each session has a 31 bit (non-cryptographically secure. i.e. generated via mt_rand()) random identifier associated with it. The attacker would have to be able to guess this. Given its only 31 bits, and its not securely generated, this isn't outside the realm of possibility, but it also makes things harder to pull off.

That said, no harm in doing things properly. So I think we should do the normal, require CSRF token and make this module must POST.

Event Timeline

Anomie triaged this task as Low priority.EditedDec 17 2018, 2:35 PM
Anomie subscribed.

I'm not sure this is an actual issue:

I don't think it is.

  • Scribunto sessions are extremely ephemeral.

Indeed. It's not saved anywhere persistent client-side so it's gone as soon as the person leaves or reloads the page, plus it's thrown away if the user clicks the "Clear" button or changes the textarea in the edit form.

  • What would an attacker even gain by messing with someone's scribunto debug session?

The "session" here is just the history of commands previously typed into the console and a copy of the previous value of the content parameter, so they don't have to be repeated for every request. The best an attacker could do would be to screw up the Lua code being run, either to confuse someone or to hope they're going to copy-paste output.

  • Each session has a 31 bit (non-cryptographically secure. i.e. generated via mt_rand()) random identifier associated with it. The attacker would have to be able to guess this. Given its only 31 bits, and its not securely generated, this isn't outside the realm of possibility, but it also makes things harder to pull off.

Note the cache key also includes the user's ID. So the attacker would either have to also be able to spoof the user somehow or restrict the attack to people using the console while logged out.

We generally require POSTs and CSRF tokens for actions that actually write the wiki. This doesn't, other than that ephemeral state cache.

@sbassett, @Reedy: two questions, 1) this seems very unexploitable, can we make it public? 2) Do you all have an opinion on whether this should require a CSRF token? It's an internal API module so we can make the change without having to bother with the breaking change process.

  1. this seems very unexploitable, can we make it public?

Given @Bawolff and Anomie's reasoning above, I think that's fine.

  1. Do you all have an opinion on whether this should require a CSRF token? It's an internal API module so we can make the change without having to bother with the breaking change process.

IMO if we're going to expend energy to fix an issue like this, we should just go ahead and require the token unless there is fear that it will break several existing workflows, etc. Digging around in turnilo, it seems action=scribunto-console endpoints get a pretty small amount of traffic each month, like under 2k hits, most likely.

sbassett lowered the priority of this task from Low to Lowest.Sep 27 2022, 5:07 PM
sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".

Change 836962 had a related patch set uploaded (by Legoktm; author: Legoktm):

[mediawiki/extensions/Scribunto@master] Require CSRF token for action=scribunto-console

https://gerrit.wikimedia.org/r/836962

https://meta.wikimedia.org/w/index.php?title=Tech%2FNews%2F2022%2F40&type=revision&diff=23872498&oldid=23871998

I'm pretty concerned that there are gadgets that are calling this API :/ will file a separate task for obsoleting libLua.js.

Anyways, I double-checked, passing the token when it's not needed just results in an API warning:

"warnings": {
  "main": {
    "*": "Unrecognized parameter: token."
  }
},

so it's safe for people to update to using .postWithToken( 'csrf', params ) ASAP.

Change 836962 merged by jenkins-bot:

[mediawiki/extensions/Scribunto@master] Require CSRF token for action=scribunto-console

https://gerrit.wikimedia.org/r/836962

Not planning to do any backports given the low risk balanced with changing an API.