What we fixed in the 1.7.0 correctness release

Version 1.7.0 is mostly a correctness release, the same posture as 1.6.2 before it. It closes a race condition in OAuth revocation, stops a payment integration from leaking two credential fields, and fixes four ACF writes that were destroying content while reporting a result that did not match what happened. None of it changes who can do what. This post walks the five fixes worth knowing about if you run the plugin; the two new admin features, an Enable all writes button and a fuller audit log, are covered separately in what 1.7.0 adds.

A revoked OAuth grant could still redeem into a working token

OAuth authorization has two steps that do not have to happen back to back. First, an approval screen mints a short-lived authorization code. Second, whenever the client gets around to it, that code is redeemed for the token that lets it call the API. Revoking a grant in between is supposed to close that avenue off, whichever step it interrupts.

It did not, in one specific timing. If a request to authorize was already in flight when you clicked Revoke on the Connection tab, that request could still finish and hand back a valid code, because the code-minting step never checked whether a revoke had just landed. The wp-admin screen said the grant was gone. The client held a code that would still work.

The real failure was one step later. Redeeming that code for a token never re-checked consent either, so the token that came back kept working, indefinitely, exactly as if the revoke had never happened. 1.7.0 adds that check at redemption. A code minted a moment before a revoke can still exist, but it can no longer be exchanged for anything once the revoke has landed.

A revoked grant, still redeemed A four step timeline. Step one, an agent starts authorizing. Step two, you click Revoke in wp-admin and the screen confirms the access is gone. Step three, the request that was already in flight finishes anyway and mints an authorization code. Step four, the client redeems that code at the token endpoint. The timeline then splits in two. Before 1.7.0, redemption never re-checked consent, so a token was issued and kept working despite the revoke. In 1.7.0, redemption re-checks consent, so the redemption is refused and the revoke holds. STEP 1 An agent starts authorizing STEP 2 You click Revoke in wp-admin, and it confirms the access is gone STEP 3 The already in-flight request finishes anyway and mints a code STEP 4 The client redeems that code at the token endpoint BEFORE 1.7.0 Consent is not re-checked at redemption 1.7.0 Consent is re-checked at redemption Token issued anyway The revoke silently did not hold Redemption refused The revoke holds

A revoke that only takes effect the next time nobody happens to be mid-request is not a revoke. Redemption now re-checks consent every time, so the moment a grant is gone, so is every unredeemed code for it.

Payment gateway settings were returning credentials in the clear

aafm/wc-get-payment-gateway and aafm/wc-list-payment-gateways redact sensitive settings before an agent can read them back. Since 1.6.2’s redaction rework, that check has matched field names against a lowercase list, so a key like apikey or password gets caught wherever a gateway declares it.

It missed the two fields Authorize.Net declares: apiLoginID and transactionKey, both camelCase. A lowercase-only match against a camelCase field name never fires, so those two came back in full, unredacted, in a response that also claimed nothing had been withheld. 1.7.0 catches the real case. The output shape is unchanged; what is inside two of its fields is not.

Four ACF writes were destroying content and reporting the wrong result

  • A flexible-content write whose row layout ACF could not resolve reported failure, and wiped the field’s existing rows on the same call.
  • Clearing a field through an address that only nearly matched the field’s real name deleted the stored value, then reported failure.
  • The protected-meta check compared the address the caller sent rather than the one ACF would actually store under, so a trailing space was enough to slip past a floor meant to block it.
  • A sub-field write that landed under an undeclared name reported failure, even on calls where the write had actually gone through.

All four are refused up front now, before anything is written. A refusal that stops a write is a much smaller problem than a write that happens anyway while the tool insists it did not.

WooCommerce was counting refunds as orders

aafm/wc-count-orders answered with a single number that mixed orders and their own refunds together. A store with six real orders and three refunds against them reported nine, because a refund is itself a record WooCommerce keeps in the same table, and the ability’s query was not excluding it. 1.7.0 counts orders.

The same pass fixed two smaller WooCommerce bugs: a variation delete that had actually succeeded was reporting failure, and product-variation writes were being checked against a display filter’s view of the parent product rather than what WooCommerce had actually stored.

Invisible characters, stripped further

1.7.0 already stripped invisible bidi and control characters from media filenames and titles, the kind of characters that can make a filename read differently than it displays. This same release extends that strip to more of where text ends up in storage: WooCommerce fields, SEO fields, ACF fields, order addresses, and stored post text.

What this release is, and is not

None of the five fixes above change what an agent can do. They change whether an already-permitted action does what it says: a revoke that holds, credentials that stay redacted, a write that either lands cleanly or is refused, a count that counts the right thing. 1.7.0 also adds two admin features, covered in what 1.7.0 adds, and separately fixes two refusals that were blaming the wrong cause, covered in what we fixed: setting alt text said permission denied, for everyone. The full history is on the changelog page, and the current safety controls are on security.