Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

NextCloud stopped authenticating with U2F #9

Closed
jakubgs opened this issue Feb 21, 2022 · 29 comments
Closed

NextCloud stopped authenticating with U2F #9

jakubgs opened this issue Feb 21, 2022 · 29 comments
Assignees

Comments

@jakubgs
Copy link
Member

jakubgs commented Feb 21, 2022

Currently attempts to authenticate with 2FA fail on our NextCloud instance as reported by @serhanwbahar.

image

@jakubgs jakubgs self-assigned this Feb 21, 2022
jakubgs referenced this issue Feb 21, 2022
Possible fix for U2F authentication issues.
status-im/infra-office#9

Signed-off-by: Jakub Sokołowski <[email protected]>
@jakubgs
Copy link
Member Author

jakubgs commented Feb 21, 2022

I have upgraded the NextCloud image to 23.0.2: https://github.com/status-im/infra-office/commit/07986cf6

@jakubgs
Copy link
Member Author

jakubgs commented Feb 21, 2022

I am able to log in using YubiKey as admin, so that works now, but there certainly is something up, because when I try to add a YubiKey to my personal account nothing happens, it just spins:

image

@jakubgs
Copy link
Member Author

jakubgs commented Feb 21, 2022

And I see this error in main log:

{
  "reqId": "OETlnUZWzvgOmRgz3Zc6",
  "level": 3,
  "time": "2022-02-21T14:43:56+00:00",
  "remoteAddr": "172.17.9.1",
  "user": "jakub",
  "app": "index",
  "method": "POST",
  "url": "/index.php/apps/twofactor_u2f/settings/finishregister",
  "message": "OCA\\TwoFactorU2F\\Controller\\SettingsController::finishRegister(): Argument #1 ($registrationData) must be of type string, null given, called in /var/www/html/lib/private/AppFramework/Http/Dispatcher.php on line 217 in file /var/www/html/custom_apps/twofactor_u2f/lib/Controller/SettingsController.php line 65",
  "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36",
  "version": "23.0.0.10",
  "exception": {
    "Exception": "Exception",
    "Message": "OCA\\TwoFactorU2F\\Controller\\SettingsController::finishRegister(): Argument #1 ($registrationData) must be of type string, null given, called in /var/www/html/lib/private/AppFramework/Http/Dispatcher.php on line 217 in file /var/www/html/custom_apps/twofactor_u2f/lib/Controller/SettingsController.php line 65",
    "Code": 0,
    "Trace": [
      { "file": "/var/www/html/lib/private/AppFramework/App.php", "line": 157, "function": "dispatch", "class": "OC\\AppFramework\\Http\\Dispatcher", "type": "->", "args": [ { "__class__": "OCA\\TwoFactorU2F\\Controller\\SettingsController" }, "finishRegister" ] },
      { "file": "/var/www/html/lib/private/Route/Router.php", "line": 302, "function": "main", "class": "OC\\AppFramework\\App", "type": "::", "args": [ "OCA\\TwoFactorU2F\\Controller\\SettingsController", "finishRegister", { "__class__": "OC\\AppFramework\\DependencyInjection\\DIContainer" }, { "_route": "twofactor_u2f.settings.finishRegister" } ] },
      { "file": "/var/www/html/lib/base.php", "line": 1006, "function": "match", "class": "OC\\Route\\Router", "type": "->", "args": [ "/apps/twofactor_u2f/settings/finishregister" ] },
      { "file": "/var/www/html/index.php", "line": 36, "function": "handleRequest", "class": "OC", "type": "::", "args": [] }
    ],
    "File": "/var/www/html/lib/private/AppFramework/Http/Dispatcher.php",
    "Line": 158,
    "Previous": {
      "Exception": "TypeError",
      "Message": "OCA\\TwoFactorU2F\\Controller\\SettingsController::finishRegister(): Argument #1 ($registrationData) must be of type string, null given, called in /var/www/html/lib/private/AppFramework/Http/Dispatcher.php on line 217",
      "Code": 0,
      "Trace": [
        { "file": "/var/www/html/lib/private/AppFramework/Http/Dispatcher.php", "line": 217, "function": "finishRegister", "class": "OCA\\TwoFactorU2F\\Controller\\SettingsController", "type": "->", "args": [ null, null, "YubiKey" ] },
        { "file": "/var/www/html/lib/private/AppFramework/Http/Dispatcher.php", "line": 126, "function": "executeController", "class": "OC\\AppFramework\\Http\\Dispatcher", "type": "->", "args": [ { "__class__": "OCA\\TwoFactorU2F\\Controller\\SettingsController" }, "finishRegister" ] },
        { "file": "/var/www/html/lib/private/AppFramework/App.php", "line": 157, "function": "dispatch", "class": "OC\\AppFramework\\Http\\Dispatcher", "type": "->", "args": [ { "__class__": "OCA\\TwoFactorU2F\\Controller\\SettingsController" }, "finishRegister" ] },
        { "file": "/var/www/html/lib/private/Route/Router.php", "line": 302, "function": "main", "class": "OC\\AppFramework\\App", "type": "::", "args": [ "OCA\\TwoFactorU2F\\Controller\\SettingsController", "finishRegister", { "__class__": "OC\\AppFramework\\DependencyInjection\\DIContainer" }, { "_route": "twofactor_u2f.settings.finishRegister" } ] },
        { "file": "/var/www/html/lib/base.php", "line": 1006, "function": "match", "class": "OC\\Route\\Router", "type": "->", "args": [ "/apps/twofactor_u2f/settings/finishregister" ] },
        { "file": "/var/www/html/index.php", "line": 36, "function": "handleRequest", "class": "OC", "type": "::", "args": [] }
      ],
      "File": "/var/www/html/custom_apps/twofactor_u2f/lib/Controller/SettingsController.php",
      "Line": 65
    },
    "CustomMessage": "--"
  }
}

