pachli / pachli-android

The Pachli Android app
https://pachli.app
GNU General Public License v3.0
86 stars 13 forks source link

Logging in to social.tchncs.de logs in in the browser frame #210

Open nikclayton opened 8 months ago

nikclayton commented 8 months ago

Describe the bug

Can't log in to social.tchncs.de.

To Reproduce Steps to reproduce the behavior:

  1. Have an account on social.tchncs.de
  2. Log in to a new account in Pachli by: a. Enter "social.tchncs.de" as the server b. Enter the username and password in the browser when prompted

Expected behavior

It should prompt to authorize the app, and then go back to the Pachli UI. Instead, the user stays in the browser and is shown the social.tchncs.de web UI.

Links

See the thread starting at https://mastodon.social/deck/@kentborg@social.tchncs.de/111313970864414061

Versions

Reproduces in 1.3 and Current (at the time of writing).

social.tchncs.de is running Mastodon v4.2.1

Affirmation I have checked other issues for this project (open and closed) and I cannot find one that matches the problem I am reporting.

nikclayton commented 8 months ago

Not just a Pachli problem, this manifests in the Mastodon Android client, Megalodon, Tusky, and Trunks.

When trying to login to a new account what normally happens is:

  1. Prompted for the server (in Pachli), then...
  2. Redirected to the server's log in page, enter the username and password
  3. Redirected to the server's "Do you want to authorize this app" page
  4. Finally redirected to the oauth2redirect URL, where the auth token can be fetched.

For logging in to mastodon.ie this looks like the following URLs:

Logging in to social.tchncs.de skips the third step -- there's no "Do you authorize this app?" interstitial to click through, and the URLs the browser sees are:

There should be a https://social.tchncs.de/oauth/authorize?... URL in between those two.

So Pachli never gets the auth code. Ditto for the other Android clients.

nikclayton commented 8 months ago

Started a discussion with the social.tchncs.de admins on Mastodon to try and figure out what's going on.

piratenpanda commented 6 months ago

Same here on hessen.social for both tusky and pachli

nikclayton commented 3 months ago

Pinged the social.tchncs.de admins again.

nikclayton commented 3 months ago

Collating relevant issues:

nikclayton commented 3 months ago

