Hot Towel/Durandal/Breeze.js: how to vertically secure data calls? - asp.net-web-api

I'm new to the whole client-side SPA world. I'm using the above technologies, which seem quite promising. However, one huge snag that I can't get over easily is the lack of built-in security. I had to manually roll out the user authorization, which IMHO should be part of the framework.
Now that I have that sorted, I'm getting major headaches with vertical security: where one user is logged in but can easily access other users' info by changing a few parameters in the browser console. I could pass the userId with every call and then compare it with the one on the server, but I was hoping that there would be an overarching solution that doesn't pollute the breeze data calls with user ids.
For example, let's say there's a call from the data service like this:
function getItems(){
var query = breeze.EntityQuery.from('Items').expand("Person");
return manager.executeQuery(query);
}
this will get all the items, not good. So let's limit by userId:
function getItems(userId){
var query = breeze.EntityQuery.from('Items').where("userId", "==", authentication.userId).expand("Person");
return manager.executeQuery(query);
}
in the second example, we get the userId from the authentication service, which stored the userId when the user was logged in. However, a malicious user can easily go the browser console and change that value.
Of course, I could pass the userId using withParameters(...) and compare it with the current one on the server, but I'd have to do that for every call, which doesn't seem right. Is there a better way to secure calls with the trusted user id?

#Ali - I understand your pain and your concern. You are right to fear any form of so-called security that relies on information passed in the URL. Fortunately there are excellent answers to your concerns and Breeze apps work well with them.
For example, have you studied the ASP.NET Breeze/Knockout Template? It uses Forms Auth for authentication and guards the Web API controller with an [Authorize] attribute. Only logged-in users can access any of the controller methods.
That authentication also sets the IPrincipal which the Web API controller makes available through its User property. You'll see User passed to the constructor of the TodoRepository. In that repository you'll find guard logic to restrict query and saves to just the Todo information belonging to the requesting user.
Look at the network traffic. You won't find any user identifying information in the URL or the request/response bodies. You will see an encrypted authentication cookie in a header.
An obvious flaw in the example is that the client/server traffic takes place in the clear. You must add transport level security (HTTPS) before you go to production. But this is a demo after all.

Why not just do this in the controller?
If the Web Api is secured with [Authorize] then you can get the users ID in the controller and make sure that the data returned is for the currently logged in user.

Related

Best way to store user related data from db, in a webapp with OIDC authentication

I have a Core3.1 web application protected with azureAD (OpenIdConnect) and I retrieve most of the user's related data I need, from the idtoken:
Username, email, employeeId, even the user's AD groups.
I also need to get some additional data from the database and I'm not sure how I should store this data in the application, to make it available everywhere and for the entire time the user is logged in.
I don't want to use cookie. For now, I used the session.
Problem is this session expires differently from the authentication session, so I had to call a static method to check if the variables are empty and eventually doing the query again.
It works... but is ugly.
I feel like I'm supposed to handle things differently but I don't know how.
A claims based solution can work best here, where you:
Define a Claims Object in your API
Populate it when your API first receives an access token
Cache the claims object for subsequent requests with the same access token
This cache will always be in sync with the user session
See my blog post for further details on the pattern. And here is some implementation code.

Gin-Gonic Restricting Routes

My webapp has means of abuse, users can access things they're not supposed to, such as 127.0.0.1/users/1 & 127.0.0.1/users/2 & 127.0.0.1/users/3 and so on, within these it reveals the user's registration email, ip, etc (via JSON, so the web server can return customized messages, greetings, and allow users to edit account data within profile settings)
This is what my route looks like:
forum.GET("/users/:user_id", routeFunc(UsersGET))
I'm using Gin-Gonic HTTP framework to create a dummy forum, can someone tell me how to stop users from accessing the /users/ route whilst allowing the actual web server to use freely? and maybe link me to the correct direction. Thanks!
(The server uses it to return things like, Welcome Back, USERNAME).
You need to add authentication and authorization to your server.
Authentication is where a user will prove their identity to you by means of a shared secret (like a password hash) and authorization is where you check if that authenticated user is allowed to take the action they are trying to make.
There are many third party services that might help you with this (e.g. Auth0) where they can handle authentication for you and provide you with libraries for authorization.
Usually people bind authentication into their Gin-Gonic server by means of middleware (e.g. gin-jwt) which is run in front of every http request. Once that middleware authenticates the user, you can add some logic to your handle that states only users can only view themselves.
Hope this helps. Good luck.

Implementing JWT with Spring security without users

I would like to set up an IT solution based on the Front / Back principle.
Front side I would use a technology like React, Angular and Back side I would use a technology like java spring boot to implement controller Rest.
The front will make Rest requests on the back to retrieve data.
I would like to add a security concept to the solution by implementing the JWT standard on the back. Thus the client, knowing the secret, could request a token back and could make requests by specifying the token via the header of the request.
I found several tutorials explaining how to set up this type of solutions. In particular: https://medium.com/#nydiarra/secure-...n-e57a25806c50
In this tutorial, we assume that we define somewhere (here in a H2 database) the different users of the app and their role (admin or standard).
So the front could ask a token but it would have to indicate the user and his password and the secret defined. The back looks in the database and gives a token relative to the role defined for this user.
My question is simple. Do we have to define users and roles if we want to use JWT?
What I would have liked to do is not to inform and not to store potential users and their roles.
Simply the front requests a token with the secret without giving user and the back gives a token. Which will be used later in the header of the requests.

