Thursday, July 17, 2008

How to create a Google Powered Site using Coldfusion

Farewell Typewriter's website is the one site I built that is pretty much Google powered. The site also integrates Blogger feeds so that the content owners can utilize already existing tools to publish news & blogs. In addition, I used Picasa to power the photos section, Youtube for the video section, Google Groups for the mailing list, Google Checkout for the merch store, Google Analytics for site statistics, and soon to be Google calendar for show dates.

Here's a snapshot of that site:





SETTING EVERYTHING UP:



Set up is quite easy and it starts out with you opening up a Google account if you havent already. From there, you'll be able to set up everything from your calendar, to your blogs, and your photo albums.

Setting up Google Analytics, Groups, and Checkout is easy. Just follow the simple steps in setting up your account. At the end, all you need is a snippet of code they provide that you can simply copy and paste into your pages.

For YouTube, the easiest way is to create a video playlist and copy and paste the code they provide at the end to embed the YouTube player into your page. Remember to choose the embed code, not the link to the player.

SETTING UP BLOGGER AND PICASA PHOTO FEEDS



Setting up Blogger is a bit trickier. The key thing is to set up your account to publish to an FTP site. You may find this on your Blogger dashboard under Settings > Publishing.

Once you're in the Publishing settings page, make sure you set view permissions to "Anybody" and also set the default template to "Classic" (you can always change this later). From there simply provide all your host/ftp information. Make sure that if you intend to run any sort of Coldfusion code to change the Blog File Name extension to "cfm". Hit Save Settings, submit, and publish. If all goes well, your blog will soon start publishing to your own server.

To display blog feeds/headlines, first look for the rss.xml feed file usually located in the root directory of your Blog File Path. Once you have that information, use the following code on your page to parse the xml feed so that you'll be able to manipulate it later:

<cfhttp url="http://www.yourdomain.com/your_blog_file_path/rss.xml" method="get">


This will let enable you to grab the feed via cfhttp. You can then use, xmlParse to create an rss object and parse the xml feed:

<cfset objRSS=xmlParse(cfhttp.filecontent)>


To temporarily view the contents of this object, use:

<cfdump var="#objRSS#">


That will give you a glimpse of the actual contents of the feed in an easy to view structured format. From there, you can easily figure out how to display the right content by traversing through the "branches" using dot notation. You're essentially drilling down to get to your content much like trying to get to a particular file located in a series of subdirectories. For example, to display the title of the first blog on the list, simply output the following:
#objRSS.rss.channel.item[1].title.XmlText#

To display the second one, simply change the array count to 2:
#objRSS.rss.channel.item[2].title.XmlText#

...and so on. Simple, right?

Now this is fine but not very efficient. Most likely, you will want to dynamically show say, 10 items at once. This can simply be achieved using cfloop and looping through the feed as many times as you want. The code to do this is:
<cfloop index="i" from="1" to="10">
#objRSS.rss.channel.item[i].title.XmlText#
</cfloop>

That particular code will allow you to display up to 10 feeds. Remember that the attribute value of to should be less than or equal to the total number of items in your feed. If you specify 10 and you only have a total of 2 items in your feed, Coldfusion will throw an error.

Well then, what if you want to dynamically display the total number of items in the feed which could vary? Simply create a variable set to the total array number of your feed as such:
<cfset variables.itemLength = arraylen(objRSS.rss.channel.item)>

Then plug that variable as the attribute of to in your loop tag like so:
<cfloop index="i" from="1" to="#variables.itemLength#">
#objRSS.rss.channel.item[i].title.XmlText#
</cfloop>

Now, you have a code that will dynamically display all the specified items in your feed.

Most people will probably want the title to be clickable so that it points to the actual content of the blog. That's fine. Simply go back and view the objRSS structure and look for the item link. Eventually, you're code will probably end up like this:
<cfloop index="i" from="1" to="#variables.itemLength#">
<a href="#objRSS.rss.channel.item[i].link.XmlText#">
#objRSS.rss.channel.item[i].title.XmlText#
</a>
</cfloop>


Congratulations! You've just dynamically integrated Blogger into your site.

Integrating Picasa photo feeds uses the same concept except you'll need to point directly to the Picasa feed album on Picasa's server since at this moment, Picasa doesn't have the ability to upload your photo album into your FTP server. You should be able to find a link to that feed when you log in to your Picasa Web Albums account. Remember though: The structure, though similar in form, will be slightly different so don't try to copy and paste the exact code above. It wont work. Make sure you traverse through Picasa's own feed structure.

That's it! Hope you find this tutorial useful.

