Implementing Security for Ajax calls - ajax

I am facing difficulty in making my Ajax request secure.
The problem is Data tampering. I have read about this problem and it is suggested that never trust the information what ever is coming from client. It can be very well changed using fiddler or any such tool. We need to validate in server side as well. But my question is how to validate.
Let's see one example.
Suppose I have Employee information in database and I have exposed one method GetEmployeeDetailByEmployeeId. Before any employee make this request he will be authenticated with userId and password and authorized whether user of this type are allowed to make this request or not.
But if one employee gives employeeId of some other employee, he will actually gets the data which he is not supposed to see. To fix this issue we have two solution
1. We should check the request against the database, whether the information requested by the person is meant for him or he is the manager of that guy
2. We should somehow validate in app layer itself whether we should reject the call or not.
First approach is performance intensive where I have to make database request and finding the association of record, also it will add cost to development.
Pls suggest which way to go and do we have any better solution to solve this kind of problem.

Clearly you need to check it at your back-end side, otherwise your application is likely to exploit by a kid.
Update
you need to implement an authorisation mechanism in your back-end, then after you load the permissions at the beginning, you can add it to the user session, so you don't need to look-up the database each time, you just need to check the user permission against the task required permission.
More
To implement the authentication mechanism: Goal, user can see it's own profile but supervisor can see everyone within his department.
user A has the user_id already loaded at the session, let say user_id = 123
user A can only request his information so if (user_id == req_user_id) then show the information, otherwise show error.
user B has the permission value of 100, let's call him supervisor then. Now if (user_id == req_profile_id) is not true we will check the permission. Let say the task permission for this particular task is 10 so if (user_perm >= task_perm), go ahead and check the department, if both the requested user and current user are at the same department, then show the information, otherwise show an error.
this should works based on your information.

Related

Allow admin user to login as other users

Is there any way to login other users account for admin user ?
Currently authentication based on Meteor Accounts
I saw this post but didn't working at all now.
The feature is important for us because when user have problem in system then admin need to see it this by simulating user account.
Thanks in advance.
It seems you want to impersonate a user. This means that you want to have Meteor.userId (or this.userId depending on context) reflect the _id of a specific user both on the client and the server.
afaict the only way to do this is to login as the user. Presumably you don't want to ask the user for their password so you have a couple of choices:
Save their existing password, replace it (temporarily) with a password of your choosing, then after you're done impersonating their account, restore their existing password.
You probably don't want to ask the user for their password and you don't need to. All you need to do is set aside Meteor.user.findOne(userId).services.password.bcrypt, then reset the password to your temporary value, then restore the original bcrypt value later.
The downside is that the original user would not be able to login while you are logged-in. Plus it's really hacky.
Extend Meteor's Accounts package to provide impersonation capability in a more elegant manner.
You might also look at validateLoginAttempt. The docs are unclear as to whether a failed login attempt could be overridden with a successful one but if it could then that would provide another pathway to solve your problem.
Instead of logging in as the users, which requires their password and which is a total no-no, you may use rather alanning:roles and allow the admin to assign the role of any user in order to draw views based the user's role.
This requires a well designed role system.
As a plus you could then at least load the documents associated with the user who you want to support.
This requires a well designed document and data model.
But generally spoken you should rather focus on writing good tests (test driven development) for components as unit tests, integration tests and UI tests.
This will reduce the need to manually view the app as an end user a lot.
The most common end user problems can be reduced by creating a good knowledge base like a wiki or video tutorials.
Even if then an error occurs in the end user side, I would rather try to implement a well designed error log that allows users automatically create tickets on error which also include the error stack.
All the above methods are to be favored before logging in AS THE USER.
As #Jankpunkt has already mentioned alanning-roles I can add something you can use without installing any external package.
Just keep a type key in the profile object of the users collection. Then define some types like 1 for super-admin, 2 for admin, 3 for general etc. Then check the authorisation of particular action by checking the value of user.profile.type key.
Caveats: Make sure you are checking the type in server side. By default profile field is writable from the client end, so if you are putting type field in the profile object make sure that you are not allowing users to modify users collection in the client end.
Here is how to restrict client end update in users collection:
Meteor.users.deny({
update() { return true; }
});
Read more on roles and permissions here:
https://guide.meteor.com/accounts.html#roles-and-permissions

How to uniquely identity a pipedrive account?

