Archive for July, 2009

MSTest = Fail

Jul 30

One of my current clients is really embracing all the MS clones of great open source tools like MSTest, Team Build, Entity Framework, etc. Although I love the open source tools like nUnit, Team City (ok not so open source but still free), and nHibernate, I thought I would try MS Test out even though I have not heard many good things about them.

First I will say something nice: MSTest has a nice code coverage suite. I really like that it is integrated with visual studio and can even highlight the areas that are covered and not covered which is the ONE feature of MSTest that I like.

Other than that the code coverage I think MS test is a complete miss when it comes to development for the following reasons:

  • Only being able to add tests to a test project. I like my unit test classes to sit in the same project as the code I am testing as I find it easier to navigate the code, easy to spot if I did not test a class (As there is no [ClassName]Tests.cs file next to it. It appears that with MS Test I can only add tests to a test project
  • VSMDI File. When a test project is created it adds a .vsmdi and .testrunconfig file to the solution. Why these are needed at the solution level (or at all), I have no idea. Adding these items makes me have several spots to go to for changing settings instead of just one
  • Poor IDE integration. In VS I now have a test view tab, a test results tab, and a test runs tab docked into the editor (plus a code coverage tab but I can agree with this being a seprate tab). All I need is one area where I can run the tests and see the results. Just a heads up but SIMPLE THINGS ARE EASY TO USE!
  • Notification about having run more than 25 test runs. Apparently MS Test keeps 25 copies of the old tests around and when you try to run your unit tests for the 26th time you get a warning about this which is annoying. In 99% of situations you will not need to go back to the first time you ran tests so why bother even telling me?
  • Release/Debug Suprises: I had a set of tests constantly failing in the MSTest runner yet constantly passing in my Resharper runner. Also the code coverage went screwy (the code coverage was not accurate and  line highlighting did not match up). After a few hours I discovered that it was because the app was set to compile to a release but MS test just look at the debug DLL’s with no warning that it is doing so. I agree that the same thing would happen with nUnit but nUnit is not integrated into the UI and is therefore not expected to be able to pick up on these things MSTest is supposed to be this integrated wonder that should know when the tests are compiled in release to maybe use the release code instead of the stale debug code (or at least warn me)
  • Hard to Navigate. When a test fails you can see some of the description of the error message but if you want further details you need to double click the item which oepns a new editor tab which explains the error a bit more. I find having to manage these tabs an annoyance and much perfer the nUnit or Resharper test runner approaches myself.
  • Hard to just run one set of tests. I have two test projects one for unit tests and one for functional tests (items that hit the database and other costly resources). It seems hard to just run tests for one of the projects. It is also hard to run tests for just one namespace. Again these things are easy with other unit testing frameworks.
  • The context menus are confusing. Right clicking on the test project and selecting “add” yeilds “New Test”, “Unit Test”, and “Ordered Test”.
    New Test: Gives you the option of creating a new test, an ordered test, or use the test wizard
    Unit Test: launches the test wizard
    Orderd Test: creates a new ordered test
    I find the multiple routes a bit confusing (not to mention how it adds 3 elements to my already crowded context menu when I only need one)

Now these are just the issues I have had with it. A quick stop on a search engine brings up many other issues but so far I have not experienced them. I find that MSTest is not as clean, fast, or simple as other unit testing frameworks out there which makes me not want to use it on another project.

 

Filed Under: .NET, Rants

Brute Force Attack Countermeasuers

Jul 28

One common attack to get into a website is to brute force the username / password. This is effective mainly due to the lack of brute force countermeasures that people build into their websites login mechanism. There are a few common countermeasures out there currently.

Account Lockout

An account lockout is when a set number of failed attempts are reached that no more attempts are allowed. Usually this involves flagging the user account in your database as locked out. While this stops a brute force attack in its tracks, it does have some consequences. The most obvious is that there will need to be a mechanism to unlock the account which is usually an administrator or else a set period of time has elapsed. The not so obvious consequence is that an attacker may lock out legitimate accounts on purpose which would deny legitimate users access until the lock is released!

Tarpitting

Tarpitting is the process of slowing an attack down. Typically an attacker tries to login thousands of times per minute in a brute force attack. By putting a delay on how long it takes to get the results back you can drop the number of attacks per minute drastically. This prevents the intententional lockout attack mentioned for the account lockout countermeasure.

The most common mistake I see when implementi ng tarpitting is when it is implemented as Thread.Sleep(failedLoginAttempts * 1000). The main issue here is that the delay time keeps growing, If I wanted to prevent a legitimate user from logging in all I have to do is fail your login a few thousand times and it would then take thousands of seconds to log back in. Instead use a hard coded delay (even something like one or two seconds drops the number of attempts an attacker can perform).

The other item to worry about when implementing tarpitting is resource exhaustion. By keeping a thread sleeping you are using resources to maintain and monitor that thread. If an attacker were to be able to do enough attempts they may be able to exhaust your servers resources which could deny service to legitmiate users.

Fake That The Login Worked

This is something I theorized that may get around the negatives of account lockouts and tarpitting. What if you build a login screen that once so many failed logins were reached that it would redirect the attacker to an empty page so that the tool they are using to brute force stops as it thinks it got a hit? I have not tested this theory out but there is a bit more information here: http://www.haveyougotwoods.com/archive/0001/01/01/annoying-brute-forcers.aspx

CAPTCHA

This one is quite annoying but placing a CAPTCHA (one of those computer generated images that you have to type in the word) on the login would drastically reduce the effectiveness of an automated attack. Now the attacker has to guess the username, password, and either guess or break the CAPTCHA image which makes the attack harder. This comes at the cost of convenience and useability to the end user. Also the big downside of CAPTCHAs is that they are not usable by the visually impared.

Abandon Passwords

This is easier said than done but there are lots of password alternatives that are much harder to break than passwords. Things like certificate exchanges, smart cards, card space, and security key tokens offer better security but all have their downsides.

 

Filed Under: Security

Oracle Raises Prices

Jul 27

Oracle has announced that they are raising the prices on the Oracle 11g database. MS has kept the price of SQL Server 2008 the same (for now). I am still amazed that Oracle charges what they do when you can almost get two MS SQL Server licences for the price of one Oracle license. While Oracle has been shown to perform faster than SQL Server 2008 I would much rather have a system that is easier to work with and cheaper than one that I find dificult to work with and out of my clients budget range.

Here is a price comparison (NOTE: prices are based on manufacturers suggested price at the time of this writing)

Oracle   Microsoft  
Standard Edition One* 5,800    
Standard Edition* 17,500 Standard Edition  5,999
Enterprise Edition  47,500 Enterprise Edition   24,999

*the differences I could find between these two editions was that Standard Edition One allows 2 sockets and Standard Edition allows 4 sockets plus clustering and workload management.

 

Filed Under: General

Securing PHP

Jul 3

Much to my disappointment PHP installs with developer settings by default. This means that the default installation has some potential security holes that need to be tightened after the install.

Any security person will tell you that an application should install in a minimal and locked down  state. I would say 95% of people don’t look to secure something after they install it, they expect it to be secure out of the box. This is what IIS now does and you have to enable any features over the baseline you want.

Doing some simple lockdowns are not hard in PHP though. I am not going to talk about every security feature in the config file, just the defaults that I feel should be changed:

safe_mode=On [Default=Off]
Turning this on makes it so that any file your php file attempts to open MUST have the same UID as the php file that is executing. It also disables or restricts many methods that access or manipulate the filesystem.

safe_mode_gid=Off [Default=Off]
Same as safe_mode but checks the GID instead of the UID. I keep this setting at its default Off state as I want to keep the access restricted to only a user.

open_basedir=[path] [Default=blank]
Restricts PHP to only access files and folders within that path. If all your sites exist in /usr/home/web then I would set open_basedir=/usr/home/web

expose_php=Off [Default=On]
PHP will not write information about itself to HTTP headers. This can help prevent a vulnerable version from being discovered by automatic scripts.

display_errors=Off [Default=On]
By turning this off error messages are not returned to the browser. This prevents information disclosure which is often a precursor to an attack.

log_errors=On [Default=Off]
turning this on logs all the errors to a file or syslog (as specified in the error_log variable)

disabled_functions=show_source, system, shell_exec, passthru, exec, phpinfo, popen, proc_open  [Default=Blank]
This allows you to completely disable certain functions in the PHP runtime that could be potentially used to exploit your system.

enable_dl=Off [Default=On]
Disables the loading of a PHP extension at runtime (i.e. dl(‘myexploit.so’);).

allow_url_fopen=Off [Default=On]
Disables using fopen to open a URL. When left on it is possible it could be exploited to download exploit code from a remote server.

upload_tmp_dir=/var/tmp/php/tmp  [Default=/var/tmp]
I change this so that automated attacks can not find any uploaded files in the default directory. It also enables you to add customized security around the directory that is restricted to its purpose.

session.save_path=/var/tmp/php/sessions [Default=/var/tmp]
Whenever a session is created it is saved to the disk. This could potentially expose the session IDs of all current sessions if an attacker can enumerate them. Changing the folder that the session files are saved to can reduce this risk.

There are also a few limits that you may want to adjust to suit your environment. I find the default memory limit quite high (128MB) but this will differ from environment to environment:

max_execution_time = 30     ; Maximum execution time of each script, in seconds
max_input_time = 60     ; Maximum amount of time each script may spend parsing request data
memory_limit = 128M      ; Maximum amount of memory a script may consume (128MB)

Using Apache to provide additional security

Many php systems ship with files that are used by the application but should never be served out to the application. The common ones are .inc, .sql, and .conf (or .config) files. Also some editors create temp files that end in a ~ and may not get cleaned up properly. We can change our Apache config to deny these files from ever being served:

<FilesMatch “\.(inc|sql|config|conf |.*~)$”>
  Order allow,deny
  Deny from all
</FilesMatch>

One of the issues is that with safe_mode set to on an attacker could still write to all files that are owned by that user. Lets take the following example

/usr/home/web/user1/index.php   Owner: nobody
/usr/home/web/user2/index.php   Owner: nobody
/usr/home/web/user3/attack.php  Owner: nobody

Even with safe_mode=On and open_basedir=/usr/home/web, running attack.php could alter index.php in user1 or user2’s directory. I know it is not common to have this kind of scenario where the same user owns all the files but it is quite possible.

I saw a nice workaround somewhere that used Apache to set the open_basedir for each virtual host that looked something like this:

<VirtualHost www.user1.com:80>
  <Location />
    php_admin_value open_basedir “/usr/home/web/user1″
  </Location>
</VirtualHost>

This would basically lock every user into their own home directory which is exactly what you would want in a shared environment.

Suhosin

Suhosin is a two part hardening add-on to PHP. One part patches PHP to help prevent buffer overflows or format string vulnerabilities. The second part is a PHP extension that adds a host of other protections and features. More info on Suhosin can be found on their website.

Filed Under: Security