@jakubgs
Copy link
Member Author

jakubgs commented Feb 21, 2022

If we look at logs from Serhan's login attempt there's no errors:

{"reqId":"wZ3zH6OfFGMqyeq3kntb","level":0,"time":"2022-02-21T15:00:12+00:00","remoteAddr":"172.17.9.1","user":"serhan","app":"encryption","method":"GET","url":"/index.php/login/selectchallenge","message":"/appinfo/app.php is deprecated, use \\OCP\\AppFramework\\Bootstrap\\IBootstrap on the application class instead.","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36","version":"23.0.0.10"}
{"reqId":"FyrxMLmns85vHnowZQWf","level":0,"time":"2022-02-21T15:00:13+00:00","remoteAddr":"172.17.9.1","user":"serhan","app":"encryption","method":"GET","url":"/cron.php","message":"/appinfo/app.php is deprecated, use \\OCP\\AppFramework\\Bootstrap\\IBootstrap on the application class instead.","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36","version":"23.0.0.10"}
{"reqId":"tC6Mv0C44kvv8tS4bwHE","level":0,"time":"2022-02-21T15:00:13+00:00","remoteAddr":"172.17.9.1","user":"serhan","app":"encryption","method":"GET","url":"/index.php/apps/encryption/ajax/getStatus","message":"/appinfo/app.php is deprecated, use \\OCP\\AppFramework\\Bootstrap\\IBootstrap on the application class instead.","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36","version":"23.0.0.10"}
{"reqId":"0QZIj6GCSsuDODMyxHTL","level":0,"time":"2022-02-21T15:00:13+00:00","remoteAddr":"172.17.9.1","user":"serhan","app":"encryption","method":"GET","url":"/index.php/login/selectchallenge?redirect_url=/index.php/apps/encryption/ajax/getStatus","message":"/appinfo/app.php is deprecated, use \\OCP\\AppFramework\\Bootstrap\\IBootstrap on the application class instead.","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36","version":"23.0.0.10"}
{"reqId":"qfUgUFLRrH67vNQpVbEH","level":0,"time":"2022-02-21T15:00:14+00:00","remoteAddr":"172.17.9.1","user":"serhan","app":"encryption","method":"GET","url":"/index.php/login/challenge/u2f","message":"/appinfo/app.php is deprecated, use \\OCP\\AppFramework\\Bootstrap\\IBootstrap on the application class instead.","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36","version":"23.0.0.10"}

@jakubgs
Copy link
Member Author

jakubgs commented Feb 22, 2022

I tried updating plugins but none of the twofactor ones updated:

[email protected]:~ % d exec -u 33 nextcloud-app php occ app:list | grep twofactor
  - twofactor_backupcodes: 1.12.0
  - twofactor_totp: 6.2.0
  - twofactor_u2f: 6.3.0

[email protected]:~ % d exec -u 33 nextcloud-app php occ app:update --all
appointments new version available: 1.12.0
appointments updated
contacts new version available: 4.0.8
contacts updated
mail new version available: 1.11.7
mail updated

@jakubgs
Copy link
Member Author

jakubgs commented Feb 22, 2022

