Archives for Adam Gotterer

To CMS or not to CMS?

In one of my recent posts someone asked in the comments what I thought about Drupal. It felt off topic, so I decided to write a post about Content Management Systems.

I personally don’t have much experience with open source (or enterprise) CMS. I had a short stint with Joomla and eventually ditched it. I have become a bit of a development control freak. More often than not I prefer to roll my own system. This isn’t for everyone and doesn’t make sense for all projects.

My problem with pre designed Content Management Systems, is it tries to solve a problem that can’t always be solved with single solution. A fits everything package usually comes with overhead, constraints and a little bit of a development black hole. These constraints can lead to excessive amounts of “work arounds”, hacks and a lack of understanding. On the other hand a pre packaged solution comes with an entire community of developers, tutorials, patches and plugins. Having resources like that can save time and money. It really comes down to what’s best for your project.

Choosing to build your own system or use an existing one depends on the scope of the project and your skill level. These are a few key points I would pay attention to while making a decision:

  • How many users will be using your site? Theres a big difference between a 10 user intranet application and a million user application.
  • What is the timeline for development?
  • What kind of budget are you working with?
  • How active is the community that maintains and contributes to the CMS?
  • How much of the CMS will you have to customize? Are there plugins that do what you need?

For a site like CollegeHumor, we needed to understand and control every line of code. Everything from the framework to the content management application is all home grown. But like I said before this doesn’t make sense for everyone. If you are building a small intranet site and can do the bulk of the work in a CMS, there is no reason to reinvent the wheel. If your site handles several million hits a day you may not want the extra overhead that a CMS comes with maybe rolling your own makes sense. Evaluate what you are working with and make a choice that best fits your project.

Facebook Invite Bookmarklet

One of the best Facebook features is the ability to invite friends to events. The most annoying part about this system is the inability to invite more then 100 friends at a time (Facebook: wheres the invite all!?). In the past I have clicked one by one and sent invites in blocks of 100. Today was the day that I had enough! I made a bookmarklet to automate the bulk of the process. Unfortunately it can’t do all the work for you, but it will automatically adds users to the invite in blocks of 100 with a single click. Heres how it works…

Step 1) Log in to Facebook and browse to the event “Invite people to come” page.

2) Setup a new bookmarklet with this code (or optionally paste in the address bar on that page):

javascript:var e=document.createElement('script');e.setAttribute('type','text/javascript');e.setAttribute('src','http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js');setTimeout( function() {var friends = $$('#friends_list span input'); var offset = parseInt(prompt('Please enter an offset')); if(offset > friends.length){alert('All done!');}for(var x = offset; x <= offset + 100; x++) {friends[x].onclick();}}, 3000);void(0);

3) Click the bookmarklet and enter 0 when prompted. (0 represents your current offset, you will need to keep track of this.)

4) Click invite

5) Repeat and increase the offset by 100 until all friends have been sent invites

Hacking the .SVN directory

The other day on College Humor and Bustedtees we discovered a fairly serious security vulnerability. Fortunately because of the layout of our code nothing malicious could be exploited (more in another post). We thought our “push” script was skipping .svn folders, it turned out to not be operating correctly.

The hack is simple, documented and easily overlooked. Once the vulnerability was found, I did my best to exploit the shit out of it. I did so very successfully. I even tried it on some other popular websites and was able to access files I should have never been able to. In one instance I gained limited access to a sites admin. I emailed all of these sites to notify them of the security vulnerability. They were most gracious, once company even sent me a gift card!

The hack obviously starts in .svn directory, specifically at the entries file. You can access this file by browsing to:

http://www.somedomain.com/.svn/entires?

This document contains all of the files and folders svn manages in that directory. In some instances you can locate admin directories and the same thing applies…

http://www.somedomain.com/admin/.svn/entries?

So at this point all you have are a bunch of file names. Sometimes you can get some fun information and access to files that were meant to be hidden. Security by obscurity is not a solution, protect files you don’t want the public to access!

Now this is where things get interesting… Any file that has been checked in I can now execute. Either directly or through an svn folder that holds file revisions. Pick any file in the list and browse to:

http://www.somedomain.com/.svn/text-base/filename.php.svn-base

