Storing Passwords

Friday, November 14th, 2008

I recently had a discussion about web app security and we were talking about the not-so-distant past when SQL-injection was the scariest thing since polio.  90% of these attacks didn’t try to return everyone’s credit card information from a database (people knew pretty early to be careful when storing this stuff), they were attempts to simply return a username and password.  

As a result, many people would go to a site that doesn’t need very much security (like a forum), and run some sort of sql-injection to return all username/password combinations from the database.  Then they would spend the whole day going from bank-website to bank-website, trying each and every one of these combinations (not only do most people use ridiculously simple passwords, they also re-use them for multiple sites) and they may get one login from one bank.  This could turn into several thousand dollars by draining that single account.  

Now, I know things have changed quite a bit, and bank websites have stepped up security standards a good deal.  I also realize that convincing people to be smarter about their login passwords would be a major challenge. However, I’m always shocked to find out that some web developers still store passwords in plain text in dB column called “password”.  

That brings us to one of the simplest methods for securing against password retrieval, that many people just don’t do. Now, there are many ways to secure against sql-injection, but let’s pretend for one minute that, somehow, someone gets the information in your database.  It doesn’t matter if it’s through injection, or getting your shared-host login from something, or someone having direct access to your server.  But let’s just say someone has your dB data, and they have all of the stored username/password combinations.  

The easiest thing to do is use a digest or hash for password storage.  You never actually need to retrieve this password, you simply need to compare a password against it.  By comparing the same hash of the input password against the stored hashed password, you are achieving the same thing. Your logins work exactly the same, except you have 4 extra lines of code.  

For another small method to improve security, add some secret letter/number/symbol combination to the word before storing/comparing.  Because most people have terrible passwords, if someone does get the information, they could get the passwords from sites that build dictionaries of MD5, SHA1, etc. combinations.  So by adding a small snippet to the end of the password, not only are you improving security against a dictionary attack, but you are differentiating this password from the user’s password that may be used some where else.

Most developers, I hope, will have learned nothing new from this article and will consider it quite obvious.  That’s a good thing.  But after hearing from a few individuals who still used plaintext storage of passwords, I felt as though this might help someone.  


simpleCart(js) + PayPal = E-commerce in minutes

Tuesday, October 28th, 2008

**update: v1.2: fixed rounding error in price formatting
**update: v1.1: back button works, no trailing comma for options

(if you want to skip right to the example and downloads, check it out here)

Over the past few years, our company has had several clients who have needed a smaller shopping cart, usually to sell just a couple of items. We generally built these small carts using paypal. I realized it would be nice to package this up, and create a lightweight, easy-to-use, flexible shopping cart.

So we made simpleCart(js). The cart is a 10.5kb javascript file that uses cookies to keep track of the items in the cart. SimpleCart(js) doesn’t require any databases or programming knowledge. You simply need to know some basic HTML and have the ability to copy and paste. However, it can easily be expanded to use databases or contain more advanced options.

Setup Paypal

The first thing you will need to do, if you don’t already have one, is set up a free merchant account with Paypal.

Add simpleCart(js) to your pages

Once you have the files downloaded, simply add this snippet to the top of any page you wish to have the cart running on:


<script src="simpleCart.js" type="text/javascript"></script>
<script type="text/javascript"><!--
simpleCart = new cart("you@yours.com");
// --></script>

You will need to replace you@yours.com with the email address you used to sign up to Paypal.

Adding items to the cart

Any page you have the simpleCart(js) running, you can add an item by simply using a link like this:


<a onclick="simpleCart.add('name=[name]','price=[price]');return false;" href="#"> link to add item </a>

You are required to at least have a name and price when adding an item to the cart. However, you can add other fields also. If you want an image to be linked to the item, you can add it like this:


simpleCart.add('name=Shirt','price=6.00','image=images/myImage.png');

Viewing the cart

You may have the cart on any page, and it will update automatically using ajax. To show the cart items on a particular page, you simply need to have an element with the class of “simpleCart_items” on the page. This element will automatically be filled with all of the items in the cart, and will show each field.


<div class="simpleCart_items"></div>

You can use any element (div,a,span,p,etc.) and the values will be put in the innerHTML of that element.

Showing the totals on a page

You can show the total quantity or price on any page by simply having an element with a class “simpleCart_quantity” or “simpleCart_total”:


<div class="simpleCart_total"></div> <span class="simpleCart_quantity"></span> items

Checkout and Empty Cart links

You can have a checkout or empty cart link anywhere on any page where the simpleCart(js) is active. You do this by simply setting the class of an element to “simpleCart_checkout” or “simpleCart_empty”:


<a class="simpleCart_checkout" href="#">checkout</a>

<a class="simpleCart_empty" href="#">empty cart</a>