AJAX calls within MVC and Identity Server

I have been playing with Thinktecture IdentityServer3 and am keen to use it as the product looks great. However, I don't fully understand how to accomplish my flow which is probably fairly common:
Create Identity Server using Implicit flow
Setup an MVC web site
Setup a separate Web API
So far so good, as demonstrated in the examples on the site. I now wish to call the API using AJAX calls directly but for this i need an access token. It seems like a large overhead to have to route these through the MVC site itself (again, in the examples).
How can I accomplish this flow? Would it essentially blend the MVC and Javascript Client samples or is there a smoother way so the user only has to sign in once? Perhaps send the access token in a hidden field but then how would it renew?
Any help on understanding this would be great.
I've managed to come up with a solution which seems to work, not sure if it's best practice though...
Expose a method on the MVC site at AJAX/AccessToken
Method should be locked down with Authorize attribute to ensure the MVC part of the site is authenticating properly with IdentityServer
Method returns the users Access Token which was generated through the above call via MVC controllers
In JavaScript, simply use this endpoint to get an Access Token and then call the API manually
The call to get the Access Token should be secure as its within the same domain/authentication model as the MVC site itself
I've put up a sample here for anyone interested:
OIDC-Website
Check out the form post client to see the endpoints being called explicitly. You will need to hit the token endpoint to get your access token.
You should be able to use these endpoints in your AJAX calls, store the received claims and tokens in a cookie and take it from there.
Note that to renew the access token, you will also need to store the refresh token. The Implicit flow does not allow for refresh tokens (you'll need to use the Authorization Code Flow or the Hybrid Flow).

How to block external http requests? (securing AJAX calls)

I want to use post to update a database and don't want people doing it manually, i.e., it should only be possible through AJAX in a client. Is there some well known cryptographic trick to use in this scenario?
Say I'm issuing a GET request to insert a new user into my database at site.com/adduser/<userid>. Someone could overpopulate my database by issuing fake requests.
There is no way to avoid forged requests in this case, as the client browser already has everything necessary to make the request; it is only a matter of some debugging for a malicious user to figure out how to make arbitrary requests to your backend, and probably even using your own code to make it easier. You don't need "cryptographic tricks", you need only obfuscation, and that will only make forging a bit inconvenient, but still not impossible.
It can be achieved.
Whenever you render a page which is supposed to make such request. Generate a random token and store it in session (for authenticated user) or database (in case this request is publicly allowed).
and instead of calling site.com/adduser/<userid> call site.com/adduser/<userid>/<token>
whenever you receive such request if the token is valid or not (from session or database)
In case token is correct, process the request and remove used token from session / db
In case token is incorrect, reject the request.
I don't really need to restrict access to the server (although that would be great), I'm looking for a cryptographic trick that would allow the server to know when things are coming from the app and not forged by the user using a sniffed token.
You cannot do this. It's almost one of the fundamental problems with client/server applications. Here's why it doesn't work: Say you had a way for your client app to authenticate itself to the server - whether it's a secret password or some other method. The information that the app needs is necessarily accessible to the app (the password is hidden in there somewhere, or whatever). But because it runs on the user's computer, that means they also have access to this information: All they need is to look at the source, or the binary, or the network traffic between your app and the server, and eventually they will figure out the mechanism by which your app authenticates, and replicate it. Maybe they'll even copy it. Maybe they'll write a clever hack to make your app do the heavy lifting (You can always just send fake user input to the app). But no matter how, they've got all the information required, and there is no way to stop them from having it that wouldn't also stop your app from having it.
Prevent Direct Access To File Called By ajax Function seems to address the question.
You can (among other solutions, I'm sure)...
use session management (log in to create a session);
send a unique key to the client which needs to be returned before it expires (can't
be re-used, and can't be stored for use later on);
and/or set headers as in the linked answer.
But anything can be spoofed if people try hard enough. The only completely secure system is one which no-one can access at all.
This is the same problem as CSRF - and the solution is the same: use a token in the AJAX request which you've perviously stored eslewhere (or can regenerate, e.g. by encrypting the parameters using the sessin id as a key). Chriss Shiflett has some sensible notes on this, and there's an OWASP project for detecting CSRF with PHP
This is some authorization issue: only authorized requests should result in the creation of a new user. So when receiving such a request, your sever needs to check whether it’s from a client that is authorized to create new users.
Now the main issue is how to decide what request is authorized. In most cases, this is done via user roles and/or some ticketing system. With user roles, you’ll have additional problems to solve like user identification and user authentication. But if that is already solved, you can easily map the users onto roles like Alice is an admin and Bob is a regular user and only admins are authorized to create new users.
It works like any other web page: login authentication, check the referrer.
The solution is adding the bold line to ajax requests. Also you should look to basic authentication, this will not be the only protector. You can catch the incomes with these code from your ajax page
Ajax Call
function callit()
{
if(window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function(){if(xmlhttp.readyState==4&&xmlhttp.status==200){document.getElementById('alp').innerHTML=xmlhttp.responseText;}}
xmlhttp.open("get", "call.asp", true);
**xmlhttp.setRequestHeader("X-Requested-With","XMLHttpRequest");**
xmlhttp.send();
}
PHP/ASP Requested Page Answer
ASP
If Request.ServerVariables("HTTP_X-Requested-With") = "XMLHttpRequest" Then
'Do stuff
Else
'Kill it
End If
PHP
if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
//Do stuff
} else {
//Kill it
}

Resources