Protect Direct Line Secret in Botframework for Web Client - node.js

I have my bot ready and working with Direct Line Secret in WebChat (by passing &s=SECRET in URL) and on other channels.
I am interested in the integration of front-end Custom Chat Application using Direct Line ClientJS (link at bottom).
After going through the documentation on Bot Framework I came to know that it can be done in 2 ways:
Pass Direct Line secret from front-end Chat Application in ClientJS
Passing Token from front-end Chat Application (But, this requires Direct Line Secret to be passed to generate token first time)
As I develop bots for my clients with their respective use-cases which
need to be kept private with client servers.
So, anybody having Direct Line Secret can easily obtain Bots Logic (i.e Not actual code, but what answer bot replies to particular question) by just passing that Direct Line secret in Microsoft Bot Framework provided WebChat client (by passing s=SECRET in URL)
So, basically, how do I hide the secret from others?
Direct Line Client : https://github.com/Microsoft/BotBuilder-Samples/tree/master/Node/core-DirectLine
Authentication Mechanism : https://learn.microsoft.com/en-us/bot-framework/rest-api/bot-framework-rest-direct-line-3-0-authentication
Programming Languages:
FrontEnd - Angular.js with Typescript
Backend - Node.js on Heroku

You need to follow method #2 as described in the section Generate a Direct Line Token. Then you won't have to use the secret in your WebChat page at all.
A Direct Line token is a key that can be used to access a single conversation. A token expires but can be refreshed.
This way your client will use the generated token on a per-conversation basis, and there's no need to embed the secret in the WebChat page. Also when you are using the token it will expire, so you have additional security there as well.

Indeed, you you need put the secret altogether for direct line but there are ways you can handle in you bot code to avoid using to other people.
Follow the below steps:
1) you can pass the domain where you want to implement with user login context.
2) login context will go in bot code and will be check server side that the user which is logged in having authorized to access or to use your chat bot.
3) Restrict your bot to that particular domain.
4) Check authentication in bot using sign in feature via card.
I hope above liners will help you.
do let me know in case you need more help.

Related

Bot Composer Web Chat embed with secure token?

I have a Bot published from Bot Composer into Azure. The bot is a simple QnA Bot. I need to securely embed it within a webpage. The iframe embed code generated has the Bot Key embedded in the URL. How do I secure this so
users cant see the Key,
limit access to users from my tenant?
Thanks in advance.
Generally speaking, if you want to hide something from the end user, you need to place it somewhere where they do not have access to. Normally, you create some kind of script that is running in the backend of your webpage and deals with creating the tokens with your secret key. These "non-critical" tokens need be to be passed to your Web Chat.
The limitation to your tenant user, you need to implement an authentication system.

OAuth2 and Single Page App - ensure client is mine