You can use any type of element for these, and you can put anything inside of the element. Anything wrapped in a tag with those classes will link appropriately.

Other Options

Adding other product options to items.


simpleCart.add('name=Shirt','price=6.00','image=images/myImage.png','size=XL','color=Blue');

You can also change the quantity that will be added to the cart:


simpleCart.add('name=Shirt','price=6.00','image=images/myImage.png','quantity=5','size=XL','color=Blue');

The order of the arguments doesn’t matter, and you can add as many options as you would like.

Styling the cart.

You can style this cart to fit the look of your page. The contents of the cart will start with a header row:


<div class="cartHeaders">
<div class="itemImage">Image</div>
<div class="itemName">Name</div>
<div class="itemPrice">Price</div>
<div class="itemOptions">Options</div>
<div class="itemQuantity">Quantity</div>
<div class="itemTotal">Total</div>
</div>

Each item in the cart will have the following form:


<div class="itemContainer">
<div class="itemImage">[myImage]</div>
<div class="itemName">Shirt</div>
<div class="itemPrice">$6.00</div>
<div class="itemOptions">size: XL; color: Blue</div>
<div class="itemQuantity"><input type="text" /></div>
<div class="itemTotal">$30.00</div>
</div>

And there will also be a totals row:


<div class="totalRow">
<div class="totalItems">6</div>
<div class="totalPrice">$30.00</div>
</div>

You can choose to omit part of the cart in your stylesheet:


.itemOptions,itemImage{
display:none;
}

Or you can hide the header or totals rows:


.totalRow{
display:none;
}

.cartHeaders{
display:none;
}

Change the order of the cart columns.

If you would like to change the order of columns or remove the columns from ever being shown, simply add a line to the top of your page:


<script type="text/javascript" src="simpleCart.js"></script>
<script type="text/javascript">
simpleCart = new cart("you@yours.com");

//Add the following line to reorder and remove item columns
simpleCart.ItemColumns = ['Image','Price','Name','Quantity','Total'];

</script>

Download and Demo

Below are links to download simpleCart(js) and to view a working Demo. One great thing about the cart being stored in cookies is that you can have your items be added on one page and the cart be on another if you wish. The demo reflects this. The main page of the sample store is here and the View Your Cart page is here.

Download simpleCartGo to Demo of simpleCart


10 Easy Steps to Great Website Optimization.

Sunday, October 12th, 2008

You could write a book on website optimization, in fact people already have. But, here’s 10 really easy steps to getting your sites optimized for speed. Hopefully this will get you started and you’ll want to investigate front end optimization a little further.

1. Run your images through smushit.com.

While it’s obvious to keep your image sizes down as low as possible, it’s not as obvious that some image editing programs like photoshop can add extra meta and formatting data in your images. Its viewable if you open the image in a text editor. Smushit is a firefox plugin that strips out all of this extra formatting and can reduce your image sizes without sacrificing quality. Once the plugin is installed, simply go to the webpage you want to optimize, click the smushit icon in the bottom right of your firefox window, and smushit will tell you how much you can save on each image as well as give you a zip file filled with the smushed images.

2. Use the Fastest CSS Selectors.

When styling elements with CSS there are many ways to specify what you’re styling and some of those ways are faster than others. According to this study by John Sykes, you should first try to just style tags:

a

the next fastest way to select something in css is by class:

.link

Then its descenders:

div div div p a.link

finally the slowest is child selectors:

div > div > div > p > a.link

3. Combine all of your non-repeating background images into one giant sprite.

Reducing HTTP requests is a huge part of website optimization and images can be the biggest culprit. So one easy thing to do is combine all of you background images that don’t repeat into one big image. Most time it helps to not put any spaces between the images and to build the sprite horizontally to make the smallest image. Then in your css you can specify the background image like this…

>.myClass{
background:url(images/bigImageSprite.png) -12px 0 no-repeat;
}

( “-12px 0″ specifies to display the image 12px to the right and 0px down)

4. Run all of your css and JS files through compressors.

Keeping code file sizes down is another no brainer. So run your CSS and JS through optimizers/compressors. For your CSS stylesheets there are plenty of optimizers out there. In fact there is a great round up and review of many of them here. I agree with the round up that the Icey CSS Compressor does a great job. In fact it reduced the stylesheet of this blog by 23%.

When it comes to compressing your JS the best service is Yahoo’s YUI compressor. Other services are either unsecure, or don’t do as well a job. You can download the YUI compressor here. Or you can use this online version from refresh-sf.com. While we’re on the subject of compressing your JS, Prototype and Scriptaculous could use some compressing. So if you use those frameworks get the compressed version aka Protopacked.

5. When saving images, try jpg, png, and gif.

