| Join | Help

February 2007 - Posts

Tuesday, February 13, 2007 6:51 PM

Security Sin #1

There are many sins for good security practices, much more than 7. One of the worst things you can do is force your user to use a specific character set when creating a password. I recently encountered this on Western Union's website, a site meant for transferring money online. This company has a lot of my personal information: Credit Card, Name and Address, previous addresses, a lot of stuff I don't want other people to know. So I went to reset my password because I couldn't seem to remember it, which isn't like me. So I went to reset it, and when I got to the point of asking me for my password, I remembered the password. It was because they don't allow special symbols in their passwords, like # or @. Worse yet, they only allow 16 characters! Now 16 characters is a longer than your average password, but honestly, why limit the number of characters? A user should be able to enter a password of a thousand characters if he wants to, and certainly there is no good reason to prevent users from using some symbols. In fact, secure websites might require symbols in the password.

A good website should never limit what a person can use as characters in their password, and never limit the length. OK, you can limit it to say 1000 characters if you want to, but still, what's the point? If a password is properly hashed and salted, there is no need to worry about the length of the password since it will be the same size all the time. This is a poor security choice, and never let your website commit this sin.

Share this post: | bookmark it! | digg it! | reddit! | kick it! | live it!
Posted by Kevin Jones with 1 comment(s)
Filed under:
Friday, February 02, 2007 11:10 PM

Make Your Programs Impersonate

Sometimes it is useful for your Programs to impersonate under a different user's context. The .NET Framework provides a little help for that, but it still requires a litle help from Platform Invoke.

We can impersonate by using the WindowsIdentity class and calling the Impersonate method on it. The only trick is actually getting a WindowsIdentity for another user. It's easy to get get one for the current user, but requires some work.

Let's say I have a Windows Account named "test" with a password of "TeSt111@", but my current Windows Account is "Kevin Jones" with a password of "notreal". However I programically want to run my program as "test".

By using the WindowsIdentity.Impersonate() method, we can impersonate. However this method expects a Windows Token, and getting a hold of one of those requires some unmanaged code. The unmanaged library we will need is advapi32.dll, which contains an entry point called "LogonUser". This is what we will use to get an impersonation token. This entry point needs a few things. It needs a Username, a domain, a password, the login type, and the login provider. It hands back the token as a reference parameter, and returns true or false as to if the logon was successful. The managed P/Invoke wrapper would look something like this:

[DllImport("advapi32.dll", EntryPoint

= "LogonUser", SetLastError = true )]
public static extern bool LogonUser( string lpszUsername, string lpszDomain,
                              
string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

This is a start. Now to get the token for the test account it would require calling this with the correct things, which might look something like this:

IntPtr token

= IntPtr . Zero;
bool success = LogonUser("test", null , "TeSt111@", 2 , 0 , ref token);
if ( ! success)
{
    
throw new Exception("An error occured logging in.");
}

WindowsImpersonationContext context = WindowsIdentity . Impersonate(token);
//At this point in time, the application is now running as a different context
context . Undo();
//After undo, it goes back to normal.
CloseHandle(token);
//Release the handle to the token.

You see this other method called "CloseHandle" which is another unmanaged call to the kernel, to release the handle to the token. This method as managed code looks like this:

[DllImport("kernel32.dll", EntryPoint

= "CloseHandle", SetLastError = true )]
public static extern bool CloseHandle(IntPtr handle);

Limitations
The only limitation to it is this code assumes you are using a local account, and not Active Directory or that you are on a domain (hence passing null as the domain). In order to do it with a network account, you would need to Duplicate the token, which I will save for another time.

Share this post: | bookmark it! | digg it! | reddit! | kick it! | live it!
Posted by Kevin Jones with no comments
Filed under: ,