In a single page app (in my case AngularJS fetched from static at a node.js + express + oauth2orize) what assures me that my client is actually... well my client? (I'm referring to Implicit Grants)
Am I missing something in that some malicious client could simply allow the user to sign in, then request a token with my client ID? Is there a way to sign my client before it is sent? Like a spec I missed out on?
The idea is that my service is a full out OAuth2 provider, but I want to provide a single page app via implicit grant to something like a Dashboard for the user to create and edit info. But I just want to be sure it's my client, the one they got from me.
If you know of specs or methods of assuring this, I'd like to see those docs. My guess right now is to generate a unique cert every time the client is requested (initial or refresh) and have that sent back in session on login.
If your client is using client flow, then no. All you can do is obfuscate your code and client id. If you are really concerned, then perhaps use the server flow. So your client will ask your server for the token and your server can take whatever precautions you see fit. Same Origin Policy will then provide you with some protection that the client code came from your site.

How to authenticate requests using ServiceStack, own user repository, and device ids?

I'm building a mobile app and a ServiceStack web service back-end. The Authentication stuff in ServiceStack looks great but easy to get lost in its flexibility - guidance much appreciated. I'll be using my own db tables for storing users etc within the web service. I'd like to have a registration process and subsequent authentication something like this:
the user initially provides just an email address, my web service then emails a registration key to the user
the user enters the key. The app sends to the web service for registration: email, key & a unique device identifier.
the web service verifies the key and stores the email & device id. It responds back with an auth token that the app will use for later authentication.
Then subsequent web service requests would provide the device id and auth token (or a hash created with it). The app is not very chatty so I'm tempted to send the authentication details on each web request.
Question 1: Should I hook into ServiceStack's registration API or just add a couple of custom web service calls? e.g. without using ServiceStack's registration I would:
post to a registration web service with the email address and device id. My web service would send the registration email with a key and add a record to the user db table.
when the user enters the key it would again post to the registration web service, this time also with the key. My web service would validate the key and update the user table marking the user as registered, creating and recording the auth token & returning it to the caller
subsequent requests would be sent using http basic auth with the device id as username and the auth token as password. The service is not very chatty so creds will be sent with each request.
I'll implement a CredentialsAuthProvider that'll get the creds with httpRequest.GetBasicAuthUserAndPassword() and validate them against the db data.
But it feels like I should use registration built in to ServiceStack.
Question 2: What's wrong with passing the authentication details with each request? This would make it easier for composing my app requests but it doesn't seem 'done' based on the ServiceStack examples. Presumably that's because it's inefficient if you have lots of requests to need to re-authenticate every call - any other reasons? My app will only make a single web request at most every few minutes so it seems simpler to avoid having sessions and just re-auth each request.
Question 3: Am I on the right track subclassing CredentialsAuthProvider?
Question 4: Is there any point using the auth token to generate a hash instead of sending the auth token each time? All communication will be over https.
Answer1: It will be OK. if you give multiple call as per requirement. Normally authentication works based on cookie, now you can store it on client and/or on server and match the user with it. Again here if you are using device you, can always use device instead of user to map and authenticate user. Based on your requirement.
I will prefer to use provider as it hides many details which you need to do manually instead. You are on right track. There are many blogs specifically for authentication and how to create custom authentication with service stack. If you like let me know I have book marked some will give it you. Best way to search latest one is checkout twitter account of Servicestack.
Answer2: This is again, I say as per requirement. Now if your user will be in WIFI zone only. (Mostly true for business users), then there is not limit for calls. Just give a API call and do the authentication in background. Simple JSON token will not hurt, It is few bytes only. But again if you have big user base who is not using good internet connection then it will be better to store authentication detail on device and check against that. Just to save a network call. In any case network call is resource heavy.
Answer3: Yes you are on a right track. Still check out blog entries for more details. I don't remember the code snippet and how it works with last update so I am not putting up code here.
Answer4: This is answer is little complicated. Passing data over https and saving user from Identity fraud is little different thing. Now, if you are not generating auth token (hash based value) then you can pass user also over the http or https. Now, this can be used by another user to mock first user and send data. Even data is being passed through https but still data is getting mocked. Hashed based value is used to avoid this situation. And also there are couple of other business use cases can be covered using auth token.
Please let me know if I have understand you questions correctly and answered them?? or If any further details is required??

How do I secure REST API calls?

I'm developing the restful web app that using some popular web framework on the backend, say (rails, sinatra, flask, express.js). Ideally, I want to develop client side with Backbone.js. How do I let only my javascript client side interact with those API calls? I don't want those API calls to be public and be called by curl or simply by entering the link on browser.
As a first principle, if your API is consumed by your JS client, you have to assume, that it is public: A simple JS debugger puts an attacker into a position, where he can send a byte-for-byte identical request from a tool of his choice.
That said, if I read your question correctly, this is not, what you want to avoid: What you really don't want to happen is, that your API is consumed (on a regular basis) without your JS client being involved. Here are some ideas on how to if not enforce, then at least encourage using your client:
I am sure, your API has some sort of authentication field (e.g. Hash computed on the client). If not, take a look at This SO question. Make sure you use a salt (or even API key) that is given to your JS client on a session basis (a.o.t. hardcoded). This way, an unauthorized consumer of your API is forced into much more work.
On loading the JS client, remember some HTTP headers (user agent comes to mind) and the IP address and ask for reauthentication if they change, employing blacklists for the usual suspects. This forces an attacker to do his homework more thoroughly again.
On the server side, remember the last few API calls, and before allowing another one, check if business logic allows for the new one right now: This denies an attacker the ability to concentrate many of his sessions into one session with your server: In combination with the other measures, this will make an abuser easy detectable.
I might not have said that with the necessary clarity: I consider it impossible to make it completely impossible for an abuser to consume your service, but you can make it so hard, it might not be worth the hassle.
You should implement some sort of authentication system. One good way to handle this is to define some expected header variables. For example, you can have an auth/login API call that returns a session token. Subsequent calls to your API will expect a session token to be set in an HTTP header variable with a specific name like 'your-api-token'.
Alternatively many systems create access tokens or keys that are expected (like youtube, facebook or twitter) using some sort of api account system. In those cases, your client would have to store these in some manner in the client.
Then it's simply a matter of adding a check for the session into your REST framework and throwing an exception. If at all possible the status code (to be restful) would be a 401 error.
There's an open standard now called "JSON Web Token",
see https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for
creating tokens that assert some number of claims. For example, a
server could generate a token that has the claim "logged in as admin"
and provide that to a client. The client could then use that token to
prove that they are logged in as admin. The tokens are signed by the
server's key, so the server is able to verify that the token is
legitimate. The tokens are designed to be compact, URL-safe and usable
especially in web browser single sign-on (SSO) context. JWT claims can
be typically used to pass identity of authenticated users between an
identity provider and a service provider, or any other type of claims
as required by business processes.[1][2] The tokens can also be
authenticated and encrypted.[3][4]
Set a SESSION var on the server when the client first loads your index.html (or backbone.js etc.)
Check this var on the server-side on every API call.
P.S. this is not a "security" solution!!! This is just to ease the load on your server so people don't abuse it or "hotlink" your API from other websites and apps.
Excuse me #MarkAmery and Eugene, but that is incorrect.
Your js+html (client) app running in the browser CAN be set up to exclude unauthorized direct calls to the API as follows:
First step: Set up the API to require authentication. The client must first authenticate itself via the server (or some other security server) for example asking the human user to provide the correct password.
Before authentication the calls to the API are not accepted.
During authentication a "token" is returned.
After authentication only API calls with the authentication "token" will be accepted.
Of course at this stage only authorized users who have the password can access the API, although if they are programmers debugging the app, they can access it directly for testing purposes.
Second step: Now set up an extra security API, that is to be called within a short limit of time after the client js+html app was initially requested from the server. This "callback" will tell the server that the client was downloaded successfully. Restrict your REST API calls to work only if the client was requested recently and successfully.
Now in order to use your API they must first download the client and actually run it in a browser. Only after successfully receiving the callback, and then user entry within a short frame of time, will the API accept calls.
So you do not have to worry that this may be an unauthorized user without credentials.
(The title of the question, 'How do I secure REST API calls', and from most of what you say, that is your major concern, and not the literal question of HOW your API is called, but rather BY WHOM, correct?)
Here's what I do:
Secure the API with an HTTP Header with calls such as X-APITOKEN:
Use session variables in PHP. Have a login system in place and save the user token in session variables.
Call JS code with Ajax to PHP and use the session variable with curl to call the API. That way, if the session variable is not set, it won't call and the PHP code contains the Access Token to the API.

using facebook client flow to authnticate and login on app/site

Other then the fact that when using facebook's client-flow you get an access token right away, and when using the server-flow you first get an authorization code that you have to exchange for an access token, What is the difference between the two flows and when should I use each of them ?
more specifically can I use client-flow and still be able to securely log a user into my application/site?
At first glance I though that I could take the access_token and id I got on the client (via client-flow), send them to my server and then if a graph api call for that ID and token does not break I can assume I am dealing with this user and log him into my site based on his FB ID.
On second thought it looks to me that If I don't follow the server-flow there is no way to securely use the client id & access_token to log the user into my application/site.
The reason I say this is that another (hacker) app owner that "shares" a user with my app. might take the access_token and and ID he (illegitimately) got for user on his authorization flow, and fake a call to my site with this data causing me to log him in as if he was this user.
Am I missing something here?
Should this not be written in big red letters on the first paragraph of https://developers.facebook.com/docs/authentication/ ?
Oauth 2 (http://oauth.net/2/) is what Facebook uses. For the most part it is the most secure interface available. If there was a way for a user to take an access token for one app and then use it in another app, then oauth2 will need to be patched (or Facebook oauth2 will need to be patched).
If you think you found a way to hack it, then you should get your $500.00 prize from http://www.facebook.com/whitehat/bounty

Resources