There is no one image file type that always yields the smallest file sizes. So when possible try all of them. Of course there are times that a jpg just won’t guarantee the correct colors that you need, but when you can try exporting your images as each type and see which is the smallest. Photoshop’s “save for web and devices” feature is great for this. It tells you what the file size will be before you have to actually export the images.

6. Place <script> tags at the bottom of the page.

This one isn’t always possible, but try as much as you can to put all your scripts at the bottom of the page. When a browser is downloading the assets to a page it goes through your html file to find what to retrieve. It generally downloads multiple items in parallel  (we’ll discuss that more later), but since a script can change anything and everything on the page it stops everything and downloads just that one script file. So if you put it at the end the browser will download everything as fast as possible first, then it will download your scripts.

7. Attach external scripts without blocking parallel downloads.

If you can’t put your <script> tags at the bottom there is a way you can put them in your page without blocking parallel downloads. You can do this in a variety of methods, but each has their own pro’s and cons. My personal choice is to add the <script> tag via the DOM. This allows you to have a download progress indicator in at least firefox (no IE, sorry), and to put your scripts on subdomains (see rule 8).


var js = document.createElement('script');
js.src = 'scriptName.js';
js.type = 'text/javascript';
var head = document.getElementsByTagName('head')[0];
head.appendChild(js);;

For more options see Steve Souder’s power point presentation on “Even Faster Websites”.

8. Put assets on sub-domains to increase parallel downloads.

The idea behind this tip is that browsers only download 2 items in parallel per domain. This is part of the HTML 1.1 spec. So if we can download 4 or even 8 things at a time we’ll get faster page downloads. To get more downloads to run in parallel we use the loophole in the “2 downloads per domain” rule, namely, the fact that it says, “per domain”. So make some sub-domains and spread your assets out. I recommend putting your images on one and your html, css, and scripts on another.

However, you must keep in mind that it’s not advisable to have too many DNS lookups in your pages. Each sub-domain forces the browser to do a DNS lookup which hurts speed. The yahoo performance team did some research on this area and came up with the conclusion that you should use at least 2 but no more than 4 host names.

9. Disable E-tags

E-tags are a way that servers check to make sure the file in your cache is the same file that’s on the server. It basically applies a unique identifier to each asset to do this. The problem is that when your site is on a server farm and multiple servers are processing requests, the e-tag will fail from server to server. It will match on the first server but will fail on the rest, thus forcing you to re-download the file that it already cached.

Disabling E-tags only really helps those sites that are on such server farms, so if you’re on a shared host its not always going to help, but it is still recommended because shared hosts routinely change servers and you might even change hosts as well. Plus it’s drop dead simple. Add the following line to your .htaccess:

FileETags none

10. Gzip your components.

Ok so this one might not fit into the “Easy Steps” part of this list, but in some cases it will. The basic idea here is to, once again, reduce file sizes. By Gzipping your components you’re reducing the file sizes of the browser’s downloads.

There are several methods you can use to Gzip your files, but depending on your server and host it might become tricky. The easiest way to do it if you’re running Apache is to first verify what version of Apache you’re running. To do this you can use firebug and look in the net panel for the server response header. You should see it.

There is also a good chance your host has the Apache version stated in the control panel somewhere.

If your Apache is version 1, add the following to your .htaccess file in your root directory:

mod_gzip_on Yes

mod_gzip_item_include mime ^application/x-javascript$
mod_gzip_item_include mime ^application/json$
mod_gzip_item_include mime ^text/.*$

mod_gzip_item_include file \.html$
mod_gzip_item_include file \.php$
mod_gzip_item_include file \.js$
mod_gzip_item_include file \.css$
mod_gzip_item_include file \.txt$
mod_gzip_item_include file \.xml$
mod_gzip_item_include file \.json$

Header append Vary Accept-Encoding

If you have Apache 2 add this to the .htaccess file instead:

AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml
application/x-javascript application/json
Header append Vary Accept-Encoding

There are many situations where your shared hosts will not allow you to edit your .htaccess file or editing it to enable gzip just won’t work. If thats the case follow this post from fiftyfoureleven.com. It shows a variety of ways to achieve this, some using php.

Further Reading

This article just scrapes the surface of out what’s there as far as website optimization. I hope this at least gets you thinking in terms of optimizing your sites. If you’d like to read more I highly encourage reading Steve Souder’s blog, Website Optimization Secrets (O’Reilly), and the Yahoo Optimization page (which used to be captained by Steve Souder). Also be sure to check out YSlow, and the Webkit Element Inspector (also found in chrome).


Writing your own code vs. Plugins

Tuesday, September 30th, 2008

Recently I have been discussing with some fellow coders the benefits of plugins, and when you should write your own code.  I basically wanted to throw out a couple of ideas and hope for some discussion on the topic.  Let me know what you guys think and I’ll do a follow up soon.

Some Background

