FIDO U2F Key: Sign authentication challenge in Chrome returns error code 4 (works in FF) - challenge-response

We are trying to add authentication via Yubico FIDO U2F Security Key to our admin website.
This works in FireFox with the U2F add-on installed but signing a challenge (using javascript) to log in keeps returning {errorCode: 4}.
Does anyone know why that might be happening or how I can debug what is going wrong?
Thanks in advance.
Details
Our website is made in Java with the ZK Framework. On server side we use the java-u2flib-server library. We sign the requests on client side using javascript in the zul files using the high level api functions u2f.register and u2f.sign.
Registration
To register a key the user first enters name and password and submits. The server creates the RegistrationData and goes to a second page. There, we use javascript function u2f.register. In the callback we send the response with the DeviceRegistration to the server.
This works both in FireFox and Chrome.
Authentication/login
The login is done similarly. When submitting the first page the server gives the DeviceRegistration json and a challenge to a second page. The page uses u2f.sign and sends the DeviceResponse to the server in the callback.
This works in Firefox but in Chrome, u2f.sign keeps returning {errorCode: 4}.
According to the documentation this means the device does not know the received DeviceRegistration but that seems unlikely since the same code works in firefox and I checked that they receive the same json from the server.
Error code 4 - DEVICE_INELIGIBLE -
The presented device is not eligible for this request. For a registration request this may mean that the token is already registered, and for a sign request it may mean that the token does not know the presented key handle.

Related

Messenger bot: You cannot access the app till you log in to www.facebook.com and follow the instructions given. No instructions were given

My messenger bot that was running for two months but this night something changed and for unclear reasons, I can't POST back to Facebook which returns an error as a response.
From begging:
This is the communication scheme
# VS - alias for the Server running chatbot
# this is what should happen
1. User -> message -> FB # User sends a message via messenger
2. VS <- message <- FB # Facebook does its thing and send me REST API POST request
3. VS -> response -> FB # I send the response meant for the User
4. User <- response <- FB # Facebook forwards the response to User
# this is what is happening
1. User -> message -> FB # works
2. VS <- message <- FB # works
3. VS -> response -> FB # works
4. VS <- error <- FB # FB returns an 400 error and User gets no response
This is the error returned in the fourth step.
# The error response from step 4
'{"error":{
"message":"You cannot access the app till you log in to www.facebook.com and follow the
instructions given.", ### !! above !! ###
"type":"OAuthException",
"code":190,
"error_data": "{\"checkpoint_url\" : \"https:\\\/\\\/www.facebook.com\"}",
"error_subcode":459,
"fbtrace_id":"A9MjzGGqQfKY2vPsszXQemu"
}
}'
I did as said in the message field but there were no instructions on facebook.com nor the developers.facebook.com. I checked from the correct account.
I did change a thing in server code, but it was a simple bug fix that shouldn't have had an impact on communication with Facebook. Obviously, I have tested it and everything worked fine.
But overnight FB decided that everything was not fine and started returning errors to every response sent (response is the third step in the communication scheme).
Do you know what this error is about or maybe where can I find help because Facebook doesn't provide real support?
Quick fix:
Log in to every administrator account of the app and check notifications or
possible security issues. For me it was changing the password of an account
that I don't use daily.
Generate new Access Token in App Dashboard/Messenger/Settings and reconfigure
your server to use it.
Longer version
The app has two administrator accounts, one is my usual and the other one was created specifically for this project (what was unnecessary).
Looking from my main account, I couldn't find anything that would tell me what is wrong, when writing this question, just to be sure I checked the other one. FB prompted me to change my password for security reasons because someone tried to log in from the USA (but I haven't tried to log in to this account lately).
I changed the password and looked for notifications that would tell me what was wrong. Nothing. Error response didn't change either in logs.
Today with nothing better in mind I switched from: requests.post("https://graph.facebook.com/v2.6/me/messages")
to:
requests.post("https://graph.facebook.com/v6.0/me/messages")
and checked logs, where I found this response:
"error":{
"message":"Error validating access token: The session has been invalidated
because the user changed their password or Facebook has changed the
session for security reasons.",
"type":"OAuthException",
"code":190,
"error_subcode":460,
"fbtrace_id":"Ay7KPJ9_gtv5s3ebKjm5LG_"
}}'
Now I did exactly what it said and generated a new Access Token in
App Dashboard/Messenger/Setting and reconfigured my server. This was it.
Then from curiosity, I changed back the v6.0 to v2.6 and everything still worked fine.

RESTful Device specific Authentication of Phone Number