I can see @serhanwbahar has all 3 available two factor auth options enabled:

[email protected]:~ % d exec -u 33 nextcloud-app php occ twofactorauth:state serhan
Two-factor authentication is enabled for user serhan

Enabled providers:
- u2f
- backup_codes
- totp

@jakubgs
Copy link
Member Author

jakubgs commented Feb 22, 2022

I think I can disable u2f provider for a specific user using the twofactorauth:disable subcommand:

[email protected]:~ % d exec -u 33 nextcloud-app php occ twofactorauth             
                                           
  Command "twofactorauth" is not defined.  
                                           
  Did you mean one of these?               
      twofactorauth:cleanup                
      twofactorauth:disable                
      twofactorauth:enable                 
      twofactorauth:enforce                
      twofactorauth:state    

[email protected]:~ % d exec -u 33 nextcloud-app php occ twofactorauth:disable --help
Description:
  Disable two-factor authentication for a user

Usage:
  twofactorauth:disable [options] [--] <uid> <provider_id>

Arguments:
  uid                    
  provider_id            

Options:
      --output[=OUTPUT]  Output format (plain, json or json_pretty, default is plain) [default: "plain"]
  -h, --help             Display this help message
  -q, --quiet            Do not output any message
  -V, --version          Display this application version
      --ansi             Force ANSI output
      --no-ansi          Disable ANSI output
  -n, --no-interaction   Do not ask any interactive question
      --no-warnings      Skip global warnings, show command output only
  -v|vv|vvv, --verbose   Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

@jakubgs
Copy link
Member Author

jakubgs commented Feb 22, 2022

It worked:

[email protected]:~ % d exec -u 33 nextcloud-app php occ twofactorauth:state serhan
Two-factor authentication is enabled for user serhan

Enabled providers:
- backup_codes
- totp
Disabled providers:
- u2f

@serhanwbahar can you try logging in using a different method and then adding U2F again?

@serhanwbahar
Copy link

I tried it, but I'm stuck with the "Adding your device..." screen. It took forever and didn't add the U2F device.

Screen Shot 2022-02-22 at 20 29 40

@jakubgs
Copy link
Member Author

jakubgs commented Feb 22, 2022

This issue looks imilar:

If you use a docker instance, the readme has an example how to do this.
nextcloud/twofactor_webauthn#16 (comment)

But there the error is :

Call to undefined function CBOR\gmp_intval()

And our error is:

OCA\TwoFactorU2F\Controller\SettingsController::finishRegister():
Argument #1 ($registrationData) must be of type string, null given,
called in /var/www/html/lib/private/AppFramework/Http/Dispatcher.php
on line 217 in file /var/www/html/custom_apps/twofactor_u2f/lib/Controller/SettingsController.php line 65

@jakubgs
Copy link
Member Author

jakubgs commented Feb 22, 2022

Ooh, this looks more promising:

had to add

'overwriteprotocol' => 'https',

in config.php
nextcloud/twofactor_u2f#690 (comment)

@jakubgs
Copy link
Member Author

jakubgs commented Feb 22, 2022

Except we already have that in the config:

https://github.com/status-im/infra-office/blob/07986cf6caa5ab41d27b7368d400c62c6d44ecb0/ansible/roles/nextcloud/templates/config.php.j2#L15

[email protected]:~ % d exec -u 33 nextcloud-app php occ config:list | jq .system.overwriteprotocol     
"https"

@jakubgs
Copy link
Member Author

jakubgs commented Mar 3, 2022

I tried editing /var/www/html/apps/settings/lib/Controller/WebAuthnController.php in the container to add some more logging, but for some reason it has absolutely no effect.

There's also /usr/src/nextcloud/apps/settings/lib/Controller/WebAuthnController.php but that doesn't do much either.

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

Upgraded NextCloud to 23.0.3 but the issue persists: https://github.com/status-im/infra-office/commit/60909113

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

Okay, looks like my modification of entrypoint has stopped the full upgrade from running:
https://github.com/status-im/infra-office/blob/6090911392bb2fad621539dd38c7459f825e3780/ansible/roles/nextcloud/templates/docker-compose.yml.j2#L8
So commenting that out has allowed me to run the full upgrade process after re-creating the containers:

image

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

Also had to manually run command to add missing indices:

