Skip to content

v5.3.2 — security hardening

Choose a tag to compare

@niranz-dev niranz-dev released this 19 Aug 06:20
· 51 commits to main since this release

Six ways the OAuth server could have been used against a site, closed. If you
are running 5.3.0 or 5.3.1, update.

The connect screen could be framed

It carries a button that hands a stranger's terminal everything the person
clicking it can do, and the code being approved arrives in the URL — so an
invisible frame over a page an attacker controls turns one click into an
administrator token. A nonce is no defence here: clickjacking does not forge a
request, it borrows a real one from a real user, and every check passes.

Every admin screen this plugin adds now sends X-Frame-Options: DENY and
Content-Security-Policy: frame-ancestors 'none', from load-{hook} — the
first attempt sent them from the render callback, where WordPress has already
printed the document and headers go nowhere.

Switching abilities off left issued tokens working

A bearer token does not merely reach this plugin; it makes the request an
administrator, and posts, users, media and plugins all answer to that. The
switch now holds in authenticate(), which also brings tokens under the domain
lock — a database restored elsewhere no longer arrives with working credentials.

Rotation could end a connection over one lost packet

The old refresh token was destroyed before the new pair had been delivered, so
any dropped response left the client holding a token that no longer existed.

A spent token now answers an honest retry for two minutes. After that it is
treated as theft: presenting it revokes every token descended from the same
approval, since cutting only the token presented would leave whoever took it
still connected.

Also

  • The plaintext device code is no longer stored as the value of the user-code
    transient
  • The endpoints that must be open to strangers are metered per address
  • Registration can no longer evict a working client to make room for a stranger
  • No credential is issued over plain HTTP
  • last_used is written at most once a minute instead of on every request,
    which was a database write per call racing with rotation over the same row

Verifying

sha256  cea0e01bdec6a93470874efa5404e81bc04d0309a7ecbbba1bc64137a2e54d20

Install: Plugins → Add New Plugin → Upload Plugin → Replace current with
uploaded
. Do not deactivate and delete — deleting runs the uninstaller, which
removes your settings, the domain lock and the recovery guard.