I, like many of you out there, started programming back in the day by messing around with computers, writing little calculator programs, making websites, etc.  But I really didn’t get into it much more until I started college, where I immediately started programming with C++.  

Most of my classes started out with projects where we had to write everything (no STL!), and all of my code was from scratch.  Once I started doing more of the “development” in “web design and development”, I still practiced the idea that the only code I know is good is the code I write.

But now I can see…

Then one day, the skies parted, trumpets sounded, and my designer Steve said “Hey, have you heard of Ruby on Rails?”  

I immediately started developing with nearly pure Rails, using the built-in-just-about-everything and loving the fact that anything I couldn’t code (or didn’t want to) was usually readily available in plugins ( I love file_column!).  

I will say this, RoR is good code.  And it’s constantly being improved.  For the most part, the plugins are also good code.  And many times, a plugin works perfectly into your project to save you time and add functionality.  

Good Programming

Ask any real programmer, and the efficiency of code is not only about how it performs, but how long it takes you to create.  So obviously there is a trade-off between using plugins and writing your own code.  

That being said, if you are a web designer who is using rails to help you out, or just trying something new, use the plugins: they are great and it will save you days of coding and headaches.  

If you consider yourself a developer (or hope to), you should still use plugins.  If you code everything, you’re going to waste time. However, don’t completely rely on them.  If you want to be a programmer, you need to know how things work, because some day there won’t be a plugin for you, and you’re going to need to know what to do.  

Also, plugins are meant to be helpful for a range of situations.  Therefore, there is going to be some overhead.  If you are concerned with performance, and a plugin isn’t “perfect” for what you’re trying to do; you might need to code from scratch (or at least be prepared to customize the plugin code).

Here’s the thing…

All things considered, I will say that my natural tendency is to code most everything myself.  I like to know where everything is, and exactly what the code is doing.  I also appreciate when the code is only doing exactly what I want it to do.  If it’s impractical to write something, by all means I will ( and do ) use plugins.  

If you want some good coding experience, and have the time, try writing something yourself that you wouldn’t normally do.  Even if you don’t end up using it, you’ll learn a bit more about RoR (or any other language) and you may just have some good code you can use again.

Agree? Disagree? Don’t care?

I’m just one guy.  Let me know what you guys think.


Remember Me’s with Rails

Friday, September 26th, 2008

I recently had a need for a login system that needed a ‘remember me’ function. After hours of looking through countless blogs, I came to the conclusion that either (1) people don’t use a remember me function with custom authentication systems for Rails, or (2) they don’t talk about it. In this article, I outline a simple remember me system using the cookie variable in Rails that will tack on to most custom authentication systems.

Using the cookie functions in Rails is pretty straightforward. It’s used with the ActionController and is quite simple to use. Most people use sessions for authentication, which is a good idea. Sessions, unlike cookies, automatically save your content as encrypted strings using the browsers cookies. ActionController#cookie provides a method for saving information in the browser, but you need to encrypt the content yourself if need be.

However, if a user selects the remember me option when logging in, we would like to have the session expiration set to be a longer period, like 30 days. Unfortunately, this is quite difficult to do if you don’t want to change the expiration of ALL sessions.

My site already uses sessions for authentication, and I’m going to leave that be. In fact, I’m not going to change anything about the session variable at all. This way, I can add this remember function to almost any authentication system I use in the future very easily.

When a user is authenticated and has selected the “remember me” option, I do two things:

- create a cookie that stores (plain text) the user’s id (you can use name, email, etc. but I prefer the id because it says nothing about the user to anyone trying to get information)

- create a second cookie with an encrypted string of some other information about the user( name, email, address )

if params[:rememberMe]
   userId = (@user.id).to_s
   cookies[:remember_me_id] = { :value => userId, :expires => 30.days.from_now }
   userCode = Digest::SHA1.hexdigest( @user.email )[4,18]
   cookies[:remember_me_code] = { :value => userCode, :expires => 30.days.from_now }
end

For the encryption of the second piece of information, use a one-directional encryption such as SHA1. We can use these two cookies to authenticate a user when they return after a session has expired.

if ( cookies[:remember_me] and cookies[:remember_me] and User.find( cookies[:remember_me]) and Digest::SHA1.hexdigest( User.find( cookies[:remember_me] ).email )[4,18] == cookies[:remember_me_code]  )
   @u = User.find( cookies[:remember_me_id] )
   session['user'] = @u.id
end

Just work that into your :before_filter for your authentication system, and you’re all set. Make sure you delete the variables when someone logs out:

if cookies[:remember_me_id] then cookies.delete :backbone_id end
if cookies[:remember_me_code] then cookies.delete :backbone_code end

****Edit: make sure to have “require ‘digest/sha1′” at the top of any page where you are using the SHA1 encryption.