[email protected]:~ % d exec -u 33 nextcloud-app php occ db:add-missing-indices
Check indices of the share table.
Check indices of the filecache table.
Check indices of the twofactor_providers table.
Check indices of the login_flow_v2 table.
Check indices of the whats_new table.
Check indices of the cards table.
Check indices of the cards_properties table.
Check indices of the calendarobjects_props table.
Check indices of the schedulingobjects table.
Check indices of the oc_properties table.
Adding properties_pathonly_index index to the oc_properties table, this can take some time...
oc_properties table updated successfully.
Check indices of the oc_jobs table.
Adding job_lastcheck_reserved index to the oc_jobs table, this can take some time...
oc_properties table updated successfully.

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

Still not working, but now I see an error like this:

Uncaught (in promise) Error: U2F device registration failed (error code unknown)
    at a.rejectRegistration (AddDeviceDialog.vue:157:1)
    at AddDeviceDialog.vue:135:1

Which seems to be a known issue:

Which suggests the important setting is overwriteprotocol: https, which we already have. Also suggests this doc.

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

When I try to add my YubiKey as WebAuthN I get this:

NotAllowedError The operation either timed out or was not allowed. See: https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.
(anonymous) @ AddDevice.vue:118
Promise.catch (async)
start @ AddDevice.vue:117
Gt @ vue.runtime.esm.js:1863
n @ vue.runtime.esm.js:2188
Ar.i._wrapper @ vue.runtime.esm.js:6961

Which based on the link suggests that the issue is with configuration of WebAuthN Relying Party:

In order to protect users from being identified without consent, implementations of the [[Create]](origin, options, sameOriginWithAncestors) method need to take care to not leak information that could enable a malicious WebAuthn Relying Party to distinguish between these cases, where "excluded" means that at least one of the credentials listed by the Relying Party in excludeCredentials is bound to the authenticator:

If the above cases are distinguishable, information is leaked by which a malicious Relying Party could identify the user by probing for which credentials are available.

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

For some reason the WebAuthN app appears to be not installed:

image

But that just adds a separate option to configure WebAuthN, which fails for the same reason:

image

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

Opened an issue for the WebAuthN timeout errors: nextcloud/twofactor_webauthn#146

But I just successfully managed to add my YubiKey on my laptop, so this might be something client-side.

image

But U2F addition doesn't work on the laptop as well.

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

I've added dome debugging prints to the code to check the values, and when the payload for POST request is:

image

The $arguments variable looks like this:

[NULL, NULL, "yubikey"]

Where yubikey is the $name passed to finishRegister():

	public function finishRegister(string $registrationData, string $clientData, string $name = null): JSONResponse {
		return new JSONResponse($this->manager->finishRegistration($this->userSession->getUser(), $registrationData, $clientData, $name));
	}

So we're clearly missing $registrationData and $clientData.

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

Interesting. When I put a debug line here:

			$this->logger->info("WTF param: $param -> '$value' ($type)");

I can see that the arguments are all of type string:

WTF param: registrationData -> '' (string)
WTF param: clientData -> '' (string)
WTF param: name -> 'yubikey' (string)

But then the first two empty strings get turned into NULLs. What?

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

From my debugging it appears that after this line:

			$arguments[] = $value;

https://github.com/nextcloud/server/blob/v23.0.3/lib/private/AppFramework/Http/Dispatcher.php#L214

The empty string turns into NULL for some unfathomable reason. Which is not what should happen:

image

@jakubgs
Copy link
Member Author

jakubgs commented Mar 24, 2022

@jakubgs
Copy link
Member Author

jakubgs commented Mar 25, 2022

Some setup improvements:

I'm starting to think it would make more sense jut to disable U2F in favor of WebAuthN.

@jakubgs
Copy link
Member Author

jakubgs commented Mar 25, 2022

As far as I can tell there are two ways to use WebAuthN in Next Cloud:

WebAuthN Module

image

WebAuthN Paswordless Native

image


The latter comes with NextCloud, the former is an application you install. The main difference is that the native method does not require the password to be provided:

image
image

Which tells me that maybe the app version is better.

jakubgs referenced this issue Mar 25, 2022
The native support allows for passwordless login, but we'd rather prompt
for password before verifying with WebAuthN device as second factor.

status-im/infra-office#9 (comment)

Signed-off-by: Jakub Sokołowski <[email protected]>
@jakubgs
Copy link
Member Author

jakubgs commented Mar 25, 2022

I've disabled native WebAuthN extension and added the app to config: https://github.com/status-im/infra-office/commit/5afbc3bc

@jakubgs
Copy link
Member Author

jakubgs commented Mar 26, 2022

I didn't fix the issue, but I've wasted enough time on this considering U2F is deprecated. Closing.

@jakubgs jakubgs closed this as completed Mar 26, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants