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.
Related
I'm working on customizing the landing page in our company's Acumatica Customer Portal by using a Wiki page, and I need to modify the displayed HTML elements based on the user's role, as well as write the user's name into one of the HTML elements.
What I'm trying to find, is a way to make an Acumatica function call maybe using Javascript, that returns the user's name and role, or maybe an API call I could make to get the same information.
What I've found / tried
I found that there's a function that returns the user name in this post, and I've tried to find ways to run it from Javascript, when the landing page loads, but haven't been able to make it work.
I also found that I can make API calls to Acumatica, and it gives a lot of options to retrieve production related data, but apparently none of the available endpoints directs to the current user's profile (which is screen SP408045 in the portal).
Thanks in advance for your help
There can be multiple users logged in at the same time.
System Monitor page lists logged in users:
An API call couldn't figure out which user you want.
With JavaScript you can try Cross Site scripting and parse the HTML element to find the logged-in user and roles. On Acumatica side the editor control values can be read with px_alls global javascript object. In both cases the logged-in user information must be present in the page. This means the pages have to be customized to add those elements. They can be hidden from UI but must be present in HTML source.
In the firebase API
https://firebase.google.com/docs/auth/web/manage-users
we can delete users, but how could we prevent users from simply registering again, in the GUI for firebase we have the option to disable users , how could we do this in the program, for example if we are building a admin panel that checks posts for a listing site that have been reported, and we want to disable the creator or the reporter for spamming as part of availiable actions.
Thanks.
I develop in react if that changes the answer.
To prevent the user from re-registering, you should disable account instead of deleting it. This will prevent the user from signing in again, and from refreshing their ID token. If you want to do this programmatically, have a look at updating a user with the Admin SDKs. For example, in Node.js it'd be:
admin.auth().updateUser(uid, { disabled: true })
Keep in mind however that even after disabling the account, their existing ID token will remain valid until it expires (typically within an hour), and cannot be revoked. If you want to prevent them from posting in the meantime, you'll also want to keep a list of blacklisted/blocked UIDs somewhere, and check against that list before allowing them to write/access the data.
You will not be able to programmatically disable a user from the frontend of your app. You will need a backend, and use the Firebase Admin SDK to update the user account to become disabled. The API is updateUser.
Well they can always register again (in case the website is public/ not invite-only), with completely different credentials.
You can do a matching of the new data and existing blocked users, and if it matches above a threshold, flag them.
And you can improve your reporting, the faster you detect a user who should be blocked, the better.
Can't say I'm super familiar with Firebase but ill try and help (can't hurt).
Have you tried to blacklist the IP of the user in question?
Hope I helped :)
Have a good day!
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.
I'm trying to write a javascript single-page-app that allows users to login and then, once logged in, create/modify records in a database. I'd like to avoid having my own server side scripts if possible, instead using something like Parse.com, Kinvey.com, or Cloudmine.me.
My issue is that these services have user login capacity but use API keys to determine whether your app has write access. They don't seem to let you have write access once your user is logged in. The only way I can think of to accomplish this is to store a write-access API key in the user's user data, so I'd have the user login, fetch the hidden API key, then change the API key of the app to use that one, so they'll have write access. Obviously this isn't very secure because once that API key is sent over the network, that user will have write-access even if we delete their account or they change their password.
Perhaps I'm going about this the wrong way, so feel free to let me know. Hopefully this made sense. Thanks!
You should be able to restrict access to a group of users using Parse.ACL: http://www.parse.com/docs/js/symbols/Parse.ACL.html
If you want to control access on a per user basis then you will have to maintain a custom property on the user object. Then you can check the custom property in the BeforeSaveRequest() function and decide whether the user has write access: http://www.parse.com/docs/js/symbols/Parse.Cloud.BeforeSaveRequest.html
By default, most BaaS providers should provide collection level security and some even offer per entry security via ACL's (Access Control Lists).
Kinvey for instance has several variations on collection level security:
http://devcenter.kinvey.com/html5/guides/security#Collectionlevelpermissions
The default security level of Shared make it so the user has access to read everything in the collection but can only write to their own items. You may also want to use the Private security level to make it so you can only read and write to your own items.
If you want to have more fine-grained control over security you can utilize entry level permissions:
http://devcenter.kinvey.com/html5/guides/security#Entitylevelpermissions
With entry level permissions you can give fine grained access to a specific user or groups of users that you manage. You can even determine what level of security a user has to your entry, read or write. If you have a need to go even finer with control you have full access to write your own security utilizing Business Logic.
Full Disclosure - I am an engineer at Kinvey.
I'd like to securely save a user's credentials to related web sites and automatically log them into those sites when they log onto ours. I understand there are some security implications to this, so I'd like others' feedback and see what has been successful for others in the past.
What technique have you used to auto-log the users in? I'd prefer not to have to duplicate the HTML form and submit it through javascript. This seems error-prone if the form ever changes. I tried putting the login form inside an iframe, but it seems like the owners of the site are able to block this (see attached screenshot). Do you know how they do this?
Secondly, what was your approach to save the credentials so that they were "safe".
...Peter
I would suggest using cookies to save a session certificate to the users machine. A good value for such a cookie would be;
userid, timestamp, hash(userid . timestamp . global_secret)
The value of global_secret needs to be very long (40 characters or so), to avoid people cracking the hash, as doing so would allow them to create their own credentials with other peoples user ids!
The 'other sites' would check for this cookie, calculate the hash using the cleartext values of userid, timestamp and the global_secret (which all sites know), check it against the hash supplied, if they match, then this is a valid certificate.
You would then need to check the timestamp and decide if this was a 'new' enough certificate to allow access.
This is the standard method.
Do not do this. Read the terms of services for each site (ie facebook):
https://www.facebook.com/terms.php?ref=pf
(3.2) You will not collect users' content or information, or otherwise access Facebook, using automated means (such as harvesting bots, robots, spiders, or scrapers) without our permission.
(3.5) You will not solicit login information or access an account belonging to someone else.
(4.8) You will not share your password, (or in the case of developers, your secret key), let anyone else access your account, or do anything else that might jeopardize the security of your account.
You put yourself and the user at risk.
These sites have an API for a reason, so I suggest you looking using those as a more "legal" approach.
So if you're trying to retrieve a facebook user's information, create an app, have them authorize your app, then retrieve the information through facebook's api (example). You can also post to their wall with this method.
https://developers.facebook.com/
https://dev.twitter.com/
https://developers.google.com/
The common method to auto login a user is to set an cookie with an random string. It have to be that the random string isn't guessable. At the server you check the cookie and if it matches then you login the user. But if your site isn't completely served with https everyone who can listen to the traffic can pretend to be the user. To increase the security a little bit you could implement that a random string is only valid for a view days and then the user has to login again and a new random string is generated. So if someone steals the cookie-id the attacker has only for a certain time access to the account.