We have an API that sends a verification code to user's mobile number. The API is:
POST /api/users/verification/start/
{
"mobile": "9849735434"
}
The above API returns following response:
{
"isVerified": false
}
If the response is "isVerified": true, we don't send a verification code to user's mobile. If it is false, we send a code.
Currently, all this works on the just mobile number. We want to make it based on (mobile + device) to make it more secure.
To achieve this, we store a user-identification cookie on the client machine and we are planning to identify the device on basis of that. How should API be modified for this new requirement? Few approaches:
Create different API that works on basis of (mobile + cookie) and sends isVerified: true only if both matches with the value stored in our database.
Modify existing API to achieve this - Since this support for device-specific OTP is not required always, we will have to pass some flag to make it only mobile-based OR (mobile and cookie).
How should we design such API to verify users based on mobile and device?
Hope this would help you, you can modify code and follow some client and server steps.
CLIENT SIDE
Step 1.
Get mobile no and country from user
GET UUID from user device. ( UUID :Is Secure.ANDROID_ID unique for each device?)
Hit Own Api with this params.
SERVER SIDE
Step 2.
Get Validate it, is this mobile no is Valid https://github.com/googlei18n/libphonenumber (we can do it from Client side too)
Step 3.
Generate OTP between 0001 - 9999 or more
Send OTP api call to send on Mobile no as per OTP service provider’s API.
Save OTP no into database along with Mobile no And UUID.
CLIENT SIDE
Step 4.
get mobile no and OTP and hit api
check OTP from DB same OTP then response success else Wrong OTP message you can send.
There are different options.
When you want to use cookies, why do you need a separate API at all? If the client has a cookie, let the client send this cookie as a cookie. Your service can analyze the cookie when needed and decide about further steps.
If you cannot send cookies and the 1st approach is not an option to you:
Device should not know, what type is it from the point of view of your service. That is why I'd suggest to use two services - one without cookies and one with cookies.
You say "RESTful". In the current form your service is not RESTful.
A) Using verbs makes the service NOT RESTful. Rename it for instance to
"POST /api/users/verification/"
B) Two operations are mixed within a single one: Check if client is authenticated and starting authentication process. Split it into two:
To check if the client is authenticated:
"GET /api/users/verification/mobile/9849735434"
To start authentication:
"POST /api/users/verification/mobile/9849735434"
For the POST you don't need a body in this case.
I would modify the existing API to fit the new requirement and here is the important thing I would do while modifying.
Whenever you create any API always have a "version" passed from the client this way you would know which section of the code to execute.
e.g Assume your mobile users have 2 different version of the app, once before this release another after. To have both the user running versioning is helpful.
Pass "Device Type" from client to check whether the client is mobile/tab or other, this will have multiple advantages firstly you will know how much user base is in phone/web, another advantage is you can customize the output size accordingly as web will have more information compared to the mobile app.
Now that you have device and version information you just have to write condition in your existing API. Once you feel there is no old version usage we can retire that portion of API.

Signin with LinkedIn - How to validate token on server side

I would like to allow users to login my web application using "Sign in with LinkedIn" Javascript SDK.
https://developer.linkedin.com/docs/signin-with-linkedin
Once user logging in using LinkedIn i need to transfer (post) the Member ID to my application server and look for a user with that linkedIn memberid in my application database.
The problem is that i couldn't find an option to validate the member id i am getting from the javascript SDK in the server side in order to make sure the end user didn't manipulate it using Chrome Dev tools for example.
Without an option to validate the value on a server side, i assume that users will be able to change the member id value before it post to the server. Am i right?
i found few old threads but the solutions do not work
If you want server side validation you should use the Oauth 2.0 approach.
Start by providing the initial link:
Li Auth
And continue from there:
https://developer.linkedin.com/docs/oauth2

Integrated Exchange login with GWT on Tomcat

I have a GWT app to deploy to Tomcat on a Windows server, with the following requirements:
1- The app should work fully, whether the user is in the Windows domain or not;
2- If the user happens to be in the domain, the app should be able to identify the user in some manner. Presumably, this should be via getThreadLocalRequest().getRemoteUser(), but any other alternative is fine...
3- If the user happens to be in the domain, the app should be able to access the MS Exchange server in that domain, without requiring the user to enter their password.
I've scoured the web high and low for this, but unfortunately, it seems there's no way to get authentication without forcing authentication. There are many examples of exclusions for, say, a login form or other "public" resources, but that won't work for us, since all the resources in a GWT app are packed into the same "page".
Maybe it's my limited understanding that's making me fail in some basic way, but I've tried to look at JCIFS, Jespa, Waffle and SPNEGO, and I just can't seem to get working the way I want to...
Any help would be greatly appreciated.
Cheers,
J.
How about putting a Javascript on your front page and have a Kerberos/SPNEGO protected page. The javascript will attempt to request a protected page, if the user is on the domain you will get the correct result from the page otherwise you will get 401 access denied. In the former case you can redirect your browser to exchange page, or have another AJAX call to retrieve things from exchange server in the later case you either show a log-in form or a generic anonymous page.
What about using JNI to call the Win32Api function LogonUser?
By doing impersonation at the thread level you will have the NTLM token added to the current thread and you would be able to call exchange with no issues

Error code 100 (Can only call this method on valid test users for your app)

getting the error {"error":{"message":"(#100) Can only call this method on valid test users for your app","type":"OAuthException"}} whenever trying to write to any facebook end point. Reading (GET) works fine, writing (POST) fails. Does anybody know how to resolve this?
I have also opened a ticket on FB dev site:
http://developers.facebook.com/bugs/184198634991192?browse=search_4e93328871c8a3231774584
The problem does not occur is I would shoot the POST request from my browser as if I am the user.
The problem does occurs only when sending from our servers on behalf of the user from one of our dev machines which have other subdomain names instead of www (such as dev1.blablabla.com & dev2.blablabla.com, while the app is registered to www.blablabla.com).
So the question is, does facebook attempt to do a reverse DNS lookup on all write requests to verify the source?
I believe your requirement is to get the user details of the owner of Facebook access token (normally the currently logged in user)
For that you have to issue a GET request and not a POST request.
The reason why it works when fired from the browser is that when you submit a query through the address bar it is send as a GET request, and when sent from your server it is send as POST and fails producing the error message mentioned in your post.
Facebook doesn't do a reverse DNS lookup on your write request and not need to configure anything in your server related to it.
Hope the answer is clear enough for you.