In this example the PHP file will be put through the PHP parser and executed. The results really depend on the layout of the code. Depending on the way the coder uses includes/requires decides on how much access and what kind of output you get. If a file is included using a relative path, the includes won’t be included since your working directory is the text-base dir. If they are using absolute paths, includes will continue through the execution. In one of the sites I poked around in, I found their admin wrapped through some kind of lite template/framework. I was able to bypass the system and go directly to the file without a using password. From there I had limited additional actions, but I still gained access to where I wasn’t welcome.

To do some additional testing I setup a test site to play with other file types. I found that files without a PHP extension, for example .inc files were NOT parsed and instead the contents were spit out to the page. In this test case the .inc file contained passwords and locations to databases. The possible additional damage I could cause from here is endless…

I’m not the first one to discover this hack, although a quick search only revealed obvious prevention methods. Protecting your site is really simple. Add this to your htacces file:

RewriteRule (\.svn)/(.*?) - [F,L]

Another option is blocking .svn folders through your web server config file for all sites.

Update
A number of people have mentioned a better prevention technique… They recommend doing an SVN export instead of a checkout or rsync. This was something I thought about after discovering the exploit. But I am by no means a system admin or the person who deals with that stuff at work. I’m glad these people were able to confirm that idea. Thanks!

PriceAdvance Passes 100,000 Firefox Installs

PHP Recursive Multidimensional Array Flatten Using SPL

function array_flatten_recursive($array) {
    if($array) {
        $flat = array();
        foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST) as $key=>$value) {
            if(!is_array($value)) {
            $flat[] = $value;
        }
    }

    return $flat;
   
    } else {
        return false;
    }
}

$array = array(
    'A' => array('B' => array( 1, 2, 3, 4, 5)),
    'C' => array( 6,7,8,9)
);

print_r(array_flatten_recursive($array));

– Response:

Array (
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 7
    [7] => 8
    [8] => 9
)
</pre>

PriceAdvance Passes 50,000 Firefox Installs

pa1.jpg

The holiday shopping season has been really good to us!

Holiday Spending

“For the holiday season through December 12, $19.44 billion has been spent online, essentially the same level compared to the corresponding days last year. For the twelve days beginning with December 1 (Cyber Monday), the kick-off to the heaviest part of the online shopping season, sales totaled $8.26 billion, up 3 percent versus year ago. However, the most recent work week (December 8-12) saw e-commerce sales decline by a marginal 1 percent, although December 9 emerged as the highest online spending day on record.”

— comScore – regarding online sales in 2008

via (Fred Wilson)

Whats new…

I was recently promoted to the Director of Back end Development for Connected Ventures. I now oversee all coding for College Humor, Bustedtees and Todays BIG Thing. The promotion came about a month ago when Kunal Shah announced he would be leaving CV to go out to San Fran to do a startup. His last day was just before thanksgiving and I have finally had two weeks to settle into the new role. Kunal left some serious shoes to fill. He helped make CV into the company it has become and was the best managers I have ever work for. He left me an incredible team and I hope I am able to pick up where he left off. He is already greatly missed.

On side projects… PriceAdvance is doing pretty awesome right now. We are doing about 3200 downloads a week and 77,000 overlay views a month. We were recently written up in Consumer Reports which has been syndicated to a ton of news broadcasts and has been driving traffic for the past 2 months. I also started another mini side project with John Zanussi, that I hope to expand on some day. Tumbltape, which takes audio posts from tumblr and turns them into a muxtape style playlist.

I have been a pretty lazy blogger recently. I hope to put together some interesting articles about Connected Ventures projects, my side projects and random development and techy stuff.

PriceAdvance on ConsumerReports MoneyAdviser

PriceAdvance on ConsumerReports MoneyAdviser: http://www.9news.com/rss/article.aspx?storyid =103552

Recursive PHP in_array function

I needed a recursive in_array function the other day and disliked all the samples I found on php.net. I wrote this one using the StandardPHPLibrary. It will recursively search through a multidimensional array and return true if the $needle is found in the $haystack.

function in_array_recursive($needle, $haystack) {

    $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack));

    foreach($it AS $element) {
        if($element == $needle) {
            return true;
        }
    }

    return false;
}