We are trying to integrate our platform with Pipedrive. As far as we have researched, in a pipedrive account, there is one admin and he can add multiple users. And the users later can login in their respective accounts.
What we are trying to make sure is that once a Pipedrive account is integrated with our platform, the same account should not be integrated twice. So, I need a unique identifier, that lets me know whether the account has already been integrated.
My initial approach was to check the api key. But it was not successful, since every users in an account have different API Keys.
After a bit of research, I found out that there is an identifier called company_id which is common for all the users in an account. But I could not find anything regarding it in documentation. So, I am not 100% confident to go ahead and implement it in our code.
Does anyone have an idea about this?
Pipedrive support rep here.
The most sure-fire way to ensure this is to make a GET request against http://api.pipedrive.com/v1/users?api_token=your_token_here.
You are correct in assuming the company_id in the additional_data object in the response is static and won't change across any users on the account.
Note that a Pipedrive account may have more than one admin, and that non-admins (regular users) might have visibility (and editing) restrictions in place, which may cause some of your GET, PUT and DELETE requests to fail.
In case you're not doing this already, I'd thus advise filtering the data array from the abovementioned endpoint for user.is_you to equal true and check whether the is_admin property is set to 1 during "registration" to ensure the user setting up the integration is an admin.
Hope this helps!
I'm not quite sure what you're asking for. Are you looking for a unique identifier for each user?
Each user has an id, you can get all users by calling
https://api.pipedrive.com/v1/users?api_token=____
This will return a JSON Object with data on your users, including their names and associated IDs. Admins are just users with different privilege levels. All admins are users, but not all users are admins. All users are part of a company, the company is identified by the first part of the Pipedrive account url ie.
https://FooCompany.pipedrive.com
Are you trying to see if a certain company has been integrated already?

Express.js + Passport.js : How to restrict multiple login by the same user?

Passport by default allows the same user to login from multiple browsers and have unique sessions created. How can I configure it to destroy the first session when the user tries to create a second session?
Currently I'm using the 'Sessions' model to add the username to the record and upon subsequent login check by username if the sessions exists. But this increases traffic to the db. I'm thinking express must be doing it already or made to, keep the 'logged in users' information in memory so that the process can be simplified. I'd be thankful for ideas around how to achieve tweak with express for this purpose or any other workaround/suggestion.
Much thanks!
I saw that at least 4 users upvote this question, so I decided to create passport-strategy for that. The new strategy called passport-one-session-per-user. It's open source strategy you can access here: https://github.com/AminaG/passport-one-session-per-user
How to use it? add it right after session. For example:
app.use(passport.session())
var passportOneSessionPerUser=require('passport-one-session-per-user')
passport.use(new passportOneSessionPerUser())
app.use(passport.authenticate('passport-one-session-per-user'))
Not need for settings, or configuration.
How it is works?
The strategy, created an array that contain serializaed user objects, and sessionID.
Every time user logged in, the strategy check if the user already logged in. If so, it's flag the other session. The next time the user in the other session make a request, the strategy see the flag, and log the user out.
I'm thinking express must be doing it already or made to, keep the 'logged in users' information in memory so that the process can be simplified.
I believe the session model loggs the user in, and saves only that logged-in-ness in the session cookie. The server itself has no clue about who is logged in, but just checks this state in the (signed) session cookie provided by the browser.
You can write your own Passport.js strategy to handle it differently.

Dynamics CRM in low-trust helpdesk scenario

