// A skewed take on the consulting business.
 

ASCIIcasts Summary #178: Seven Rails Security Tips
Posted by Kevin on September 13, 2009 04:24

ASCIIcasts rock. There's a place for screencasts and video demonstrations, but conveying something like the points in Seven Security Tips isn't one of them. The only thing better is just giving a summary, so here it goes.

1. Use attr_accessible in your model to avoid side effects with mass assignment.

When assigning object values with something like User.new(params[:user]) or update_attributes(params[:user]), unintended fields, like allow_admin or has_many relations, may be set with a tool like curl. To prevent this, use attr_accessible in the model to whitelist the fields mass assignment may use.

2. Use validates_attachment_content_type to whitelist upload content types.

You do not want users to upload PHP scripts and whatnot to an accessible portion of your site.

3. Enable filter_parameter_logging for fields that should not be saved in the log files.

It's bad enough when developers fail to encrypt passwords in a database. The next worse blunder is logging the unencrypted passwords. Use this in your application_controller.rb to filter occurrences of parameters. See the Rails API entry for more info. API summary: the filter operates on case-insensitive substrings of all parameters defined.

4. Protect against CSRF by adding protect_from_forgery to your ApplicationController.

Simple yet effective.

5. Scope your Active Record finds to the current user.

This is an easy one to overlook. The first trick is making sure your relationships are defined in your models. Once they are in place you can leverage the association magic: current_user.orders.find(params[:id]).

6. Fer cryin' out loud, parameterize your SQL already!

This should be self-explanatory. In fact, it shouldn't even need mentioning. OK, here's a snippet stolen from the ASCIIcast which borrowed from the Railscast:

@projects = current_user.projects.all(
    :conditions => ["name like ?", "%#{params[:search]}%"])

7. Sanitize user provided values when displaying HTML.

The Railscast instructs you to use the h method (e.g. <%= h comment.naughty_value =>), but since Rails 3 will do this automatically, you might be better off using xss_terminate which is a handy "install and forget" plugin.

ActiveScaffold and FCKeditor
Posted by Kevin on September 07, 2009 04:24

To paraphrase a common saying, "open source software is only free if your time has no value." Such was the last day of work while trying to integrate ActiveScaffold and FCKeditor. The sad thing is that it really shouldn't have been this way.

For starters, people really need to update their project's documentation (see most of the README files on github). Secondly, the documentation should include a somewhat logical example. Each code snippet should meaningfully pertain to the other, related code snippets. Thirdly, the example code should actually work. Fourthly, the previous three rules go doubly if you are dealing with JavaScript.

OK, I'm finished venting. Let's get to the meat and potatoes. I'm assuming you have a model working with ActiveScaffold, which is generally pretty simple to get up and running.

The two primary resources for installing were the (a) github page for the github fckeditor plugin and the most useful, but slightly incomplete, FCK Editor Plugin in ActiveScaffold. Without further commentary, here are the steps, minus the premature balding inducing frustration.

Install the FCKeditor plugin from within your Rails application:

script/plugin install git://github.com/davividal/fckeditor.git
rake fckeditor:install

The following steps relate to a simple admin controller for an equally simple About model.

script/generate model about content:text published:boolean
rake db:migrate
mkdir app/controllers/admin
mkdir app/helpers/admin/
mkdir -p app/views/admin/about
touch app/controllers/admin/about_controller.rb
touch app/helpers/admin/about_helper.rb
touch app/views/layouts/admin.html.erb
cp vendor/plugins/active_scaffold/frontends/default/views/_create_form.html.erb app/views/admin/about/
cp vendor/plugins/active_scaffold/frontends/default/views/_update_form.html.erb app/views/admin/about/

The Admin::About controller:

class Admin::AboutController < ApplicationController
  layout 'admin'
  active_scaffold :about
end

The following lines need to be included in your admin layout:

<%= javascript_include_tag :defaults, "builder", "scriptaculous", "fckeditor/fckeditor" %>
<%= active_scaffold_includes %>

Here's the about helper:

module Admin::AboutHelper
  def content_form_column(record, input_name)
    fckeditor_textarea(:record, :content, :ajax => true, :width => '800px', :height => '200px')
  end

  def content_column(record)
    sanitize(record.content)
  end
end

In the two admin/about partials, you need to replace submit button code with the following:

&lt;input type="submit" value="Update" class="submit"
       onClick="var oEditor = FCKeditorAPI.GetInstance('record_<%=@record.id%>_<%='content'%>_editor');
       $('record_<%=@record.id%>_<%='content' %>_editor_hidden').value = oEditor.GetXHTML();" /&gt;

Substitute Update for Create as appropriate. This last bit is very important, and not mentioned pretty much anywhere except Ganesh's post. You'll notice one important difference from his code though: when assigning the hidden variable you need to actually add the "_hidden" part to the id.

