IP Based User Authorization in MVC4 - security

We have an MVC application which we need to do some security check before we let user to start using system. The use case is below;
We have Company table which stores valid IP addresses(also range). And company has associated users. If a user logs in from an unidentified email address, we need to make sure that user is still working for corresponding company. Therefore, we use company email address to validate the user.
I have 2 ways to implement this;
1) Generate a token, and send a link with token as query string to the user, when user clicks on this link, I will validate the user for a certain period of time(1 day)
2) Sending user's email a 6 digit number when user successfully logs in, and ask user to enter that pin number. If the pin is valid, then validate the user.
I recently see many big companies using pin numbers and your mobile no. That made me think that the second method is more secure than the first one(I have no facts, only assumption). Is that true?
Which one of these methods is more secure? if non of them, what is the best way of implementing this use case.
Thanks

Have you looked at IP spoofing - I wouldn't recommend using IP addresses for security.
1) - I don't understand how that is secure...
2) - called two factor authentication and would typically involve sending a pin to a mobile, and not an email.
If implemented properly 2) should be secure, but that is an additional step and not a complete security model. I would start by looking at the authentication that is part of MVC5.

If you want to have a jump start on two factor authentication without building a solution from scratch, look at this open source framework that can easily integrate into an MVC4 application. As Joe R mentioned, relying on IPs for security is not a standard practice.

Related

How do services/platforms uniquely identify users?