Securing Your Coldfusion Apps using Parameterized Queries

When we're developing websites, we often become complacent. Maybe we're too lazy, maybe we're rushing to meet deadlines, or maybe we're just too naive. I'm guilty of this myself. Often times though, this complacency can have disastrous consequences.

I used to think my applications were secure until I heard about a little devil called "SQL Injection." Essentially, it's a type of intrusion technique hackers use to compromise and hijack your system by taking advantage of a loophole in your database. This is initially done simply by appending a malicious SQL code at the end of a url pointing to a page running a database-driven app, in essence, "injecting" the code into your database query.

THE SOURCE OF THE PROBLEM

For example, let's say you have a simple knowledgebase page. Perhaps this page displays data stored in a simple knowledgebase table. One very common way of accessing a specific record from that table would be to pass a parameter via the url like so:

http://www.yoursite.com/knowledgebase/showarticle.cfm?id=12
Consequently, in the showarticle.cfm page, you may have this simple coldfusion query:
SELECT ArticleBody FROM KnowledgeBase WHERE id = #url.id#
Using the right cfoutput tags, that would of course output the content of ArticleBody whose record id equal 12.

"What's wrong with that?", you say.

Well, in an ideal world, nothing. That's a perfectly valid SQL statement...with one tiny flaw.

TIME TO WRECK HAVOC

Suppose a malicious hacker came across your knowledgebase page and determines that it does indeed run an SQL query. Well, just to be a jerk, he might try typing the following on the address bar:
http://www.yoursite.com/knowledgebase/showarticle.cfm?id=12;DELETE FROM KnowledgeBase

Guess what happens when he hits the return key. That's right! Every single record in your KnowledeBase table just went bye-bye. How's this possible? Well, see that little semi-colon after the id number? It enables two or more SQL statements to be executed on the same line. No, it's not a flaw or a bug in SQL. It's a perfectly legal way to write SQL statements and its fine until your expose your query to the world. Sure, in this case, Mr. Hacker still needs to guess the table name but it often doesn't take a genius to guess that most KnowledgeBase tables are named, well, "KnowledgeBase", or that User Account data are stored in the "Users" table with a "username" and "password" as field names.

Now if that makes you cringe, good because that's just the tip of the iceberg. I've only shown you one method of doing doing SQL injection. A skilled attacker can execute a multitude of attacks including displaying sensitive data such as user account information, perform UPDATE and INSERT statements to manipulate data, even execute shell commands which can eventually create a security breach all the way to the very depths of your network.

PARAMETRIZED QUERY TO THE RESCUE

Fortunately, most scripting languages offer a way to protect against this. In Coldfusion, one way of preventing SQL Injection is to parameterize your queries. In layman's term, you're essentially setting a set of conditions to filter the data before it is passed into you SQL statement thereby limiting and ultimately preventing any other data to be passed other than those you expect.

It's not rocket science either. In fact, in Coldfusion, it's as simple as using the cfqueryparam tag in your SQL statements. The syntax is as follows:
<cfqueryparam cf_sql_type="(data type)" value="(string or variable)" maxlength="(character limit)">

So, using our original SQL statement above, you might use it as such:
SELECT ArticleBody FROM KnowledgeBase WHERE id =<cfqueryparam cfsqltype="cf_sql_integer" value="url.id" maxlength="3">
In this case, under you're essentially telling Coldfusion to only accept an integer for the value of url.id with a length no greater than 3 digits. In doing so, you've pretty much limited the ability of the attacker to append extra code to your sql statement. Anything other than an integer value exceeding the maximum character length will be rejected. If your cf_sql_type is a numeric value, you may even add the scale attribute, such as scale="2", to limit the numeric value to a real number with 2 decimal places. If you're expecting a string, simply use cf_sql_varchar for the value of cfsqltype. For more information on this tag, visit:

http://livedocs.adobe.com/coldfusion/6.1/htmldocs/tags-b20.htm

As an extra precaution, make sure you turn off verbose debugging in Coldfusion to prevent the attacker from seeing the details of the error page Coldfusion throws if it in fact detects an invalid data type.

To increase its effectiveness, you should also consider using this method in conjuction with other security measures such as turning off shell access, restricting tags/commands, setting proper database permission, flattening data, and turning off verbose debugging. I will go further into other methods in upcoming articles.

AN OUNCE OF PREVENTION

As you can see, one simple extra step can go a long way. Like the saying goes, "An once of prevention is worth a pound of cure." Next time you're feeling lazy writing that extra code, just think of the risk you're taking.

Now go back to your code and see how many queries you can parameterize!