Conversation
…e app names
The site's `Authorization` header was attached to every request the
editor made, whatever the host: iOS `EditorHTTPClient.configureRequest`,
Android `EditorHTTPClient.perform` and `download`, the manifest request
of Android's `org.wordpress.gutenberg.EditorAssetsLibrary`, and the web
editor's `tokenAuthMiddleware`. An asset on another party's host, or an
`apiFetch( { url } )` to another party's service, received the site's
credentials.
A request now carries the header when its origin (scheme, host and port)
is that of `siteURL` or `siteApiRoot`, or when it is over HTTPS and its
host matches an entry in the new `EditorConfiguration.authHeaderDomains`.
An entry is taken as written: `s0.wp.com` is that one host, and
`*.wp.com` is `wp.com` and every subdomain of it. The library infers
nothing about WordPress.com; both demo apps name `*.wp.com` and
`*.files.wordpress.com` for WordPress.com accounts.
The rule lives in `EditorAuthorizationScope` on iOS and Android and in
`isWithinAuthorizationScope` on the web, and `GBKitGlobal` carries
`authHeaderDomains` to the web editor. On the web, a request by `path`
is for the site's API and keeps the header; a request by `url` alone is
checked.
BREAKING CHANGE: both native `EditorHTTPClient` constructors take a
required `authorizationScope`. iOS gains
`EditorHTTPClient(configuration:)`, which derives it.
XCFramework BuildThis PR's XCFramework is available for testing. Add the following to your .package(url: "https://github.com/wordpress-mobile/GutenbergKit", branch: "pr-build/757")Built from 07ed4d6 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes a bug where the site's
Authorizationheader was attached to every request the editor made, whatever the host. A plugin script served from a vendor's CDN, or a block callingapiFetch( { url } )against another party's service, received the site's credentials.The header now goes to the site and its REST API, plus any hosts the app names in a new
authHeaderDomainsconfiguration option.This is a breaking change. Both native
EditorHTTPClientconstructors gain a requiredauthorizationScopeparameter. A GitHub code search finds no call to either constructor in WordPress-iOS or WordPress-Android.Which requests carry the header
A request carries it when either of these holds:
siteURLor ofsiteApiRoot.authHeaderDomains.Each entry is taken exactly as written:
s0.wp.coms0.wp.comonly — not its subdomains, notwp.com*.wp.comwp.comand every subdomain of it, at any depth*.com.comhostAn entry is ignored when it is empty, or has a
*anywhere but as the whole first label (.wp.com,s*.wp.com,*.*.com).An app that names nothing keeps working against its own site. The list is empty by default, and the first rule needs no configuration. Because it compares origins, a lookalike host (
https://example.com.vendor.net) and the site's own host overhttpare both refused.The library infers nothing about WordPress.com. A site reached through WordPress.com is served from more than its own address, so the app names those hosts:
*.wp.comand*.files.wordpress.com. Both demo apps do so for WordPress.com accounts, and name nothing for self-hosted sites.Changes
EditorConfiguration.authHeaderDomainson both platforms — iOS[String]withsetAuthHeaderDomains(_:), AndroidSet<String>— carried throughtoBuilder, equality, and hashing.EditorAuthorizationScopeon iOS and Android, andisWithinAuthorizationScopeinsrc/utils/authorization-scope.js. Each platform's copy of the rule lives in that one place.EditorHTTPClient.configureRequestand AndroidEditorHTTPClient.perform/downloadattach the header only within the scope. iOS gainsEditorHTTPClient(configuration:), whichEditorServiceandEditorViewControllernow use.org.wordpress.gutenberg.EditorAssetsLibrary, which opens its ownHttpURLConnectionrather than going throughEditorHTTPClient. A customeditorAssetsEndpointon another host no longer receives the header unless that host is named.tokenAuthMiddleware. A request bypathis for the site's API and keeps the header. A request byurlalone is checked.credentials: 'omit'is now set only when the header is attached.authHeaderDomainsto the web editor throughGBKitGlobal, so it applies the list the native side was configured with.docs/code/authorization.md, with a short section indocs/integration.md.jQuery AJAX requests (
src/utils/ajax.js) were already limited to the site's origin and are unchanged.What we explored
siteApiRootonpublic-api.wordpress.comas permission to send the token to*.wp.com. Rejected: it put WordPress.com host names in library code and made the library decide what a WordPress.com site is. The app already knows, so the app says.*.. Removed: iOS and the web view have no public-suffix list, so the rule refused*.combut accepted*.co.uk. A wildcard is taken at its word instead, and the docs say to name the narrowest domain that will do.Not in this PR
EditorHTTPClientProtocolimplementation adds whichever headers it likes.*.files.wordpress.comdoes not by itself make a private site's media display.authHeaderDomainsfor sites reached through WordPress.com when they take this release. Until they do, their token goes only to the site and topublic-api.wordpress.com.Test plan
swift test— 583 and 395 tests pass.make lint-iosreports no violations.EditorViewControllerchange, which the host build compiles out.detektis clean,:Gutenberg:testDebugUnitTestpasses 735 tests, and the demo app compiles.make test-web-unitpasses 369 tests in 25 files. ESLint and Prettier are clean.EditorHTTPClientTests: 6 issues, e.g.a request to another party's host goes out without the Authorization header.EditorHTTPClientAuthorizationTest:perform sends no Authorization header to another party's hostand itsdownloadtwin.EditorAssetsManifestAuthorizationTest:the manifest request sends no Authorization header to an endpoint on another party's host.api-fetch.test.js: 4 failures, e.g.should not send the auth header with a request by URL to a lookalike host.wp.comhosts.Neither demo-app step has been run yet — this PR has had no device, simulator, or E2E run.