I am working on a web application, asp net web forms site (.Net 4.0, C#).
I want to be able to ban a user's IP either temporarily or permanently.
A permanent ban would occur if the IP address is attempting to log in using multiple usernames and passwords. This would signify a malicious attacker, so I want to ban them. I would like to avoid using the database at this step to avoid DOS type attacks slowing down the network.
A temporary IP ban would occur if the user types in the wrong username, such as username1 instead of username, and they keep trying to log in with their password. This method will use the database as the user might have not realizes they typed in the wrong username.
My question is:
How can I track if the same or different user name has been used across the page refreshes?
I am thinking about using a Session, but after some searching around for similar problems, it looks like the Session requires cookies and an attacker would avoid those.
For permanent IP bans, I found some code that uses the IIS api and the Microsoft.Web.Administration package. Here is the link for some code adding IPs to the IIS ban list:
IIS IP Security
How can I implement the tracking of the log in attempts without using the database?
I am also implementing the server (IIS) IP restrictions as another layer of security, but this only blocks an IP based on the number of attempts within a certain time period (which is desired) but does not differentiate between the cases I mentioned above.
Using any client side storage such as sessions or cookies seems like a bad way to deter an attacker. You say that you don't want to use the database because it could slow down the network so my suggestion would be to use a second local database or a in memory list to hold information pertaining to recent login attempts. It could store IP address, username, hashed password, and a time stamp. When you go to authenticate a user you could check against this local data. MSND Article on caching for more information.
If you are using html 5.0, you could use the local storage ability. Of course, malicious users may have disabled that, as well as cookies, but worth considering.
Related
I'm building an application that syncs data between users' Exchange Server accounts (version 2007-2013 supported) and the application.
The application can't use impersonation (at least not in the typical case) as users could be on any number of domains and exchange servers.
I know I'm going to have to ask for their username/email-address and password initially. However, I really don't want to be responsible for storing these credentials if I don't have to (even if they are encrypted, I'd rather not).
I'm not sure what questions to ask, so I'm going with these:
How does Exchange Server authenticate? Do the user's credentials get sent directly to the server as they are, or are the hashed together before being sent across the wire? If they are hashed, how can I get/generate this hash for re-use on successive authentications?
Does Exchange Server send some sort of authentication token that can be re-used later (and forever, until password change or invalidation)?
If you know of a solution to the problem, that the answers to these questions won't address, please do provide it instead.
Active directory federation services is exactly for such tasks. You can read about it there.
As mentioned by Kirill, ADFS 2.0 is one of the best solution for your task. You can also look into other SSO implementations as well. Though the main goal of SSO implementation is to maintain single Login state for multiple application (thereby reducing multiple Login prompt for each application), some of your application goals seems relevant. Please do a thorough research on all the tradeoffs before heading to the sso implementation since there is a small degree of complexity involved during implementation. SSO suits best if you are considering integration of multiple application in the future with the exchange server.
To answer some of your questions (in the same order - considering an SSO scenario with ADFS 2.0):
The authentication to exchange server will be done via ADFS 2.0 (Which provides security tokens (STS service) - to your application after authenticating with AD/ main Directory service). All the communication is encrypted and token signing certificates are used for Integrity and confidentiality.
The lifetime of Security tokens sent by ADFS 2.0 can be configured and reused as required. Please see this blog post for more details.
Also you can configure the ADFS 2.0 (Federation Service) to send only the relevant claim values (like username and email address) to the application, thereby improving the data security.
The System.Net.CredentialCache should work to suite your needs. The WebCredentials is a wrapper for the System.Net.NetworkCredential. Depending on the connection type/domain ect you should be able to utilize System.Net.CredentialCache.DefaultNetworkCredentials or System.Net.CredentialCache.DefaultCredentials
perhaps you should take a look at this Links Connecting to EWS by using the EWS Managed API , Connect to Exchange - Getting Started Tutorial? hopfully it will give you a new idea how to solve your problem :)
because if i understand the information correctly you maybe over think problem but i haven't any experiences so i could also absolute wrong
Bottom Line
If you can't configure anything on the server, there's no automatically generated token to use. It's unfortunate, but you're facing the same general problem that web browsers have--saving the password.
It's worth noting that any authentication needs to be over SSL (an https connection) to prevent a third party listening in on the authentication.
Password storage thoughts:
My suggestion is then to be somewhat creative when storing the password. You can use a keyed encryption algorithm, and then use a hash to generate the key, letting you arbitrarily choose what goes into the key. You would want at least 3 pieces of information going into this: something unique to the device, something unique to the app, and something unique to the exchange server.
For example:
a unique id given by the device (it doesn't matter whether or not this value is app-specific or not, merely that it is consistent)
a (long) string of information compiled into the app, possibly keyed to installation specific values, say the time when the app was first used
something unique to the destination, like the DNS name and perhaps some more specific server info
If you're willing to provide the option to the user, you could have an authorization PIN of some kind that would also be added to the data.
All this data gets put together in one byte array and hashed. The hash (or part of it, or it twice, depending on the hash size vs. the key length) is then used as the key for the encryption of the password.
You could also include some check information along with the password to be able to check client side whether or not the password was decrypted correctly. (If the wrong data is hashed, the wrong key is generated, and the wrong result comes from the decryption).
It's worth noting that all the information to be used for putting into the hash needs to be stored on the device, which is why I would suggest a Pin to authorize the usage of the account.
I am sure there're lots of discussions already, but how to store a password in an application? (I meant not a user password to be stored in a table in a database, but the password to build connection string)
I've seen suggestions like store it encrypted in a flat file such as xml file, then read it +decrypt it at run time. If this application runs on a server, this is a very good choice, but what if the application will be deployed to end-users' pc? i.e. the flat file will be copied to the user's pc. Is this still a good practice? (my instinct is 'NO')
I know the existence of SecurityString, but then I also read in one post that SecurityString can be easily broken into, too.
Is it a good idea to use Password Vault that comes with Windows 7? Is there any good example of utilizing it programmatically? I've seen an example in msdn, but firstly it is labeled with 'windows 8', secondly when I downloaded the files and opened the solution in visual studio 2012 EXPRESS, it failed to open.
Any suggestion is welcome...many thanks.
--update--
Let's say, the application will be running on a handful of PCs within a windows domain. (1) At start-up, the application will do a LDAP authentication (active directory). Only upon successful authentication, the application will carry on, and (2) behind the scene the app can connect to the database, take user input to query the db, and this is where the db passwd comes into the play to build the connection string (no this is not SQL SERVER database so I don't think the option of using windows authentication is viable, unless a commercial plug-in is used).
The db resides in the same domain, and has been set up to allow certain range of IP addresses, and is SSL enabled. In short, it is quite secure in this sense. The only bit that is not yet secure is how to store the db passwd for the application.
What caught my eye was the Mysql Workbench. It will save db connections, including the password - which is stored in a password vault. That is mysql's own implementation of a password vault, and I am very curious as to how it is done.
There is no way to give a password to your users and expect it to remain safe. Even if it is hidden in your compiled application and hashed with a one way hash, the determined will recover it.
Instead you should consider your security architecture.
If you are providing services which your application connects to then you should look at providing some sort of more robust authentication as part of your public API.
If the connection string is for connecting to another part of the distributed software, then you should make the password configurable by the end user and store it in a keyring or other encrypted storage.
-- Update --
It looks like this might be what you are looking for;
http://www.microsoft.com/indonesia/msdn/credmgmt.aspx
If the application is going to be deployed where you have no or little control over the system security, ie, external user pc, then it may be worth creating a user login. Authenticate the user against this login, and then from a relatively secure server use whatever credentials you need to provide data.
This does not guarantee security, but it will be easier to maintain if you need to change the password at some point in the future, or if an individual user is compromised.
I have a Asp.Net MVC4 website which can connect to multiple databases depending on the user's login credentials. In order to get the database access list for the user, I have to perform a few complex joins when they login. To avoid having to do this more than once, I am currently encrypting and storing the database ID in a cookie. I now realize that this may not be a good idea and even strong encryption may be broken. In addition, the encrypted cookie is transferred around on every request increasing traffic. I am now thinking about using the HttpContext.Current.Cache to store the data instead. Can anyone comment on whether this is a good idea. I would also be interested in knowing if there are better options out there. My website is not deployed on a server farm right now but what would be the implications if I were to use a cache and a server farm in future?
Based on your requirements (i.e. keep a hold of sensitive user specific info across a session), the correct place is for this is the SessionState. AFAIK sessions states can be shared across multiple web servers so if you did use a server farm you wouldn't need to change anything.
Session is right container for user sensitive data. Or you can store it in database and get it there by some identifier that is stored in session(it is useful if you store large amount of data).
I am wondering if i need to add any other kind of security on this asp.net application - web forms (available only on network domain and through VPN connection)?
Application Environment: Asp.net 4.0, Vb.net, Oracle 10g, Web Services, Window server 2003 or 2008, Hosted on domain
User Authentication Mode: Window (Not using asp.net membership)
Authentication Scenario:
Application is accessible via intranet site and system authenticates user with his system user name. On the default page system will first get the current user name (HttpContext.Current.User.Identity.Name) and then match it in the user table (oracle DB), if it is matched then store procedure will return all the access permissions (menu details) relevant to this user group. There is a user group and permission table in the oracle DB.
In the store procedure, system will also check the user permissions before any DML transaction.
Main security concern
Major: restrict people to access the information depends on their permissions. Normal user shouldn’t get access to other’s data.
Minor: We don’t want anyone to get into our system outside office network.
As Joachim says, this arrangement only supports Windows systems running on the local network. Shifting to basic authentication will allow more clients to connect but exposes the passwords on the network (effectively in clear text) without HTTPS. Forms authentication is similar.
Without server authentication, users could be redirected to a similar server without their knowledge or suffer a main-in-the-middle attack. HTTPS gives you this with the server certificate. This may not be a concern on a local network but users' hosts (in c:\windows\system32\drivers\etc) files are often vulnerable.
Without encryption, any user can sniff the information sent back and forward over the network assuming they are on the same subnet. This may be an acceptable risk for most applications but not if the information is sensitive, e.g. contains sensitive or personal information.
Consider replay attacks (see How do I prevent replay attacks? for an example) if people are performing important operations like approvals.
Consider auditing access to the database, particularly the user group and permission tables. Someone could add themselves or move them into a group, perform an operation then remove themselves. Check your pages for SQL injection and similar attacks which could accomplish this.
In summary, how likely are people to compromise or interfere with the system and how much are you willing to invest to protect it? Assuming the server can handle the load, HTTPS is a hard to go past as a first step.
Unsure what kind of ASP.Net technology you are using (MVC/Razor/Web Forms).
If you are using Web Forms, then you can immediately take advantage of ASP.NET Login Controls like LoginView Control. They work with ASP.Net Forms Authentication (with or without using ASP.net Membership). You can also take advantage of Roles.
Your intranet server should be "protected" if it's not exposed in your network publicly (in any way). Of course that's a bold statement that depends entirely on your network implementation - e.g. subnetting, internal net/no nat/route/no port forwarding, no dns, etc. This makes VPN as your only point of exposure from the outside, then you must enforce proper security policies for your VPN infrastructure - e.g. one-time passwords, client inspection, etc.
Update:
If you are using Active Directory, you can create users/groups in AD to provide access accordingly (e.g. Finance AD group can only access "finance" folder). I haven't kept abreast with browser support for NTLM outside of Internet Explorer however.
You did mention user data is in an Oracle db however(?). I'm not familiar with solutions that allow no login screen access (to network resources) using a db/Oracle.....
Also, that would mean one-time passwords for VPN access may not be available. Look into token based VPNs so users can still use their AD credentials but need a new token each time - this will help mitigate the "passwords in yellow sticky notes" (because you can have tighter control over tokens).
My website can be access from many domain (a my own blog engine). So, how i can cross authentication?
I'm using: IIS7, C#, asp.net membership, form authentication.
If you are using Active Directory (assuming that is what you refer to as domains), you can simply configure multiple ActiveDirectoryMembershipProvider sections and use the asp:Login control templates, add a dropdown for the domains you want to authenticate against, and on the OnAuthenticate event of the Login control, set the selected AD membership provider.
For different providers like SQL Server membership provider, I'm not sure I understand what the issue is. Can you elaborate?
I'm going to take a guess here after having tried to read your question a couple of times again. If with 'multiple domains' you mean you have multiple websites (multiple fully qualified domain names), and you want to use the same SQL Server datastore to authenticate users against, and run the same website, the solution would be to point the appropriate DNS A record to the IP address of the original hosting server.
Any decent domain registrar should allow you to change the DNS record.
However, Forms Auth creates a cookie, and you will not be able to read the cookie from a different domain than that you are on because of obvious security issues, so in that case you're stuck.
The only possibility I can see is that you're passing some encrypted identity in a querystring, but that is very, very dodgy, as you would want to make sure there's a minimal validity time limit on it as it opens up a right can of worms (security holes). Probably not recommended.
Crikey, that's a long way of saying "No, you can't - securely."
If are talking about sub domains and not about different top level domains, then you can actually do it, see this post.