Hopefully this helps someone roll with FCKeditor and ActiveScaffold (or Ajax in general) without wasting their Labor Day Sunday as I did. Let me know if something doesn't work. I know that input statement needs real angle brackets, but I'm too tired to debug that display issue just this minute.

UPDATE: Since all my new projects use jQuery, I'll be switching to this jQuery.wysiwyg.

Identically Named Methods in a Rails Controller
Posted by Kevin on May 26, 2009 18:17

First off, never do this. Of course, you wouldn't. Except by accident. I'm only admitting to it in the hopes someone else out there doesn't waste too much time with something so simple.

I was RESTifying a controller by whitelisting methods and then testing. For #show I forgot to delete the private version before testing. Hilarity ensued. Neither Mongrel or Thin would tell me there was a problem, but, even though I had a show method, I was told it didn't exist. On a whim, I scrolled to the bottom of the file and noticed that show existed as a private method, and removing it promptly solved my problem.

While playing with routes to figure out the problem, I also encountered #show rendering show.rhtml, (it's old code) -- the server appeared to be running the private method instead of the public version. This is probably a bug, but in Ruby or Rails?

Careful with that config.gem, Eugene
Posted by Kevin on April 10, 2009 18:02

With the advent of Github as the Ruby Gem hosting platform of choice, you have to be specific when you use config.gem in you config/environment.rb file.

Recently, I noticed that my Rails application generated from a You've Got Rails template was choking on the rubyist-aasm library. Given the following configuration in config/environment.rb:

  config.gem "rubyist-aasm"

Which would yield the following errors initially discovered when running Rake:

  no such file to load -- rubyist-aasm
  ...
  Missing these required gems:
    rubyist-aasm

The problem appears due to Github namespacing gems by prefixing the username to the Gem name. The solution is to specify the actual library name:

  config.gem "rubyist-aasm", :lib => "aasm", :source => "http://gems.github.com"
Are My Gems Compatible with Ruby 1.9?
Posted by Kevin on March 30, 2009 23:37

I was recently wondering out loud to Patrick over IM about there being an easy way to check if my installed Gems are supported by Ruby 1.9. A quick Google search didn't turn anything up so after a little prompting I wrote Am I Ruby 1.9?.

Am I Ruby 1.9? looks at the 5 most recent comments on Is it Ruby 1.9 for each gem you have installed and then guesses whether it works. Hopefully this will help spark some interest in people updating gems to support Ruby 1.9. I know there are a few I'm going to take a look at!

Is It Ruby 1.9 is a great project, but like all social constructs, it only works if people participate.

Proper Trimming on Save with TextMate
Posted by Kevin on February 19, 2009 16:27

I previously blogged about a method to make TextMate trim trailing spaces when it is saved. However, it had the unfortunate side effect of forcing you to save your file again after the trimming -- even if you hadn't made any changes. I've since implemented Sven Axelsson's comment on how to do it with a macro.

Prior to the previous blog post, my attempt at trimming and saving via a macro didn't work. Sven's suggestion solves that problem. Here it is, outlined a bit more verbosely:

  • Create a new bundle with a command having the following features:
    • Delete the default command text.
    • Save: Current file
    • Input: None
    • Output: Discard
  • Don't give the new bundle an Activation key.
  • Record your macro:
    • Bundles -> Macros -> Start Recording
    • Select Bundles -> Text -> Converting / Stripping -> Remove Trailing Spaces in Document.
    • Select Bundles ->
    • Bundles -> Macros -> Stop Recording
  • Save your new macro
    • Bundles -> Macros -> Save Last Recording...
    • Edit the name
    • Click in the Activation (Key Equivalent) text field and hit Command-S.

I find it strange that Sven's is the only comment out there in Google search land explaining how to do this. So, either it is intuitively obvious to everyone but me, or I just have a Monkish fascination with trimming those pesky trailing spaces.

Trimming Trailing Spaces With Text Mate
Posted by Kevin on February 01, 2009 21:32

NOTICE: This method has a major drawback that is corrected in a the new post: Proper Trimming on Save with TextMate

One thing Text Mate doesn't do by default, and lacks an easy preference setting for, is trim trailing spaces when saving. Luckily, there is an easy way to implement this feature.

  1. Select Bundles->Bundles Editor->Show Bundle Editor
  2. Find Text->Remove Trailing Spaces in Document
  3. Make it look as follows:

Text Mate Bundle Editor

Now, whenever you save your document the trailing spaces will be eliminated.

A slightly faster way is to replace the perl script with:

  sed -e "s/ {1,}$//"

[Update 1] I just noticed that every blue moon multiple copies of the file will get appended instead of replacing. Not sure exactly the cause, but I can host C-s down repeatedly and not force the problem to occur, so YMMV.

Caching Rails Pages with Passenger and a Sub-URI
Posted by Kevin on January 21, 2009 03:06