In the meantime, what seems to work is:

  1. Try and login with Pachli (i.e., add an account, enter "social.tchncs.de" in the "Which instance?" box, and enter your username and password when prompted
  2. You remain in the webview, and see the web timeline
  3. Press "Back" until you are back at the Pachli login screen from step 1, "social.tchncs.de" should still be in the "Which instance?" box
  4. From the "..." menu at the top right choose "Login with Browser"
  5. This should show you the screen asking you to authorise Pachli. Do that, and the login should complete.
ThisIsMissEm commented 3 months ago

The flow here you have isn't entirely correct..

The issue in https://github.com/mastodon/mastodon/issues/26535 is that data from a previous OAuth flow persists outside of that flow, as far as I understand it.

ThisIsMissEm commented 3 months ago

@nikclayton I was looking into Pachli's code, and noticed that you don't seem to use the (from what I can tell) recommended AccountManager APIs — https://developer.android.com/training/id-auth/authenticate

Instead you're using a custom WebView to perform the authentication in, which should work, though I'm not sure exactly how this may handle cookies and redirects — perhaps there's an issue in here, which means that Mastodon doesn't receive back the cookie saying "redirect from /auth/sign_in back to /oauth/authorize?..." ?

nikclayton commented 3 months ago

@ThisIsMissEm Yeah, this is inherited code that I haven't got around to cleaning up yet. I'm going to throw together a proof of concept small app that does use the AccountManager APIs to rule that out (or, possibly, in).

In the meantime I just tested the latest release of Fedilab, which exhibits the same problem. codeberg doesn't have search though, so it's a pain trying to track down what that's using...

ThisIsMissEm commented 3 months ago

@nikclayton it seems to use a CustomTab (maybe by default) or an intent: https://codeberg.org/tom79/Fedilab/src/branch/main/app/src/main/java/app/fedilab/android/ui/fragment/FragmentLoginMain.java#L302-L320

nikclayton commented 3 months ago

@ThisIsMissEm Looking at this some more, I'm not sure the AccountManager APIs are the correct ones to use.

Reading https://developer.android.com/training/id-auth/custom_auth that starts with

So far we've talked about accessing Google APIs, which use accounts and users defined by Google. If you have your own online service, though, it won't have Google accounts or users, so what do you do? It turns out to be relatively straightforward to install new account types on a user's device. This lesson explains how to create a custom account type that works the same way as the built-in accounts do.

which sounds promising. However, it then says:

The first thing you'll need is a way to get credentials from the user. This may be as simple as a dialog box that asks for a name and a password. Or it may be a more exotic procedure like a one-time password or a biometric scan.

I think that's bad practice, for a couple of reasons.

  1. Pachli shouldn't be asking the user for their Mastodon account details; it's training users to provide those credentials somewhere other than their web browser.

  2. If the user is already logged in in their browser that'll be re-used, instead of the user needing to enter credentials again (if they use the "Login with browser" option)

In an ideal world Pachli wouldn't use a WebView either, it would use browser custom tabs -- Google banned using a webview for login to Google accounts with https://developers.googleblog.com/2021/06/upcoming-security-changes-to-googles-oauth-2.0-authorization-endpoint.html

However, some browsers do not work well with custom tabs, per

which is why Tusky (where this code originated from) switched to webview by default.

https://github.com/tuskyapp/Tusky/issues/3316 is a recent counter point, and maybe it's time to switch back.

https://dev.to/theplebdev/oauth20-and-android-login-with-github-and-get-the-authorization-code-40n3 has a decent description of what I think is supposed to happen.

ThisIsMissEm commented 3 months ago

The dev.to article matches what I'd expect, but my assumption/understanding was that AccountManager would be like that new iOS "sign in with ..." browser frame thing — ASWebAuthenticationSession

The Auth0 SDK for android also uses this intents thing: https://github.com/auth0/Auth0.Android/blob/main/auth0/src/main/AndroidManifest.xml

Maybe that's a place to start?

ThisIsMissEm commented 3 months ago

The reason I'm thinking this is a bug specific to Android is because we're only receiving reports of issues with OAuth 2.0 flows from android, not yet from iOS — the other conflated issues in that ticket https://github.com/mastodon/mastodon/issues/26535 were related to how those web applications were performing authentication. (e.g., already being authenticated for the logged in user so the authorization redirect happening "silently" when the user expected the authorize / reject prompt screen, because force_login wasn't true).

I have seen some issues with the session cookie / devise & doorkeeper where post completion of one oauth flow a session cookie from the previous exists still so weird stuff happens within mastodon. But I don't think that's what's happening here, as you explicitly clear cookies & it happens on every sign-in — the issue I describe here I don't yet have a good reproduction case.

nikclayton commented 3 months ago

I think the Android stuff is a red herring, I can reproduce the problem 100% of the time in Firefox on the desktop.

Do this once:

Register an app, by POST to https://social.tchncs.de/api/v1/apps with the following form parameters: (I use https://restfox.dev for this).

client_name : niktest redirect_uris: urn:ietf:wg:oauth:2.0:oob

This returns

{
    "id": "180303",
    "name": "niktest",
    "website": null,
    "redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
    "client_id": "3O564i0P3W9k3qN0dWL2iJpbD90W6G4HR9OulatuGS8",
    "client_secret": "REDACTED",
    "vapid_key": "REDACTED"
}

Then:

Step 1.

Open https://social.tchncs.de, and ensure I am logged out.

Step 2.

Attempt to authorize the app by going to: https://social.tchncs.de/oauth/authorize?client_id=3O564i0P3W9k3qN0dWL2iJpbD90W6G4HR9OulatuGS8&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code

Step 3.

I am prompted for username and password. I enter them.

Step 4.

Problem: At this point I am supposed to be shown the "Authorize this app" page, with the "Authorize" and "Deny" buttons. I am not, I am shown the normal Mastodon UI with my home timeline, the "This is your home base within Mastodon" message, etc.

Step 5.

If I open a second tab, and re-enter the URL from step 2 I am prompted to authorize/deny the app. If I click "Authorize" it shows me the authorization code (as expected, because I used redirect_uri=urn:ietf...).


If I do the same sequence on mastodon.social then it works -- at step 4 I am, as expected, prompted to authorize/deny the app.

ThisIsMissEm commented 3 months ago

I did just notice that social.tchncs.de is sending two referrer-policy headers, which is unexpected (I can't reproduce elsewhere)

Screenshot 2024-04-03 at 16 13 38

mastodon.ie isn't, so that's possibly not the source of the bug, but would impact Mastodon because the referrer header is used to track where to return users back to.

ThisIsMissEm commented 3 months ago

@nikclayton do you have "do not track" enabled? Or any other settings that may mess with the referer header?

nikclayton commented 3 months ago

I can reproduce the issue by opening https://social.tchncs.de/oauth/authorize?client_id=3O564i0P3W9k3qN0dWL2iJpbD90W6G4HR9OulatuGS8&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code in Chrome on Android (when logged out of social.tchncs.de) with and without Chrome's "Do not track" privacy option set.

I don't have any plugins installed in Chrome on Android, so I don't believe the referer header is being modified.

I'll be able to check the Firefox config tomorrow.

nikclayton commented 3 months ago

@ThisIsMissEm Firefox, in a private browsing window, with "Do not track" disabled.

  1. Open https://social.tchncs.de/oauth/authorize?client_id=3O564i0P3W9k3qN0dWL2iJpbD90W6G4HR9OulatuGS8&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code

Request headers:

GET /oauth/authorize?client_id=3O564i0P3W9k3qN0dWL2iJpbD90W6G4HR9OulatuGS8&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code HTTP/2
Host: social.tchncs.de
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache

Response from social.tchncs.de is a 302 to https://social.tchncs.de/auth/sign_in, and has, as you note, two different "referrer-policy" headers, same-origin and strict-origin.

Full response headers:

HTTP/2 302 
server: nginx
date: Thu, 04 Apr 2024 08:36:23 GMT
content-type: text/html; charset=utf-8
x-frame-options: DENY
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: same-origin
location: https://social.tchncs.de/auth/sign_in
cache-control: private, no-store
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://social.tchncs.de; img-src 'self' https: data: blob: https://social.tchncs.de; style-src 'self' https://social.tchncs.de 'nonce-pGb/htQJfCe7QtJr+BBmoQ=='; media-src 'self' https: data: https://social.tchncs.de; frame-src 'self' https:; manifest-src 'self' https://social.tchncs.de; form-action 'self'; child-src 'self' blob: https://social.tchncs.de; worker-src 'self' blob: https://social.tchncs.de; connect-src 'self' data: blob: https://social.tchncs.de https://f2.tchncs.de wss://social.tchncs.de; script-src 'self' https://social.tchncs.de 'wasm-unsafe-eval'
set-cookie: _mastodon_session=6CR...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
x-request-id: 58963dd2-fcde-4c7f-af99-caf3e86316d1
x-runtime: 0.001739
strict-transport-security: max-age=63072000; includeSubDomains
referrer-policy: strict-origin
X-Firefox-Spdy: h2
  1. GET https://social.tchncs.de/auth/sign_in

Full request headers:

GET /auth/sign_in HTTP/2
Host: social.tchncs.de
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: _mastodon_session=6CR...[REDACTED]
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache

Full response headers

HTTP/2 200 
server: nginx
date: Thu, 04 Apr 2024 08:36:23 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
x-frame-options: DENY
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: same-origin
link: </packs/js/locale/en-json-255639d1480034924027.chunk.js>; rel=preload; as=script; type=text/javascript; integrity=sha256-FCM+Kj6HylH+OPy86SxB6le/Yn+u+qOOGeJk2kKCzWA=
cache-control: private, no-store
etag: W/"dab275de0d7441713f7ba517a913db01"
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://social.tchncs.de; img-src 'self' https: data: blob: https://social.tchncs.de; style-src 'self' https://social.tchncs.de 'nonce-7RxsMekarQFxzVVISn3rKA=='; media-src 'self' https: data: https://social.tchncs.de; frame-src 'self' https:; manifest-src 'self' https://social.tchncs.de; child-src 'self' blob: https://social.tchncs.de; worker-src 'self' blob: https://social.tchncs.de; connect-src 'self' data: blob: https://social.tchncs.de https://f2.tchncs.de wss://social.tchncs.de; script-src 'self' https://social.tchncs.de 'wasm-unsafe-eval'
set-cookie: _mastodon_session=HO5...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
x-request-id: 772449d6-e9ea-4884-a382-3b9f07eac3f6
x-runtime: 0.006030
strict-transport-security: max-age=63072000; includeSubDomains
content-encoding: gzip
referrer-policy: strict-origin
X-Firefox-Spdy: h2

Possibly of interest -- this response sets a different _mastodon_session cookie value than the first response.

  1. Enter a username and password in to the form, and submit. As before I am not prompted to authorize the app, but sent straight to the timeline.

POST https://social.tchncs.de/auth/signin, which 302 redirects to https://social.tchncs.de/

Request headers:

POST /auth/sign_in HTTP/2
Host: social.tchncs.de
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://social.tchncs.de/
Content-Type: application/x-www-form-urlencoded
Content-Length: 207
Origin: https://social.tchncs.de
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: _mastodon_session=HO5...[REDACTED]
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache

Response headers:

HTTP/2 302 
server: nginx
date: Thu, 04 Apr 2024 08:44:55 GMT
content-type: text/html; charset=utf-8
x-frame-options: DENY
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: same-origin
location: https://social.tchncs.de/
cache-control: private, no-store
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://social.tchncs.de; img-src 'self' https: data: blob: https://social.tchncs.de; style-src 'self' https://social.tchncs.de 'nonce-3hWs7YWj4cMlV7aTtpzPXQ=='; media-src 'self' https: data: https://social.tchncs.de; frame-src 'self' https:; manifest-src 'self' https://social.tchncs.de; form-action 'self'; child-src 'self' blob: https://social.tchncs.de; worker-src 'self' blob: https://social.tchncs.de; connect-src 'self' data: blob: https://social.tchncs.de https://f2.tchncs.de wss://social.tchncs.de; script-src 'self' https://social.tchncs.de 'wasm-unsafe-eval'
set-cookie: _session_id=eyJ...[REDACTED]; path=/; expires=Fri, 04 Apr 2025 08:44:55 GMT; HttpOnly; SameSite=Lax; secure
set-cookie: _mastodon_session=FX9...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
x-request-id: b84f428a-c0ba-4f60-bbd2-abcfec7c4bc9
x-runtime: 0.072738
strict-transport-security: max-age=63072000; includeSubDomains
referrer-policy: strict-origin
X-Firefox-Spdy: h2
nikclayton commented 3 months ago

Now the same thing, but after logging in, in a new tab in the same private browsing window.

  1. Open https://social.tchncs.de/oauth/authorize?client_id=3O564i0P3W9k3qN0dWL2iJpbD90W6G4HR9OulatuGS8&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code

Request headers:

GET /oauth/authorize?client_id=3O564i0P3W9k3qN0dWL2iJpbD90W6G4HR9OulatuGS8&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code HTTP/2
Host: social.tchncs.de
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: _mastodon_session=V6A...[REDACTED]
_session_id=eyJ...[REDACTED]
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache
TE: trailers

Response is a 200 with the following headers:

HTTP/2 200 
server: nginx
date: Thu, 04 Apr 2024 08:50:47 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
x-frame-options: DENY
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: same-origin
link: </packs/js/locale/en-json-255639d1480034924027.chunk.js>; rel=preload; as=script; type=text/javascript; integrity=sha256-FCM+Kj6HylH+OPy86SxB6le/Yn+u+qOOGeJk2kKCzWA=
cache-control: private, no-store
etag: W/"76ba33087f0bc8b82596c556f2c2f4c9"
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://social.tchncs.de; img-src 'self' https: data: blob: https://social.tchncs.de; style-src 'self' https://social.tchncs.de 'nonce-/x5L1lNFud/SBJZzdG7hlw=='; media-src 'self' https: data: https://social.tchncs.de; frame-src 'self' https:; manifest-src 'self' https://social.tchncs.de; child-src 'self' blob: https://social.tchncs.de; worker-src 'self' blob: https://social.tchncs.de; connect-src 'self' data: blob: https://social.tchncs.de https://f2.tchncs.de wss://social.tchncs.de; script-src 'self' https://social.tchncs.de 'wasm-unsafe-eval'
set-cookie: _session_id=eyJ...[REDACTED]; path=/; expires=Fri, 04 Apr 2025 08:50:47 GMT; HttpOnly; SameSite=Lax; secure
set-cookie: _mastodon_session=icy...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
x-request-id: 2c2b16e7-9a16-499e-89ef-8790d9503cb1
x-runtime: 0.010265
strict-transport-security: max-age=63072000; includeSubDomains
content-encoding: gzip
referrer-policy: strict-origin
X-Firefox-Spdy: h2
  1. Click the "Authorize" button, which POSTs to https://social.tchncs.de/oauth/authorize

Request headers

POST /oauth/authorize HTTP/2
Host: social.tchncs.de
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://social.tchncs.de/
Content-Type: application/x-www-form-urlencoded
Content-Length: 253
Origin: https://social.tchncs.de
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: _mastodon_session=icy...[REDACTED]
_session_id=eyJ...[REDACTED]
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache

Response headers:

HTTP/2 302 
server: nginx
date: Thu, 04 Apr 2024 08:53:56 GMT
content-type: text/html; charset=utf-8
x-frame-options: DENY
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: same-origin
location: https://social.tchncs.de/oauth/authorize/native?code=e0f...[REDACTED]
cache-control: private, no-store
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://social.tchncs.de; img-src 'self' https: data: blob: https://social.tchncs.de; style-src 'self' https://social.tchncs.de 'nonce-MyR4yI3nCwkfvabnQP4wNg=='; media-src 'self' https: data: https://social.tchncs.de; frame-src 'self' https:; manifest-src 'self' https://social.tchncs.de; child-src 'self' blob: https://social.tchncs.de; worker-src 'self' blob: https://social.tchncs.de; connect-src 'self' data: blob: https://social.tchncs.de https://f2.tchncs.de wss://social.tchncs.de; script-src 'self' https://social.tchncs.de 'wasm-unsafe-eval'
set-cookie: _session_id=eyJ...[REDACTED]; path=/; expires=Fri, 04 Apr 2025 08:53:56 GMT; HttpOnly; SameSite=Lax; secure
set-cookie: _mastodon_session=Ku0...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
x-request-id: a20e3b9e-4e82-48c6-84c4-16077e5fcd59
x-runtime: 0.009237
strict-transport-security: max-age=63072000; includeSubDomains
referrer-policy: strict-origin
X-Firefox-Spdy: h2
  1. Get the page to show the application auth code, https://social.tchncs.de/oauth/authorize/native?code=e0f...[REDACTED]

Request headers

GET /oauth/authorize/native?code=e0f...[REDACTED] HTTP/2
Host: social.tchncs.de
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://social.tchncs.de/
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: _mastodon_session=Ku0...[REDACTED]
_session_id=eyJ...[REDACTED]
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache
TE: trailers

Response headers

HTTP/2 200 
server: nginx
date: Thu, 04 Apr 2024 08:53:56 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
x-frame-options: DENY
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: same-origin
link: </packs/js/locale/en-json-255639d1480034924027.chunk.js>; rel=preload; as=script; type=text/javascript; integrity=sha256-FCM+Kj6HylH+OPy86SxB6le/Yn+u+qOOGeJk2kKCzWA=
cache-control: private, no-store
etag: W/"5c04bd3636a12bceecae53cb7fa96916"
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://social.tchncs.de; img-src 'self' https: data: blob: https://social.tchncs.de; style-src 'self' https://social.tchncs.de 'nonce-eWH/TRR/J5g55smpnKc/9g=='; media-src 'self' https: data: https://social.tchncs.de; frame-src 'self' https:; manifest-src 'self' https://social.tchncs.de; child-src 'self' blob: https://social.tchncs.de; worker-src 'self' blob: https://social.tchncs.de; connect-src 'self' data: blob: https://social.tchncs.de https://f2.tchncs.de wss://social.tchncs.de; script-src 'self' https://social.tchncs.de 'wasm-unsafe-eval'
set-cookie: _session_id=eyJ...[REDACTED]; path=/; expires=Fri, 04 Apr 2025 08:53:56 GMT; HttpOnly; SameSite=Lax; secure
set-cookie: _mastodon_session=2oY...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
x-request-id: faf5ea3e-48f3-4e85-8e64-708d626c6164
x-runtime: 0.006383
strict-transport-security: max-age=63072000; includeSubDomains
content-encoding: gzip
referrer-policy: strict-origin
X-Firefox-Spdy: h2
nikclayton commented 3 months ago

Now trying the same thing as https://github.com/pachli/pachli-android/issues/210#issuecomment-2036571145 (i.e., try and authorize the app starting from a logged out state), but with mastodon.social.

  1. https://mastodon.social/oauth/authorize?client_id=lAqIYHpjr49PDd9GddJJ7ZlTzo4fJEioTouGdJ-6uuM&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code

Request headers:

GET /oauth/authorize?client_id=lAqIYHpjr49PDd9GddJJ7ZlTzo4fJEioTouGdJ-6uuM&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code HTTP/3
Host: mastodon.social
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: _mastodon_session=ExY...[REDACTED]
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache
TE: trailers

Response is a 302 redirect to https://mastodon.social/auth/sign_in

Response headers:

HTTP/3 302 
content-length: 0
referrer-policy: same-origin
x-request-id: 74974a436845e3cc07f11c413c02952e
set-cookie: _mastodon_session=zk4...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
x-content-type-options: nosniff
x-frame-options: DENY
accept-ranges: bytes
content-type: text/html; charset=utf-8
location: https://mastodon.social/auth/sign_in
x-xss-protection: 0
x-runtime: 0.009285
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://mastodon.social; img-src 'self' data: blob: https://mastodon.social https://files.mastodon.social; style-src 'self' https://mastodon.social 'nonce-ml2PndIQ8V49Z2+OC4z4Rw=='; media-src 'self' data: https://mastodon.social https://files.mastodon.social; frame-src 'self' https:; manifest-src 'self' https://mastodon.social; form-action 'self'; child-src 'self' blob: https://mastodon.social; worker-src 'self' blob: https://mastodon.social; connect-src 'self' data: blob: https://mastodon.social https://files.mastodon.social wss://streaming.mastodon.social; script-src 'self' https://mastodon.social 'wasm-unsafe-eval'
cache-control: private, no-store
via: 1.1 varnish, 1.1 varnish, 1.1 varnish
date: Thu, 04 Apr 2024 09:05:17 GMT
x-served-by: cache-fra-etou8220047-FRA, cache-fra-eddf8230105-FRA, cache-ams21026-AMS
x-cache: MISS, MISS, MISS
x-cache-hits: 0, 0, 0
x-timer: S1712221518.725172,VS0,VE41
strict-transport-security: max-age=31557600
alt-svc: h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
  1. Get https://mastodon.social/auth/sign_in

Request headers:

GET /auth/sign_in HTTP/3
Host: mastodon.social
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: _mastodon_session=zk4...[REDACTED]
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache
TE: trailers

Response is a 200 and the sign in page.

Response headers:

HTTP/3 200 
content-length: 19498
accept-ranges: bytes
x-frame-options: DENY
etag: W/"364e85d9905ca0726584071bbd3022e4"
x-xss-protection: 0
cache-control: private, no-store
content-type: text/html; charset=utf-8
link: </packs/js/locale/en-json-92adf6253ae9a47c0d3c.chunk.js>; rel=preload; as=script; type=text/javascript; integrity=sha256-bNTy4L61lxKwtKpATwgDZXZ11dFXwdbNyFqGZQXYfas=
x-content-type-options: nosniff
x-request-id: b99599cf1e9cc646647c86bb66e45702
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://mastodon.social; img-src 'self' data: blob: https://mastodon.social https://files.mastodon.social; style-src 'self' https://mastodon.social 'nonce-PV3TsmCkwD166SSf1Wq0HA=='; media-src 'self' data: https://mastodon.social https://files.mastodon.social; frame-src 'self' https:; manifest-src 'self' https://mastodon.social; child-src 'self' blob: https://mastodon.social; worker-src 'self' blob: https://mastodon.social; connect-src 'self' data: blob: https://mastodon.social https://files.mastodon.social wss://streaming.mastodon.social; script-src 'self' https://mastodon.social 'wasm-unsafe-eval'
referrer-policy: same-origin
x-runtime: 0.032417
via: 1.1 varnish, 1.1 varnish, 1.1 varnish
set-cookie: _mastodon_session=Oh6...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
date: Thu, 04 Apr 2024 09:05:17 GMT
x-served-by: cache-fra-eddf8230045-FRA, cache-fra-eddf8230035-FRA, cache-ams21026-AMS
x-cache: MISS, MISS, MISS
x-cache-hits: 0, 0, 0
x-timer: S1712221518.791105,VS0,VE115
vary: Accept-Encoding
strict-transport-security: max-age=31557600
alt-svc: h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
  1. Sign in, which POSTs to https://mastodon.social/auth/sign_in:

Request

POST /auth/sign_in HTTP/3
Host: mastodon.social
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://mastodon.social/auth/sign_in
Content-Type: application/x-www-form-urlencoded
Content-Length: 195
Origin: https://mastodon.social
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: _mastodon_session=Oh6...[REDACTED]
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache

Response

HTTP/3 302 
content-length: 0
accept-ranges: bytes
x-frame-options: DENY
x-xss-protection: 0
cache-control: private, no-store
content-type: text/html; charset=utf-8
x-content-type-options: nosniff
location: https://mastodon.social/oauth/authorize?client_id=lAqIYHpjr49PDd9GddJJ7ZlTzo4fJEioTouGdJ-6uuM&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=codex-request-id: 85b8542448268f2a5c4896136e04db66
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://mastodon.social; img-src 'self' data: blob: https://mastodon.social https://files.mastodon.social; style-src 'self' https://mastodon.social 'nonce-0i6ZQ6gz3t22XvkvsvzeOQ=='; media-src 'self' data: https://mastodon.social https://files.mastodon.social; frame-src 'self' https:; manifest-src 'self' https://mastodon.social; form-action 'self'; child-src 'self' blob: https://mastodon.social; worker-src 'self' blob: https://mastodon.social; connect-src 'self' data: blob: https://mastodon.social https://files.mastodon.social wss://streaming.mastodon.social; script-src 'self' https://mastodon.social 'wasm-unsafe-eval'
referrer-policy: same-origin
x-runtime: 0.116234
via: 1.1 varnish, 1.1 varnish, 1.1 varnish
set-cookie: _session_id=eyJ...[REDACTED]; path=/; expires=Fri, 04 Apr 2025 09:09:18 GMT; HttpOnly; SameSite=Lax; secure
set-cookie: _mastodon_session=86Q...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
date: Thu, 04 Apr 2024 09:09:18 GMT
x-served-by: cache-fra-eddf8230083-FRA, cache-fra-eddf8230083-FRA, cache-ams21026-AMS
x-cache: MISS, MISS, MISS
x-cache-hits: 0, 0, 0
x-timer: S1712221758.293219,VS0,VE199
strict-transport-security: max-age=31557600
alt-svc: h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400

Follow the redirect

Request

GET /oauth/authorize?client_id=lAqIYHpjr49PDd9GddJJ7ZlTzo4fJEioTouGdJ-6uuM&scope=read&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code HTTP/3
Host: mastodon.social
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://mastodon.social/auth/sign_in
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: _mastodon_session=86Q...[REDACTED]
_session_id=eyJ...[REDACTED]
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache
TE: trailers

Response

HTTP/3 200 
content-length: 16754
accept-ranges: bytes
x-frame-options: DENY
etag: W/"2f16fca5c6d098fefaccda88e1f4dabc"
x-xss-protection: 0
cache-control: private, no-store
content-type: text/html; charset=utf-8
link: </packs/js/locale/en-json-92adf6253ae9a47c0d3c.chunk.js>; rel=preload; as=script; type=text/javascript; integrity=sha256-bNTy4L61lxKwtKpATwgDZXZ11dFXwdbNyFqGZQXYfas=
x-content-type-options: nosniff
x-request-id: aa4bc88719ef0741fcef6ccc19c0157c
content-security-policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; font-src 'self' https://mastodon.social; img-src 'self' data: blob: https://mastodon.social https://files.mastodon.social; style-src 'self' https://mastodon.social 'nonce-pbfTS2QJWqlPE9ma4o654A=='; media-src 'self' data: https://mastodon.social https://files.mastodon.social; frame-src 'self' https:; manifest-src 'self' https://mastodon.social; child-src 'self' blob: https://mastodon.social; worker-src 'self' blob: https://mastodon.social; connect-src 'self' data: blob: https://mastodon.social https://files.mastodon.social wss://streaming.mastodon.social; script-src 'self' https://mastodon.social 'wasm-unsafe-eval'
referrer-policy: same-origin
x-runtime: 0.022009
via: 1.1 varnish, 1.1 varnish, 1.1 varnish
set-cookie: _session_id=eyJ...[REDACTED]; path=/; expires=Fri, 04 Apr 2025 09:12:51 GMT; HttpOnly; SameSite=Lax; secure
set-cookie: _mastodon_session=Y4c...[REDACTED]; path=/; HttpOnly; SameSite=Lax; secure
date: Thu, 04 Apr 2024 09:12:51 GMT
x-served-by: cache-fra-eddf8230049-FRA, cache-fra-etou8220047-FRA, cache-ams21081-AMS
x-cache: MISS, MISS, MISS
x-cache-hits: 0, 0, 0
x-timer: S1712221972.555008,VS0,VE108
vary: Accept-Encoding
strict-transport-security: max-age=31557600
alt-svc: h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
  1. Authorize the app, which works as normal.
nikclayton commented 3 months ago

The only thing that stands out for me there is, as you've noted, the difference in the Referer headers; the header sent to social.tchncs.de is missing the path and query string because it's setting referrer-policy: strict-origin in the responses.

I'll contact the social.tchncs.de admins with this info and see if they can figure out why that is, and change their config not to.

nikclayton commented 3 months ago

~https://mastodon.gougere.fr/@cyclotopie/112211752115341300 reports that servers scicomm.xyz and mastodon.gougere.fr have the same problem at login.~

~Edit: I've requested an account on scicomm.xyz to see if it has the same "double referrer-policy" problem.~

Edit: probably a red herring

ClearlyClaire commented 3 months ago

I can reproduce the issue on tchncs.de and not on main. I'm pretty sure this is indeed because of strict-origin. Mastodon uses the referrer's path to handle the redirect-after-login flow, and excludes referrers paths including /auth from it. However, in social.tchncs.de's case, the path being omitted means the referrer won't match /auth and will overwrite the redirect path.

https://mastodon.gougere.fr/@cyclotopie/112211752115341300 reports that servers scicomm.xyz and mastodon.gougere.fr have the same problem at login.

The post states:

not even reaching the stage when credentials are being requested.

so I doubt the problem is the same.

nikclayton commented 3 months ago

@ClearlyClaire Thanks for that.

I can't reproduce the problem on scicomm.xyz; my test account was just approved and I can log in to in Pachli with no problems.

marcr commented 2 months ago

@nikclayton @ClearlyClaire I had the same problem and discussed this with Milan (social.tchncs.de admin). He just fixed the server config. The referrer policy should now be set to same-origin only.

nikclayton commented 2 months ago

Same here on hessen.social for both tusky and pachli

@piratenpanda now we know the problem (and the fix) I've asked the admin of hessen.social to fix their server configuration, https://mastodon.social/@pachli/112258102835803341

Todo.

nikclayton commented 2 months ago

@piratenpanda hessen.social should be fixed now.

piratenpanda commented 2 months ago

Wonderful news. Thanks for your time!

drboone commented 2 months ago

Step 4.

Problem: At this point I am supposed to be shown the "Authorize this app" page, with the "Authorize" and "Deny" buttons. I am not, I am shown the normal Mastodon UI with my home timeline, the "This is your home base within Mastodon" message, etc.

If you capture a HAR archive of the session, does the browser send the cookie it should in the requests it makes for step 4? When I see this issue, my browsers do not.