3/12/2011

Security Kit on GitHub

I was planning to do this a long time ago, but this, that and the other delayed me. Finally, I've registered at GitHub and added repository for Security Kit. In short, that's the module for Drupal CMS which provides with few options to improve the security of your Drupal-based site. It aims to simplify the process of setting up security features which exist in modern browsers (CSP, Origin, X-Frame-Options etc.).
Present situation in web security indicates that regardless huge number of hacks and all these talks about "every site needs to be secured", the number of vulnerabilities does not decrease. Just take a look at XSSed. So, browser companies decided to add more built-in features to harden the web. They are mostly implemented with HTTP response headers and all the website owner/admin has to do is to add one.
Still, many people have no idea about such things or they don't know how to do this. That's the reason of creating Security Kit and, previously, SafeClick (which is so highly tailored, just for Clickjacking, so I decided to move it to Security Kit and close it).
Even though Drupal recently migrated to Git from CVS (thanks!), I plan to develop SecKit on GitHub along with other projects, which I hope I will soon finish (at least to make them public).

P.S. I do really hope and expect collaboration.

2/07/2011

Verify methods for PHPUnit (like Selenium)

If you have ever used Selenium RC + PHPUnit and used in your tests a lot of verfiy* assertions (i.e. non-strict assertions), you should have seen that they are actually look like:

try {
  $this->assert...();
} catch (PHPUnit_Framework_AssertionFailedError $e) {
  array_push($this->verificationErrors, $e->toString());
}

When you have around 100 verifications the code becomes a mess. That's when you should write your own verify* methods and instead use them.

I thought it would be useful for other PHPUnit + Selenium testers, so here is an example I of verifyEquals() as I guess it's the most used method:

class PHPUnit_Selenium_Verifications extends PHPUnit_Extensions_SeleniumTestCase {

  /**
   * Non-strictly asserts that two variables are equal.
   *
   * @param  mixed   $expected
   * @param  mixed   $actual
   * @param  string  $message
   * @param  float   $delta
   * @param  integer $maxDepth
   * @param  boolean $canonicalize
   * @param  boolean $ignoreCase
   */
  public static function verifyEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE) {
    // try assertion
    try {
      $this->assertEquals($expected, $actual, $message, $delta, $maxDepth, $canonicalize, $ignoreCase);
    // print exception and line number of assertion
    } catch (PHPUnit_Framework_AssertionFailedError $e) {
      array_push($this->verificationErrors, $e->toString(), "  on "  . __LINE__ . " line.");
    }
  }

Now you can just use $this->verifyEquals() instead of try-catch constructions.
I will keep on adding other methods if somebody finds this useful.

UPD: PHPUnit has built-in verifyCommand() method, which resolves all the problems.

12/17/2010

Private browsing in Opera is not so private actually

I've always been using Opera's private browsing when didn't want any history and other stuff to be saved locally. Always until I decided to take a look at how private it really is.
After some private browsing I navigated to ~/.opera/temporary_downloads and noticed that Opera stores some necessary files there. There were:
  • crossdomain.xml (which may reveal domain you browsed in many cases)
  • various swf files (which may reveal sensitive information when decompiled)
  • strange video_related.htm file, which contained a lot of info
That's fine, but the actual problem is that Opera doesn't delete the files when closed. It only do this when opened in next time. It works so regardless private or usual navigation. And I doubt anyone opens Opera again just to clear files after private browsing.
So, Opera's private browsing is not so private actually.

12/04/2010

Drupal and cookies domain caching

From time to time anyone experience some problems with non-fresh Drupal installations (e.g. some project from SCM). The major one for me was some strange cookie setting and handling - when I tried to login Drupal replied with correct Set-Cookie header, but cookies were not saved within browser, i.e. after login the page was just reloaded with login prompt. No message or anything to help me. So I just started commenting and editing related code by random. Finally, I got it. The problem is that Drupal was installed first with hostname A and I tried to work with it on hostname B. Don't know why sometimes it's okay and sometimes it's not. However, you just need to uncomment $cookie_domain and set it to your hostname in settings.php. Just like this:

$cookie_domain = 'your.domain';

11/01/2010

Using Hudson variables in Python

While moving my continuous integration build script to Python (using Python Plugin for Hudson), I faced a problem of using Hudson environment variables. I am new to Python and get used just to place variables in shell script like $WORKSPACE or ${WORKSPACE}. Still, it didn't work in case of Python. So, if you met such a problem, you should use os.eviron() method. For example:

#!/usr/bin/python

import os

workspace = os.environ['WORKSPACE']
print workspace

10/30/2010

Getting Fun from Responsible Disclosures

I've recently released two proof-of-concepts for jCart application and Simpli Easy Newsletter (formerly AFC Simple Newsletter) script. Both of these disclosures were pretty exciting actually.
As a responsible security researcher, I first contacted both vendors.
Guy from Simpli Easy Newsletter quickly replied. He said: Thanks, I'll let my friend know so he can fix.
Funny, isn't it? Three weeks have passed, but his friend did nothing and further emails from me were ignored. So, my disclosure was responsible in effect.
Absolutely different situation happened to jCart. I sent an email to its vendor, but didn't receive any reply and in a couple of days released vulnerabilities. Some time later I received annoyed email from Doug Whitney (jCart guy), where he explained that I was wrong not contacting him first. Of course, I forwarded him my previous email and, what's funny, everything was correct, but it got into Spam box. So, was it responsible disclosure or not? Anyhow, it was pretty funny.

10/02/2010

PunBB v1.3 Extension Scanner

While pentesting one project, I've faced PunBB v1.3 forum running there. As long as it would take a bit of time to check for installed extensions (even though there are not so much for it), I've written a pretty simple Python script to enumerate them. Maybe I It gets the list of available extensions from PunBB site and searches for them at provided website. Its code is really dirty, but I needed quick solution. Maybe it will be useful for someone. Or maybe I just failed googling for a one. Anyway, here it is. Usage (note no trailing slash):

$  python3 scanner.py http://www.example.com/forum

#!/usr/bin/python3

import urllib.request, re, sys

host = sys.argv[1]

try:
  l = urllib.request.urlopen('http://punbb.informer.com/svn/additions/punbb-1.3/extensions/')
except urllib.error.HTTPError:
  print('Cannot enumerate available extensions from http://punbb.informer.com/')
  exit()

e = l.read().decode()
e = re.sub('<.*?>', '', e)
e = re.findall('(pun_.*/)', e)

for i in e:
  try:
    urllib.request.urlopen(host + '/extensions/' + i)
    print('YES - ' + i)
  except urllib.error.HTTPError:
    print('NO  - ' + i)