The problem PAR solves
When you select Connect, the printer builds an authorization request and hands it to your browser to deliver. The authorization request lesson read that URL one parameter at a time: the scope, the return address, state, and the PKCE challenge. Every one of those values travels in the address bar, through your browser, before the photo service sees any of it.
That arrangement is simple, and it has served every flow so far. It also means the printer cannot control what happens to its request on the way, and the photo service only learns for certain which client sent it at the very end, when the printer exchanges the code.
A request in plain sight
Earlier lessons kept tokens out of addresses for good reason. As Using access tokens explained, a URL is kept in browser history, written to server and proxy logs, and can be passed to other sites in the Referer header. An authorization request is a URL too, so everything in it is exposed in the same ways.
For the printer's request, that exposure is tolerable. The scope and return address are not secrets, and the PKCE challenge is designed to be seen. Other requests carry more. A request might include your email address so the sign-in page can fill it in, or describe a payment you are about to approve, with an amount and a recipient. Those details then sit wherever the URL was recorded.
A URL also has to fit. Browsers, web servers, and proxies all limit the length of an address, and their limits differ. Requests that describe access in detail can grow past what some part of the path will accept, and the failure then appears somewhere the printer cannot see.
A request anyone can change
Redirect URI validation began with an attacker writing an authorization request of their own. The printer's client ID is public, so anyone can build a URL that names photo-printer. Exact matching kept that attacker from choosing the return address, and the photo service checks the other parameters against the printer's registration as well, so a scope the printer may not request is refused too.
Within those limits, though, the service cannot tell which values the printer chose. If the printer is registered for both photos.read and albums.create, a request edited to ask for both looks just as legitimate as one the printer built. The edit can come from a malicious browser extension that rewrites the address on its way, or from an attacker who starts a connection in their own browser and changes the request before sending it on. For a request that names a payment, an edit could change the amount or the recipient, and the person approving it might not notice.
A request written from scratch fares no better. Sent to you in a message, it would show the photo service's familiar consent screen, with the printer's name on it, for a request the printer never made.
Checks that come too late
The Client authentication methods lesson explained why the authorization request carries no client credential: it travels through a browser, where a credential would be exposed. The consequence is that the first time the photo service can confirm the printer's identity is the token request, after you have signed in and approved the connection.
By then, a request that should never have been accepted has already put a sign-in page and a consent screen in front of you. If the service finds a problem it can report, it sends your browser back to the printer with an error, which means another round trip through the browser just to say that the request was bad.
Sending the request directly
Pushed Authorization Requests, usually called PAR and published as RFC 9126 in 2021, change the route the request takes. The printer's backend sends the authorization request parameters straight to the photo service in an HTTPS POST, to a new endpoint for this purpose, and authenticates exactly as it does at the token endpoint. The service checks the client and the request, stores the request, and returns a short-lived reference to it, called a request URI. The browser then carries only the client ID and that reference.
| Weakness | With a pushed request |
|---|---|
| Parameters visible and recorded in the browser | The browser carries an opaque reference instead of the parameters. |
| Parameters changed or forged in the browser | The parameters never pass through the browser, and only the authenticated printer can push a request in its name. |
| Requests too long for a URL | The request travels in a POST body, and the URL stays short whatever the request contains. |
| Client verified only at the token request | The client authenticates before you see any page, so the service can refuse a bad request without involving you. |
PAR changes the request, not the rest of the flow. The authorization response still returns through your browser with a code, state, and iss, and the printer checks it as before. The code exchange is unchanged. The reference itself also travels through the browser, which is why it works only briefly, only once, and only for the client that pushed it.