Ever since I started using blurt for my blog, I have wanted to add page caching. Patrick, the author, thinks it is premature optimization -- especially since no one reads our blogs anyway (or at least mine). My view is that performance really stinks on a 256 MB shared slice. By implementing page caching, pages that used to take between a few hundred ms and a few seconds, are now instantaneous. About as digg safe as a single, puny, server can be!

Getting it working wasn't that easy, though. I followed the usual suspects for page caching, but kept running into weird issues with the sweepers. We were originally frozen at Rails 2.1.1, and I think most of the obvious problems were fixed by upgrading to 2.2.2. Once things appeared working, I deployed to production only to be greeted with new issues. Seems I forgot to configure my developer Passenger instance to use a sub URI like I'm doing in production.

The first bit of Google-delivered help was Paul Gross's article on using Mephisto with Phusion Passenger with a custom cache directory. Of course, that's for a website without a sub-URI. Before I could address that issue, I needed to fix a Rails 2.2.2 problem. It pays to read the release notes, and luckily for me someone else had.

First, add the following to your appropriate environment. If you are doing things right, it should be in config/environment.rb and not config/environments/production.rb:

  config.action_controller.relative_url_root = "<sub-uri>"

Next, remove "config.action_view.cache_template_loading = true" from config/environments/production.rb.

Now you are ready to engage in mod_rewrite hacking! A useful trick is to actually log what mod_rewrite is doing. Add the following lines to your apache config (virtual host or other):

        RewriteLog /var/log/apache2/<domain>-rewrite.log
        RewriteLogLevel 3

After playing around for a bit, Paul's rewrite code turned into:

        RailsAllowModRewrite on
        RewriteEngine on
        RewriteRule ^/<sub-uri>/?$ /<sub-uri>/cache/index.html [QSA]
        RewriteRule ^/<sub-uri>/([^.]+?)/?$ /<sub-uri>/cache/$1.html [QSA]
        RewriteCond %{DOCUMENT_ROOT}/<sub-uri>/cache/%{REQUEST_FILENAME} -f
        RewriteRule ^/<sub-uri>/(.*)$ /<sub-uri>/cache/$1 [L]

Hopefully this helps prevent someone from futzing around in circles for a few hours.

iPhone Development Part 1: Getting Apple's Ducks to Line Up
Posted by Kevin on November 04, 2008 08:44

Mike Ash wrote an entertaining and somewhat informative article on the iPhone development process. Unfortunately, some of the good, getting started info was left out. Since I just started developing for the iPhone, I thought it might be useful to someone if I itemized what to do and where to read how to do it.

First off, find a fast Internet connection and download the iPhone SDK. If you have the the standard OS X SDK, it appears you have to install the iPhone version after it. I upgraded to the latest OS X SDK and it appeared to have clobbered my iPhone installation such that I no longer had the option to create iPhone applications, so keep the iPhone SDK package nearby.

  1. As Mike mentioned, head on over to the Apple developer site and apply to the program. Really, you aren't applying, you are purchasing the right to access the features that allow you to actually test and deploy iPhone applications. No one actually reviews your application -- they just take your money. I already had a developer account, so I'm not sure if my approval arrived quickly or not.
  2. OK, login to you account after you receive the approval email address.
  3. In order to deploy your application to your device for testing, you need to visit the Program Portal to register your device, create a development certificate, an App ID (I have no idea why people capitalize Id since it is an abbreviation of one word, maybe it just looks less awkward...), and create provisioning profile. Apple provides some nice How To articles on the tab bar of each section.
  4. The How To directions for creating a certificate are pretty straight forward. After it is submitted it takes a few minutes to get an email telling you it is ready. I followed the installation instructions and added it to my login keychain, but this seems like a bad place to store it.
  5. As with certificates, adding a device is well explained in the How To.
  6. Adding an App ID is a little trickier. The name cannot have spaces, so just squish the words together. The Bundle Identifier gives you the choice of com.companyname.* and com.companyname.appname, the former allows you to share keychain access across multiple applications. In general, you probably want to chose the latter format.
  7. The provisioning process creates a profile that ties a developer, device, and application together. The XCode Organizer (Window -> Organizer) uses one or more profiles to create one or more build targets. Again, well documented in the How To. You have to save the profile and then drag it into the Provisioning window of the Organizer.

After completing these tasks, you can finally start developing! Test your setup by going through a tutorial like the excellent iPhone SDK Tutorial: Build a Simple RSS reader for the iPhone by Jason Terhorst. There's a missing closing brace in there, but otherwise it is pretty cut-n-paste.

A couple of gotchas I experienced:

  • If the Organizer is failing to install your application, disconnect and reconnect your iPhone, possibly rebooting it as well. The disconnect is definitely required.
  • To use the simulator instead of installing on your device after clicking Build & Go, select the appropriate simulator from the Project -> Set Active SDK menu.

Feel free to ask any questions, and definitely help me correct any errors!

 
 
© 2013 Concepts Ahead :: Logo Design by Peyton Crump :: Powered by Blurt