Ok, so imagine a bank has a call-centre filled with low-trust staff. The staff need to provide basic service to customers over the phone. The call centre staff take calls from a customer, ask them certain security questions, and then service the accounts in some way.
Now, from the customer's point of view, the bank is verifying who they are by asking the security questions. This is subtly different from the bank's point of view: It is verifying that the call centre employee is talking to the customer.
Why is this difference important? The bank wants to restrict these low trust staff, so they cannot view any details of the accounts until the customer calls them. So a call centre employee can't browse account details of customers that haven't just contacted him and asked for service.
So the question is:
Is this sort of setup possible in Dynamics CRM 2011? How would one go about implementing it? Some level of customization would be OK, but a bespoke application driven from the CRM data is not.
I'm thinking that maybe it's possible to create a custom component that temporarily modifies the user's permissions to a record (and all its children) after answering some security questions. However, I'm not even sure that record-based security (beyond Ownership) is supported in CRM...? I guess one could temporarily assign ownership to the user. Is that wise?
Please note: Simply hiding views & find buttons from the GUI isn't the sort of level of security we're looking for here. We're looking to literally restrict the user from accesing the records in question.
I can see a couple of options:
Working within the permissions model. This could work. You could have access restricted by default, and then have another entity where you'd enter in the account details, a plugin would run and verify the details, and then share the record to the current user. I'd be a little concerned, however, on how the unsharing would work. What would trigger it? Would there be a process that just runs outside of CRM and unshares records periodically. What if that process fails? We've also had performance issues in the past with this type of model... CRM seems to do a lot of work under the hood every time an individual record's permissions are changed like this.
Reassigning the owner, as you suggest. Would multiple users ever need to look at the same data? Does the owner of the record need to be maintained for any other reason (e.g. This is Joe's account because he's the owner).
Working exclusively with plugins. You could have a plugin registered on Retrieve and RetrieveMultiple of a record. This plugin could filter out all the details you want to hide from the end user. When the user needs to view the rest of the data, they fill out a form or dialog or something with the data. This data is then included in the Retrieve call for the record. The plugin checks for the hidden data, verifies that it's there and correct, then strips it out and lets the request continue, only this time it retrieves all attributes, and the form populates as expected.
Disclaimer: this answer is based on plenty of CRM 4.0 experience and reading the release notes for 2011.
Short answer: no.
Long answer: yes, but the customisation would be major. The 'easiest' option that springs to mind, is that the authentication process is carried out as a bespoke asp.net page that either a) uses a service account to re-assign an entity to an individual and then returns them to the relevant CRM form, then a plug in that re-assigns it back on saving changes
or
b) has it's own set of forms to that update and retrieve information as a service account, and only do so after answering the security questions.
As an aside, any kind of 'scripted' form is almost impossible in CRM 4.0. I believe 2011 slightly improves on that, but what I've seen is still not encouraging. Using CRM in a contact centre for us has meant investing in a piece of third party form building software and creating bespoke forms that can be launched from CRM and return data via the web services (which are impressively flexible). We only use the CRM interface for viewing historic requests - even most updates trigger one of the bespoke forms.
If I was to implement such a scenario I would create a customer access record (new_custaccess) that is linked to the customer record (new_customer). For this example - keeping it simple - I'm going to assume that the customer has a simple access code they must provide before the bank employee (Operator) can access the record. The access code is stored on new_custaccess in a field (new_secretcode).
Security is that the Operator has no privileges to new_customer and read/update privileges to new_custaccess.
There is a single field (new_secretcodeoperator) on new_custaccess that the operator can update. All other fields are restricted from update (and, if appropriate, read) to the Operator.
When the Customer calls and the Operator searches for the appropriate new_custaccess record. Once they locate the record they enter the Customer provided secret code into the field new_secretcode and do a save.
A Pre-Update query executes on new_custaccess in the context of a user with full privileges (call it MASTER, for fun here.) That plug-in checks to see if the provided code matches the secret code. If it doesn't it throws an error and the Operator can retry. If it does match the plug-in strips the field new_secretcodeoperator from the record, to keep it from saving the value. It also shares appropriate permission on the record new_customer to the appropriate operator.
The Operator now has access to the Customer record (you'll have to decide whether to cascade permissions or share on each record - that decision is beyond this discussion.)
We now need to deal with rescinding permission on the Customer record. I would handle this by having an entity new_customeraccess that is generated by the previous plug-in whenever access is granted to a Customer record. A workflow should be triggered on Create of new_customeraccess that cause new_customeraccess to be updated every 20 minutes (or whatever time the client prefers.)
A plugin is registered on Update of new_customeraccess that fires when the field updated by the workflow is modified. This plug-in will determine - via whatever criteria is decided on by the business - whether to continue sharing or revoke sharing.
I would also create some javascript/html based pop-up from the new_customer ribbon to end sharing by updating a field on new_customeraccess. Provide the Operator with limited Update privs on new_customeraccess via field level security.
This should accomplish what you want without going outside the standard CRM customization model. Not exactly sure of where you draw the line on bespoke but this is probably as close as you'll get to OOTB. A few plug-ins are all the C# you'll need. And the only JavaScript will be for usability, not functionality.
Let me know if you have questions.

Where do I prevent users from accessing other users' data?

On a website I am building I need to allow users to edit their orders. Easy enough. But how do I ensure that a user cannot edit other users' orders? Do I perform checks in the model or in the controller to verify that the order belongs to the authenticated user?
Put checks in the view (yes, the view) for rapid response to user errors.
Put checks in the controller to ensure data integrity.
For example, in a web based app, you might have browser javascript to check all fields, including username, so the user gets rapid response to fix erroneous transactions. However, back at your server, you can not rely on the browser to really validate the data, since the browser is outside your control -- it might be corrupted, either intentionally or accidentally, and not doing validation as you intend. Thus you need to revalidate everything on your server to ensure integrity.
Well hopefully your site doesn't have any way for a user to even attempt to edit someone else's orders. But if it's still possible to try, you could put that logic in either the model or controller. It's a matter of opinion. Some people will say that the controller should do things like access checks, and the model only knows how to modify itself. Others will say "fat model, skinny controller" and say that the security checks need to be reusable across controllers and so they should go in the model. It's your call.

Resources