Category: Security

Simple Local Web servers November 27th, 2013

I’ve had this post saved as a draft for two years, so I finally decided to clean it up a little and publish it in case anyone else finds the information useful.

In web development, for both client and server testing, it’s often very useful to have a local web server running in order to serve test cases. This post outlines a few quick and easy ways to run a local web server that don’t involve installing Apache or nginx and all their dependencies.

The simplest way I know of to get a local web server is with netcat:

brandon@dexter:~$ nc -l 8000

Then, when you hit the URL http://localhost:8000 in your browser, you will see the request show up on the terminal where netcat is running:

GET / HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:6.0a1) Gecko/20110513 Firefox/6.0a1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cache-Control: max-age=0

You can then type an arbitrary response back to the browser, terminating the stream with Ctrl+C:

HTTP/1.1 200 OK
Content-Type: text/html

Hello <b>world</b>
^C

The hello world HTML page shows up in your browser as you would expect. You could just as easily use an existing file on your filesystem as input for the response:

brandon@dexter:~$ nc -l 8000 < http_response_file.txt

Another option to consider, especially if you already have test cases or other static content ready to serve, is Python’s SimpleHTTPServer class. You don’t even need to write a script to run one of these servers locally:

brandon@dexter:~$ python -m SimpleHTTPServer 8000
Serving HTTP on 0.0.0.0 port 8000 ...d

This time, hitting http://localhost:8000 in your browser will bring up a directory listing with your current working directory as the document root. Your requests are also logged on your Python terminal:
localhost - - [16/May/2011 14:55:36] "GET / HTTP/1.1" 200 -

On a separate but related note, you can get a local SMTP testing server, which only logs to the console and doesn’t actually send mail, by running:

$ sudo python -m smtpd -c DebuggingServer -n localhost:25
Password:

---------- MESSAGE FOLLOWS ----------
Content-Type: multipart/alternative;
boundary="===============5376655522220276269=="
MIME-Version: 1.0
Subject: Veracode report for 2013-10-24
From: python.script@example.com
To: recipient@example.org
X-Peer: 127.0.0.1

--===============5376655522220276269==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

= Plain text version =
Hello world!

--===============5376655522220276269==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

<html><body>
<h1>HTML Version</h1>
<p>Hello <b>world</b>!</p>
</body></html>

--===============5376655522220276269==--
------------ END MESSAGE ------------

Update to CSP Bookmarklet January 20th, 2011

It was pointed out to me that my CSP bookmarklet was using a feature added in ECMAScript 5, Object.keys, and thus did not work in older browsers. I added a bit of code to address this:

Object.keys = Object.keys || function(obj) {
  var keys = [];
  for (var key in obj) {
    if (obj.hasOwnProperty(key))
      keys.push(key);
  }
  return keys;
}

Browsers that don’t natively support Object.keys will now have that functionality added when the bookmarklet runs. Go ahead, give it a try: Recommend CSP

As before, the full source is posted for you to browse as well.

Content Security Policy Recommendation Bookmarklet October 14th, 2010

I wrote a bookmarklet that analyzes the content on the current page and recommends a Content Security Policy based on the types of content it finds on the page and the sources of that content. The implementation also takes into account resources that are dynamically added to the page by JavaScript.

For instance, today I learned that ReCAPTCHA loads script both from api.recaptcha.net, but also from www.google.com. Note to self: figure out why Google needs to know about every ReCAPTCHA load.

You can test it out by clicking the following bookmarklet: Recommend CSP

If you find it useful, drag it to your bookmarks toolbar and you can use it from any web page. Feel free to check out the bookmarklet source as well.

In the future, I would like to add notifications for potential inline script violations.

Hacked my DEF CON 18 badge July 30th, 2010

I was only able to stay for part of the first day of DEF CON this year, but I’m glad I did. One of the things they’ve done for the last five years or so is put microcontrollers in the badges, and put in little Easter eggs for people to search for. This year’s had a Ninja Party mode which was locked by default, but you could unlock it by placing a series of 15 tumblers in the correct position.

They published the source code for the badges on the CD they gave out at registration (so perhaps I’m stupid for loading the CD on my laptop rather than smart for reverse engineering the badge). I opened up DC18_Badge.c and, searching for “Ninja” (the code was commented nicely), quickly found the following two C functions:

/*************************************/
/* NINJA ROUTINES
/*************************************/

int dc18_ninja_validate(uint32_t val) 
{
    uint16_t a, b;
    
    a = (uint16_t)(val & 0xfff);
    b = (uint16_t)(val >> 12);
    
    if((a ^ b) == 0x916) 
    {
        return 1;
    }
    return 0;
}

// encode tumbler states into
// 24-bit value
uint32_t
dc18_encode_tumblers(tumbler_state_type
                     *tumblers) 
{
    uint32_t x = 0, j = 1;
    uint16_t i;
    
    for (i = 0; i < TUMBLERS_PER_IMAGE;
         i++) 
    {
        x += tumblers[i] * j;
        j *= 3;
    }
    
    return x;
}

So the trick was to find the number that made (a ^ b) == 0x916 and then figure out the tumbler positions to represent that number. I wrote two small Python functions to automate those tasks. To find the number that would unlock Ninja Mode, I wrote this loop. I added a print statement to show how far into the search we were, thinking it might take some time to find it, but it popped out 6423 in no time at all:

while 1:
    a = i & 0xfff
    b = i >> 12
    if i % 10000 == 0:
        print "# a: %d, b: %d, i: %d" % \
            (a, b, i)
    if a ^ b == 0x916:
        print "DONE: %d" % (i)
        break
    i += 1
	
DONE: 6423

Now all that was left was to figure out the tumbler positions to represent 6423. Clearly, dc18_encode_tumblers tells us how to do that. I whipped up this little function to convert the tumbler positions to a decimal number:

def enc_tumblers(tum):
    x = 0; j = 1;
    for i in range(15):
        x += tum[i] * j
        j *= 3
    return x

>>> enc_tumblers([1,1,1,1,1,2,2,2,
                  0,0,0,0,0,0,0])
6439

I was going to write another loop to increment the tumbler array I was passing to enc_tumblers, but my first guess was so close that I just manually entered the settings until I found the winning configuration:

>>> enc_tumblers([0,2,2,0,1,2,2,2,
                       0,0,0,0,0,0,0])
6423

Once I had the configuration, I put the tumblers in the appropriate positions: 0 - up, 1 - middle, 2 - down. After that, well, I guess I'm a ninja now:

WordPress and Content Security Policy April 12th, 2010

Lately, I have been implementing the server logic for Content Security Policy in WordPress. I was very pleased to see that the WordPress community opened up the tracking bug for this feature around the time we first blogged about it. One of the neat things about working for Mozilla is that contributions to other important open source projects are treated as valid, valuable uses of our time.

Today, I posted my first patch to WordPress, still a work in progress, which adds an administration panel (see below) for configuring CSP. One of the features I’m rather happy with is “Suggest Policy”, which analyzes the content in the user’s blog and recommends a policy based on the content types and sources it finds.

Next I’ll be working on moving the remaining inline script into external script files. Stay tuned for further updates!

East Bay Psychotherapist
Licensed Clinical Social Worker provides psychotherapy and counseling services for couples and individuals in the East Bay Area.