U2F Authentication throws unsupported URLNetworkTaskDescription Error
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 2.5k
- Forks
- 1k
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 13
Description
Steps to reproduce
- Add U2F (YubiKey etc.) authentication to an account with the Featured U2F 2FA App (By Christoph Wurzt)
- Try to sign in with an iOS client, when you successfully enter the first factor the error will appear.
Expected behaviour
iOS asking the user to scan the security key.
Actual behaviour
The error as shown in the attached screenshot is thrown.
For copy-pasting:
unsupported URLNetworkTaskDescription
LocalDataTask
< - some ID - >
NSLocalizedDescription unsupported URL
NSErrorFailingURLStringKey u2f://auth?%7B%22type%22:%22u2f_sign_request%22
-- omitted inserted URL and secrets --
_WKRecoveryAttempterErrorKey
<WKReloadFrameErrorRecoveryAttempter: 0x28125be40>
Screenshots

Logs
The server logs reveal nothing special, it shows the first factor auth as successful and then nothing, indicating the error is most likely client-side.
Client logs don't really reveal anything either, pasting them for completion
2021-10-21 23:32:53 Start session with level 1 Nextcloud Liquid for iOS 4.0.6.0 © 2021
2021-10-21 23:33:07 Network request started: GET https://my.nextcloud.server/status.php
2021-10-21 23:33:08 Network response request: https://my.nextcloud.server/status.php, result: success({
edition = "";
extendedSupport = 0;
installed = 1;
maintenance = 0;
needsDbUpgrade = 0;
productname = Nextcloud;
version = "22.2.0";
versionstring = "22.2.0";
})
2021-10-21 23:33:08 Network request started: POST https://my.nextcloud.server/index.php/login/v2
2021-10-21 23:33:08 Network response request: https://my.nextcloud.server/index.php/login/v2, result: success({
login = "https://my.nextcloud.server/login/v2/flow/<omitted>";
poll = {
endpoint = "https://my.nextcloud.server/login/v2/poll";
token = <omitted>;
};
})
2021-10-21 23:53:47 Network request started: GET https://my.nextcloud.server/status.php
2021-10-21 23:53:48 Network response request: https://my.nextcloud.server/status.php, result: success({
edition = "";
extendedSupport = 0;
installed = 1;
maintenance = 0;
needsDbUpgrade = 0;
productname = Nextcloud;
version = "22.2.0";
versionstring = "22.2.0";
})
2021-10-21 23:53:48 Network request started: POST https://my.nextcloud.server/index.php/login/v2
2021-10-21 23:53:48 Network response request: https://my.nextcloud.server/index.php/login/v2, result: success({
login = "https://my.nextcloud.server/login/v2/flow/<omitted>";
poll = {
endpoint = "https://my.nextcloud.server/login/v2/poll";
token = <omitted>;
};
})
2021-10-21 23:54:20 initialize Main
2021-10-21 23:54:21 Network request started: POST https://my.nextcloud.server/ocs/v2.php/apps/notifications/api/v2/push?format=json
2021-10-21 23:54:21 Network request started: GET https://my.nextcloud.server/ocs/v2.php/cloud/user?format=json
2021-10-21 23:54:21 Network request started: GET https://my.nextcloud.server/status.php
2021-10-21 23:54:21 Network request started: PROPFIND https://my.nextcloud.server/remote.php/webdav
2021-10-21 23:54:24 Network response request: https://my.nextcloud.server/status.php, result: success({
edition = "";
extendedSupport = 0;
installed = 1;
maintenance = 0;
needsDbUpgrade = 0;
productname = Nextcloud;
version = "22.2.0";
versionstring = "22.2.0";
})
2021-10-21 23:54:24 Network response request: https://my.nextcloud.server/ocs/v2.php/apps/notifications/api/v2/push?format=json, result: success({
ocs = {
data = {
deviceIdentifier = "ftqRbi4ovXYdq88WpSs8ooeYmANs2a38+fAhohMpEvYrauSmAhslVSwUqT6yU5ZykWPfUXQYEe2GEHE6agP47g==";
publicKey = "<omitted>";
signature = "<omitted>";
};
meta = {
message = OK;
status = ok;
statuscode = 201;
};
};
})
2021-10-21 23:54:24 Network response request: https://my.nextcloud.server/ocs/v2.php/cloud/user?format=json, result: success({
ocs = {
data = {
"additional_mail" = (
);
"additional_mailScope" = (
);
address = "";
addressScope = "v2-local";
avatarScope = "v2-federated";
backend = Database;
backendCapabilities = {
setDisplayName = 1;
setPassword = 1;
};
"display-name" = <omitted>;
displaynameScope = "v2-federated";
email = "<omitted>";
emailScope = "v2-federated";
enabled = 1;
groups = (
admin,
everyone
);
id = <omitted>;
language = "en_GB";
lastLogin = 1634853247000;
locale = "en_GB";
phone = "";
phoneScope = "v2-local";
quota = {
free = 1187418841088;
quota = "-3";
relative = "0.45";
total = 1192783880818;
used = 5365039730;
};
storageLocation = "/nfs/nextcloud//<omitted>";
subadmin = (
);
twitter = "";
twitterScope = "v2-local";
website = "";
websiteScope = "v2-local";
};
meta = {
message = OK;
status = ok;
statuscode = 200;
};
};
})
2021-10-21 23:54:24 Network response request: https://my.nextcloud.server/remote.php/webdav, result: success(1512 bytes)
2021-10-21 23:54:24 Network request started: POST https://push-notifications.nextcloud.com/devices?format=json
2021-10-21 23:54:24 Network request started: REPORT https://my.nextcloud.server/remote.php/dav/files/<omitted>
2021-10-21 23:54:24 Network request started: GET https://my.nextcloud.server/index.php/avatar/<omitted>/512
2021-10-21 23:54:24 Network request started: GET https://my.nextcloud.server/ocs/v1.php/cloud/capabilities?format=json
2021-10-21 23:54:24 Network request started: PROPFIND https://my.nextcloud.server/remote.php/webdav/
2021-10-21 23:54:25 Subscribed to Push Notification server & proxy successfully
2021-10-21 23:54:25 Network response request: https://my.nextcloud.server/remote.php/dav/files/<omitted>, result: success(156 bytes)
2021-10-21 23:54:26 Network request started: GET https://my.nextcloud.server/ocs/v2.php/apps/files_sharing/api/v1/shares?reshares=false&subfiles=false
2021-10-21 23:54:26 Network request started: GET https://my.nextcloud.server/ocs/v2.php/apps/files/api/v1/directEditing?format=json
2021-10-21 23:54:26 Network request started: GET https://my.nextcloud.server/ocs/v2.php/apps/external/api/v1?format=json
2021-10-21 23:54:26 Network request started: GET https://my.nextcloud.server/ocs/v2.php/apps/user_status/api/v1/user_status?format=json
2021-10-21 23:54:27 Network response request: https://my.nextcloud.server/ocs/v2.php/apps/external/api/v1?format=json, result: success({
ocs = {
data = (
{
icon = "https://my.nextcloud.server/apps/external/icons/rss-32.ico";
id = 1;
name = News;
redirect = 0;
type = link;
url = "https://rss.<omitted>";
},
{
icon = "https://my.nextcloud.server/apps/external/icons/favicon.ico";
id = 2;
name = Radarr;
redirect = 0;
type = link;
url = "https://radarr.my.nextcloud.server";
},
{
icon = "https://my.nextcloud.server/apps/external/icons/sonarr.svg";
id = 3;
name = Sonarr;
redirect = 0;
type = link;
url = "https://sonarr.my.nextcloud.server";
},
{
icon = "https://my.nextcloud.server/apps/external/icons/lidarr.svg";
id = 4;
name = Lidarr;
redirect = 0;
type = link;
url = "https://lidarr.my.nextcloud.server";
},
{
icon = "https://my.nextcloud.server/apps/external/icons/torrent-32.ico";
id = 5;
name = Transmission;
redirect = 0;
type = link;
url = "https://transmission.my.nextcloud.server";
},
{
icon = "https://my.nextcloud.server/apps/external/icons/Webp.net-resizeimage.png";
id = 6;
name = Prowlarr;
redirect = 0;
type = link;
url = "https://prowlarr.my.nextcloud.server";
},
{
icon = "https://my.nextcloud.server/apps/external/icons/cloud-download-32.ico";
id = 7;
name = NZBGet;
redirect = 0;
type = link;
url = "https://nzbget.my.nextcloud.server";
},
{
icon = "https://my.nextcloud.server/apps/external/icons/external.svg";
id = 8;
name = Graylog;
redirect = 0;
type = link;
url = "https://fe-lb-graylog.my.nextcloud.server";
}
);
meta = {
message = OK;
status = ok;
statuscode = 200;
};
};
})
2021-10-21 23:54:27 Network response request: https://my.nextcloud.server/ocs/v2.php/apps/files/api/v1/directEditing?format=json, result: success({
ocs = {
data = {
creators = {
textdocument = {
editor = text;
extension = md;
id = textdocument;
mimetype = "text/markdown";
name = "text document";
templates = 0;
};
};
editors = {
text = {
id = text;
mimetypes = (
"text/markdown",
"text/plain",
"application/cmd",
"application/x-empty",
"application/x-msdos-program",
"application/javascript",
"application/json",
"application/x-perl",
"application/x-php",
"application/x-tex",
"application/xml",
"application/yaml",
"text/css",
"text/csv",
"text/html",
"text/org",
"text/x-c",
"text/x-c++src",
"text/x-h",
"text/x-java-source",
"text/x-ldif",
"text/x-python",
"text/x-shellscript"
);
name = "Nextcloud Text";
optionalMimetypes = (
);
secure = 0;
};
};
};
meta = {
message = OK;
status = ok;
statuscode = 200;
};
};
})
2021-10-21 23:54:27 Network response request: https://my.nextcloud.server/ocs/v2.php/apps/user_status/api/v1/user_status?format=json, result: success({
ocs = {
data = {
clearAt = "<null>";
icon = "<null>";
message = "<null>";
messageId = "<null>";
messageIsPredefined = 0;
status = online;
statusIsUserDefined = 0;
userId = <omitted>;
};
meta = {
message = OK;
status = ok;
statuscode = 200;
};
};
})
2021-10-21 23:54:27 Network response request: https://my.nextcloud.server/ocs/v2.php/apps/files_sharing/api/v1/shares?reshares=false&subfiles=false, result: success(4051 bytes)
2021-10-21 23:54:30 Network response request: https://my.nextcloud.server/remote.php/webdav/, result: success(36161 bytes)
Reasoning or why should it be changed/implemented?
The U2F plugin is stated to be production ready. This bug would break the entire operation in environments where U2F keys are mandatory.
Since it's the official Nextcloud app, support for a security feature like this seems only sensible.
Environment data
iOS version: iOS 15.0.1 @ iPhone 13 Pro
Nextcloud iOS app version: 4.0.60
Server operating system: Debian 11
Web server: nginx 1.21.3 on both backend server and frontend proxy.
Database: MariaDB 10.15.11
PHP version: 8.0.11 (FPM)
Nextcloud version: 22.2.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the U2F sign-in flow in the iOS client and tracing how the client handles the u2f:// URL after the first factor succeeds. Done means the client accepts the U2F response and prompts the user to scan the security key instead of showing the unsupported URL error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, swift
- Domain
- authentication, mobile-dev, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100