In Laravel, you can restrict access to some Controllers (eg. Admin-related controllers such as Admin/UsersController, Admin/SettingsController, etc.) to specific user sessions. Because it's server-side, the user has no-way to snoop-out about such controllers unless authenticated.
In the case of AngularJs's, the code resides in the browser. Thus, anyone can get a look at the javascript source codes and might figure-out the behaviour of the app. Say he might discover that there are controllers that manage admin-related data. Or anyone might try to brute-force-search the app's URL for javascript files to observe. Say he looks at http://myapp.com/AdminSettingsController.js in which authenticated users should only be able to see or should not at all.
Going back to the main question, how do you resolve such issues?
This problem has only one solution. Treat JavaScript as language for your User Interface only. Nothing more than that. Don't store any sensitive data in browser, don't store any sensitive logic (e.g. database queries) either. There is no way to hide network traffic or source code from client.
I usually create some sort of user object on client side, which contains users role for resolving permissions, and I use the permission for display controls, e.g. show some buttons only to admin etc. BUT, this only affects the displaying of the page, If user interacts with that controls, the controls rely on the server and if the user does not have proper permissions on the server as well, the interaction with the control fails, so if anyone with some knowledge change the user object on the client and grants him administrator role, he only sees the control what the administrator would see, but he can not make administrator actions nor he sees any sensitive data.
Related
From the server I get a list of places that the session user has access to.
Now I want to store these roles where I can show or not display the route or buttons for the user. Where is the best place to store this data in Angular?
Short answer
Inside of a service.
Why?
You mention that you receive a list of places from the server: the client can use for example Chrome's Developer Tools to inspect the network traffic and just read the list of places there.
You should secure the access to your routes and content server side, and don't worry about the client-side "security". The user has access to the full client-side source code. If the client-side environment can decrypt or access something, then eventually so can the client.
There's many kind of storage available on the client side: There's the LocalStorage API for persistent storage, or you can make an Angular service that transiently stores the retrieved role information. But just keep in mind that your user can read everything that you write in your Angular application, so trying to keep buttons or routes hidden won't work on power users going through your code.
I am new to Javascript and have been using a global boolean hasAccessPermissions that retrieves data from an API to store if the user has admin privileges or not.
And with this data, I am showing some elements of the screen only to admin users. However, I've been told that it is a security breach, since the non-admin user has access to this code and can see and alter what he sees by editing my boolean locally.
How can I hide UI elements based on user access privileges in JS 'the correct way' ?
Answering my own question, since it's been a while without an answer.
You don't. Everything that runs in JS can be viewed and modified by the user, you would need to handle user permissions on the server-side.
I want to implement authorization in AngularJS. In my project which is some kind of social media, different roles or even same roles may see a view file differently.
For example imagine we have two different roles: customer and company.
A customer and a company may have different things in a shared view file, for example a company can have rate on his profile while a customer can't. (different roles).
Or a customer may see a button in a page while another customer can't. (same roles)
As you can see I can't implement authorization by simply checking the roles, and in some situations I need to communicate to the server.
I have multiple choices:
Create a variable in my controller's scope with corresponding permissions, which they have default value of false:
$scope.auth = {
canRate: false,
isConnected: false
};
Then connect to server and change the value of auth object based on the response. And use ng-if in my view files to show or hide elements.
Create a directive and pass comma-separated permissions to it.
<button auth="canRate,isConnected"></button>
Then connect to server to check the permissions. If all of them where true, then show the element.
Use resolve: {...} and get all necessary data from the server when routing, which increases loading time of each page.
I want to know is there a better approach to solve this problem?
Any kind of help or comment would be greatly appreciated.
Note: Of course I have server side authentication and authorization! I just want to show some elements in a view file based on user roles or some other conditions which I explained. And this elements are something like a button or a link, otherwise instead of using a shared view and hiding elements, I could use different views for each situation.
Any how, I know this approaches are for display purposes only, and they can not solve security challenges.
First things first, I LOVE AngularJS. But, like all web client frameworks, in a strict sense you can't implement Authorization in AngularJS.
You can not trust the web client to hide data from the user. If the server sends the data to the client, they can still find a way to see it (using fiddler for example) even if you use ng-hide to avoid displaying it.
So, you must implement Authorization on the server side. Now then, assuming you do that:
AngularJS is great for building dynamic web interfaces based on the data you receive from the server. So, your server should only send the data your client is allowed to see. Then, you can use ng-hide or ng-if to avoid displaying the components that would otherwise show that data.
Furthermore, your server can even send an object that contains the list of possible actions available to the user. And then you could use ng-hide in your buttons so as not to show them when the action isn't available.
Even still, you will need to code your server side to ignore actions that the user isn't allowed to take.
Your approach will work, but it is not secure. I would make sure that the server handles the authentication as well. Personally, I've always used a server-side token based authentication system when working with AngularJS.
Instead of using ng-if, you should make your GET or POST requests require the token given on login. From there the server can determine whether or not to allow the request to succeed, with no chance of the user faking credentials. Both of your examples work fine, but use them as a means to hide things for display purposes only. The web client will NOT keep sensitive information safe or prevent the possibility of POST requests from unwanted users.
I need to understand and maybe ideas about single page apps.
I want to create a project, i'll do it with MVC. I also want to use AngularJS for client side programming.
I know that AngularJS is good for single page applications and when working with SPAs you send your data to API to process. But data sent from Angular is visible to user and open to be manipulated.
I don't want users to be able to see any data or access to the API from the internet. Witch way i should follow?
I'm thinking about keeping sensitive user data in MVC controller. For example let's say user Id is very sensitive for my project. If i keep user id in javascript variable, when i'm sending it to API with some command user will able to change the id and manipulate the system. But if i keep user-id in MVC controller, via user authentication, and send request to my MVC controller then the user won't be able to change it. But i know this is not the best way of doing things, there must be a more clever way.
I'll be glad if someone can explain how this things works in SPAs or when you use Angular and MVC together.
This won't work, you can't prevent user from tampering the data, crafting custom request and doing whatever she wants at her side.
What you should do is to never trust upcoming data - which means validate every incoming id twice, once when you produce it and then when it comes back. Either it comes plain and you verify if it's legal or you encrypt it so when it comes back you decrypt it.
Some data can be stored at the server side, the id you mention is such example. This way user never sees the data, what you pass is the session id which is a long random value, rather impossible to craft. This approach comes with the cost of server side resources that are used, the more users the more resources at the server stored between requests.
Say, a link to a person is sent to a user via email. If the person is already logged into the webpage in his/her browser, clicking on the link takes him/her to the page. However, if he/she is not logged in, he/she should be asked to login in order to access the page. Is there a way to achieve the above functionality using jquery, javascript?
Yes. Build a back-end authentication system, using AJAX and whatever your server-side language is.
From there, develop a hypermedia-style of content-system, and a modular, "widget"-based application delivery model.
Within your hypermedia responses to login (plus passing whatever relevant path information was gained from the e-mail), either redirect the page to a new page (based on the linked response from the server), or download the widgets requested from the server (for whatever application you're displaying media in), and then stream in AJAX content (again, from a URL dictated by the server-response).
This is about as close as you're going to get to security, in terms of delivering things to the client, in real-time, with authentication.
If you were to load the reports/gallery/game/whatever, and put a div over it, and ask for users to log in, then smart users can just kill the div.
If you include the content, or include the application components (JS files), or even include the links to the JS files which will request and display the content, then clever people are again going to disassemble that, in 20 seconds, flat.
The only way I can see to do this is to have a common request-point, to touch the server, and conditionally load your application, based on "next-steps" URLs, passed to the client, based on successful authorization and/or successfully completing whatever the previous step was, plus doing authentication of some form on each request (REST-based tokens+nonces, or otherwise)...
This would keep the content (and any application-structure which might have vulnerabilities) from the client, until you can guarantee that the client has been properly authorized, and the entire application is running inside of multiple enclosed/sandboxed modules, with no direct access to one another, and only instance-based access to a shared-library.
Is it worth the work?
Who knows.
Are we talking about a NORAD nuclear-launch iPhone app, which must run in JavaScript?
Then no, engineering this whole thing for the next six months isn't overboard.
And again, all of this security falls over as soon as one person leaves themselves logged-in, and leaves their phone on the table (biometric authentication as well, then?).
Are we talking about a gallery or discount-offers that you want to prevent people to log into, so you know that only the invited people are using them?
Well, then an 18-month project to engineer, develop, debug and deploy a system like this is probably going to be overkill.
In this case, perhaps you can just do your best to prevent the average person from stealing your content or using your cut-prices, and accept that people who take the time to dig into and reverse-engineer everything are going to find a way to get what they want, 95 times out of 100.
In that case, perhaps just putting a login div overtop of the page IS what you're going to be looking for...
If you're dealing with, say a company back-end, or with company fiscals or end-user, private-data, or anything of the sort, then aside from meeting legal requirements for collection/display/storage, how much extra work you put into the security of the system depends on how much your company's willing to pay to do it.
If it makes you feel better, there are companies out there that pay $60,000-$150,000 a year, to use JS tracking/testing programs from Adobe. Those programs sit right there, on the webpage, most of the time, for anybody to see, as long as you know where to look.
So this isn't exactly an unknown problem.
Yes it is. By authenticating (login) you can store a "loggedIn" cookie which you have to delete by session end (logout or closing the browser). You can use that cookie to check if somebody is logged in or not. If not logged in, than you can display the login page and send the login request with ajax. Btw it is not a good practice to use hybrid applications like that. It is better to use SPA-s with REST service, or implement this on server side.