If you log into a platform (Twitch, Blizzard, Steam, Most Crypto exchanges, Most Banks) from a new device you'll typically get an email stating so.
As far as my knowledge goes, the only information you can get on a request is
IP address
Device Operating system & version
Browser type & version
Are these platforms basing their "unique" users off of this information alone and/or am is there more information that can be gathered?
From a security perspective the largest thing is your identity or how you authenticate. That's king. The email stating "hey this is a new device" I've seen handled differently from site to site. Most commonly it's actually browser cache and I see banks specifically use browser cache to store these kinds of tokens. Otherwise every time your cellphone connected to a new cell tower you'd likely be flagged as different. They're not necessarily the same as an authentication token, rather it just says hey I've authenticated as this user to this site before. Since it's generated by the service provider, the service provider knows to trust it, and it's nearly impossible to hack (assuming it's implemented correctly).
From my own experience the operating systems and browser types, that's more record keeping than actionable insights, however you could build a security system that takes into account an IP address from very different geo-locations. I.e. why is this guy from the US logging in from China. They just logged in from California 3 hours ago, this is impossible. I don't believe most sites really go to that extent though. I do see MFA providers saying "hey there's a login from china, do you want to approve?". That workflow makes a lot more sense.
The last part of your question is tricky, regarding "unique users." Most calculate that based off the number of sessions opened (tabs), or in the case of Twitch (since you mentioned them specifically), the number of tabs that are streaming that video in. These open platforms where anyone without an account can stream the content obviously treat this differently than say Netflix that makes you authenticate and each account has a limited number of sessions that can be open.
AFAIK, most of the systems like this stores a cookie in your browser when you log (not the session cookie, just a random ID) that is also assiciated to your account in the provider database, so when you came back, you log in, and they check whether you have that cookie set and in case if the ID matches
They you can probably do some more advance stuff with that ID, like base that value from the browser, OS, expire date and so on

Generate secure shareable URL for access to web app (NodeJS)

I am building an application in NodeJS + Express where teams can share information with one and other and chat (kind of like an internal messaging forum).
Sometimes there is a need for the team's clients to view and edit some of this stored information on a case by case basis (e.g. a client asks a question and wants to message back and forth with the team, using my app). I don't want the client to have to sign up for an account in this case.
I am thus wondering what is the most secure strategy for generating a URL where anyone with the URL can view and edit a document/POST data to my app within the confines of a single document, without signing in?
(I've seen a couple of posts on this topic but they're quite old and don't focus on this specific case.)
First of all, I can absolutely understand the benefits, but still it is not an optimal idea. However, I would like to summarize some thoughts and recommendations that will help you with the development:
A link like this should not be able to perform critical actions or read highly sensitive data.
Access should be unique and short-lived. For example, the customer could enter his e-mail address or mobile phone number and receive an access code.
If you generate random URLs, they should be generated in a secure random manner (e.g. uuid provides a way to create cryptographically-strong random values).
If I had to design this I would provide as little functionality as possible. Also, the administrator would have to enter a trusted email address and/or mobile phone number when releasing the document. The URL with a UUIDv4 is then sent to this channel and when the customer clicks on the link, he gets a short-lived access code on a separate channel if possible (on the same channel if only one was configured). This way you prevent the danger of an unauthorized person accessing the document in case a customer forwards the original URL out of stupidity.

Is this safe for client side code?

I'm writing a GWT application where users login and interact with their profile. I understand that each form entry needs to be validated on the server, however, I am unsure about potential security issues once the user has logged in.
Let me explain. My application (the relevant parts) works as follows:
1 - user enters email/pass
2 - this info is sent back to the server, a DB is queried, passwords are checked (which are salted and hashed)
3. if the passwords match the profile associated w/ the email, this is considered success
Now I am unsure whether or not it is safe to pass the profile ID back to the client, which would then be used to query the DB for information relevant to the user to be displayed on the profile page.
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
-Nick
What you are dealing with here is a session management issue. Ideally, you want a way to keep track of logged in users (using random values as the session key), know how long they have been idle, be able to extend sessions as the user is using the site, and expire sessions.
Simply passing the profile ID to the client, and relying on it to send it back for each request is not sufficient - you are correct with your concern.
You want to keep a list of sessions with expiration times in a database. Every time an action is executed that needs user permissions (which should be pretty much everything), check to see if the session is still valid, if it is, extend it by however long you want. If it is expired, kill the session completely and log the user out.
You can store your session keys in a cookie (you have to trust the client at some point), but make sure they are non-deterministic and have a very large keyspace so it cannot be brute forced to get a valid session.
Since you're logging a user in, you must be using a backend that supports sessions (PHP, .Net, JAVA, etc), as Stefan H. said. That means that you shouldn't keep any ids on your client side, since a simple id substitution might grant me full access to another user's account (depending on what functionality you expose on your client, of course).
Any server request to get sensitive info (or for any admin actions) for the logged in user should look something like getMyCreditCard(), setMyCreditCard(), etc (note that no unique ids are passed in).
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
Stefan H is correct that you can solve this via session management if your session keys are unguessable and unfixable.
Another way to solve it is to use crypto-primitives to prevent tampering with the ID.
For example, you can store a private key on your server and use it to sign the profile ID. On subsequent requests, your server can trust the profile ID if it passes the signature check.
Rule 1 - Avoid cooking up your own security solution and use existing tested approaches.
Rule 2 - If your server side is java then you should be thinking along the lines of jsessionid. Spring Security will give you a good starting point to manage session ids with additional security features. There will be similar existing frameworks across php too (i did not see server side language tags in the question).
Rule 3 - With GWT you come across javascript based security issues with Google Team documents and suggests XSRF and XSS security prevention steps. Reference - https://developers.google.com/web-toolkit/articles/security_for_gwt_applications

Secure OpenID user authentication

My goal is a secure login in system such as stackoverflow uses. I am a newbie but as you have probably seen I have spent all day looking up stackoverflow articles on security. As a result of this research I have now worked out a plan of attack. In particular this page was a great help Using OpenID for website Authentication. Can you please tell me if the following system would be a secure system and if not how should I improve the system.
Use OpenID to validate users.
Once a user has been validated by OpenID get user's email address from OpenID.
Hash the email address and store in session variable.
Compare Hashed email address to list of hashed email addresses in databases
Return content appropriate to that user based on the hashed email address.
In particular I am nervous about using the email address instead of the ProviderOpenID.
Please assume that I have (as I have found answers to these questions on other stackoverflow pages):
Properly destroyed sessions after use.
Setup my server to store session data in an inaccessible location.
Setup my database in a secure manner.
I am using SSL to ensure traffic cannot be intercepted.
Thanks in advance.
In general, your way better of using some authentication architecture for the language you are using that supports OpenID. Not only is it more secure, its just easier, you write less code, and you don't have to maintain that code or test it. There are ones for PHP,python,c#/asp.net, rails. A lot of frameworks also have support.
First, why not use the provided ID ?
I think you have two problems:
Its possible that an openID provider could return a email address for a different domain than the provider's.
For example, gmail could authenticate me correctly but I could specify that my email address was billg#microsoft.com. Then you would read my identity as me being Bill Gates despite the fact that it is not. There are of course ways to prevent this, but the standard system probably has safeguards included and even if it doesn't, it is someone else's responsibility to fix them and other people will be looking at those issues.
If I am reading the wikipedia article correctly, openID id's are not necessarily email addresses
This is not a security problem , but it does break expected behavior.

How to Check for Shared Accounts

We have an application that includes a voting component.
To try and minimise voter fraud we allow N number of votes from the same IP address within a specific period. If this limit is hit we ignore the IP address for a while.
The issue with this approach is if a group of people from a school or similar vote they quickly hit the number. Their voting can also occur very quickly (e.g. a user in the class asks his classmates to vote which causes a large number in a short period).
We can look to set a cookie on the user's computer to help determine if they are sharing accounts or check the user agent string and use that too.
Apart from tracking by IP, what other strategies do people use to determine if a user is a legitimate or a shared account when the actual IP is shared?
If your goal is to prevent cheating in on-line voting, the answer is: you can't, unless you use something like SSL client certificates (cumbersome).
Some techniques to make it harder would be using some kind of one time token sent trough e-mail or SMS. Every smart kid knows how to cheat control cookies using privacy mode of modern web browsers.

Resources