Posted by Tom Moertel
Thu, 16 Jun 2005 16:00:00 GMT
I am delighted to report that the button_to
helper
has been added to the Ruby on Rails
web-development framework. David
applied the patch earlier
today, and so button_to will be in the much-anticipated Rails 1.0
release.
David’s change-log entry summarizes the patch well:
Added button_to as a form-based solution to deal with harmful
actions that should be hidden behind POSTs. This makes it just as
easy as link_to to create a safe trigger for actions like destroy,
although it’s limited by being a block element, the fixed look,
and a no-no inside other forms.
David does a good job of highlighting the helper’s limitations. I’ll
take this opportunity to elaborate on each.
It is a block element
The button_to helper creates a small form, which in HTML is considered
block content, just
like the p, div, and blockquote elements are. Basically, block
content cannot be mixed into runs of text. But links can: links are
inline content. Thus
button_to cannot be used as a drop-in replacement for every
occurrence of link_to that might be unsafe; it works only for those
occurrences within block-accepting contexts.
Luckily for us, when designers use links to trigger unsafe actions,
they rarely slip such links into the middle of ordinary looking
text. Naughty uses of link_to almost always occur within contexts
that accept block content. In Rails-generated scaffolding code, for
instance, the unsafe uses of link_to occur within table cells, and
table cells have a flow content
model, which accepts
both inline and block content. So button_to works great for the
default cases in Rails.
It has a fixed look
As its name implies, button_to creates buttons. Buttons don’t look
like links and aren’t styled the same way that links are. For some
design scenarios, this might be a problem.
(My view is that links should not be used to trigger unsafe
actions. In the same way that action-triggering GET requests violate
the spirit of the HTTP standards, action-triggering hypertext links
violate the spirit of the HTML standards. For this reason, I view this
limitation as a feature.)
It is a no-no inside other forms
Forms cannot be nested, and so button_to cannot be used inside of
forms.
Fortunately, this limitation usually doesn’t matter because when we
are inside of a form, we can use its buttons instead of
button_to-created buttons to trigger actions. Still, there are some
circumstances where it does matter, such as the “Amazon.com wish list”
scenario. In this scenario, we should consider other
options.
The bottom line: Pick the low-hanging fruit
While button_to has its limitations, it does provide a simple solution
to the unsafe-GET problem for most real-world cases. I am glad that it
is now a part of Rails, and I offer a big thank-you to David for
accepting the patch.
Posted in web development, rails
Tags get, gwa, link_to, post, rails, safe, unsafe
no comments
no trackbacks

Posted by Tom Moertel
Sun, 08 May 2005 16:00:00 GMT
As I wrote earlier, it’s time for web developers to do away with the fundamentally broken practice of using hypertext links to trigger dangerous events such as deleting things. One of the first places we ought to clean house is in the burgeoning Rails web-application framework, where this practice is pervasive.
The primary culprit in Rails is the all-too-easy link_to method, which is (presently) the orthodox means of creating links to any action, even unsafe ones. For example:
link_to "Destroy", :controller => 'accounts',
:action => 'destroy', :id => 6
The above code generates the following HTML hypertext link, which when followed will merrily delete account number 6:
<a href="/accounts/destroy/6">Destroy</a>
Because this practice is dangerous and contrary to the decade-old convention that links be safe, the link_to method thoughtfully lets us request that a Javascript confirmation dialog be tacked onto the link for added protection:
link_to "Destroy", ..., :confirm => "Are you sure?"
The resulting “safe” HTML:
<a href="/accounts/destroy/6"
onclick="return confirm('Are you sure?');">Destroy</a>
Unfortunately, the Javascript protection doesn’t work. First, not all web browsers care about it. Lots of people surf with Javascript turned off. Second, a whole slew of things besides web browsers live on the Internet, and almost all of them are oblivious to Javascript. Web crawlers fall into this category. They will be more than happy to follow any link you feed to them. “Hey, Googlebot just deleted every account in our database!” Oops.
Thus another layer of protection is commonly used: authorization. The theory is that dangerous links can be safely corralled in the private parts of a web application, where the public and web crawlers cannot go. Only authorized users can get into those parts, and those users will be smart enough not to click on the truly dangerous links unless they really mean it.
The problem is, any number of intermediary agents can be operating on behalf of an authorized user, and these agents are free to do anything the user is allowed to do, such as follow dangerous links. Google’s Web Accelerator is one such agent. It tries to make your surfing faster by (among other things) pre-fetching the resources that are linked to on the pages you visit. And what happens if you, an authorized user, visit a page containing dangerous links? That’s right, Web Accelerator will fetch the “resources” those links point to – and delete a bunch of your stuff.
I hope by this point that I have argued convincingly that using links for unsafe actions is a bad idea. Even if you feel justified in ignoring the applicable parts of the HTTP RFCs, it’s a bad idea. Even if you tack on Javascript confirmations and hide your links in authorization-protected zones of your site, it’s a bad idea. It is, all around, a bad idea. Don’t do it.
So what alternatives are there? Read on for one possibility, button_to.
Read more...
Posted in ruby, web development, rails
Tags get, gwa, link_to, post, rails, safe, unsafe
9 comments
no trackbacks

Posted by Tom Moertel
Sat, 07 May 2005 01:55:00 GMT
There has been a lot of heat lately about Google’s Web Accelerator (GWA)
exposing serious problems in some popular web
applications. The problem, in short, is that these applications use
GET-based links that when followed perform dangerous actions such as
deleting records in a database. According to web standards going back
a decade, that is a no-no: Links should be safe to follow. Thus GWA,
expecting links to be safe, tries to help you out by pre-fetching
various resources that are linked to by the pages you
visit. Unfortunately, if the page you happen to be visiting contains
lots of dangerous links, GWA will innocently try to pre-fetch the
“resources” that the links point to, and in doing so will accidentally
delete a bunch of stuff. Oops.
That’s the backdrop for our real story, which is the response from the
community of web developers. What I find fascinating, and somewhat
disheartening, is the number of people who say the problem is Google’s
to fix. Yes, there are a lot of broken web apps out there, and Google
could have been smarter about working around the minefields those apps
represent. But that’s a side problem. The real problem is that there
are a lot of broken web apps out there, and they do represent
minefields. Worse, a lot of web developers think it is acceptable to
brush aside fundamental conventions of the web going back a decade
when they find it sexier to use GET instead of POST.
What these developers overlook is that the web is not a bunch of
colorful pages with buttons, clickable links, and pretty
pictures. Rather the web is a distributed collection of hypertext
documents, each of which has a meaning that is given by standards that
most people have agreed to follow. While the collection may look like
a bunch of colorful pages in one particular visual presentation, it
really, truly is not.
Nevertheless, many web applications are designed with the prevailing
mindset that the meaning of the web is nothing more than how it looks
and behaves in a web browser. Even if those web applications are not
intended for use outside of a few approved browsers – the escape
hatch that is often used to justify departures from the
standards – this mindset is wrong.
The reason it is wrong is because, like it or not, web applications
are implemented in terms of protocols and languages that mean
something. The bits and pieces of a web application each mean
something, even if what they mean is not in harmony with the
designer’s overall vision. What a web designer may see as a bold, red
link that says “delete” and is protected by a Javascript confirmation
dialog, is actually a hypertext reference – a pointer
to another resource that the standards say should not be dangerous to
follow. Thus there is a fundamental mismatch between what the designer
is trying to say – “follow this link only if you
really, no-kidding want to delete something” – and
what his markup actually means: “this link is safe to follow.”
The bottom line is that hypertext links are supposed to be
safe. Dangerous links can’t be made “safe” by layering tricks on
them. Wrapping them with Javascript confirmation dialogs doesn’t make
them safe. This trick fails fundamentally because the meaning of a
link doesn’t change when there is Javascript associated with it. It
fails practically because not all consumers of hypertext evaluate
Javascript, nor do any standards suggest that they should. (This is
also why client-side validation cannot be trusted on the server side.)
Hiding dangerous links in authorization-controlled portions of a web
application does not make them safe, either. This trick might shield
the links from external spiders, but the standards allow for any
number of intermediary agents (such as Google’s Web Accelerator) to
work on behalf of an authorized user. Anything the user is authorized
to do, so are the user’s agents. If the user can click the “delete”
link, so can the agents.
Let’s answer the wake-up call.
GWA is only the first of a new breed of
smarter user agents that promise to make the web a better place for
all of us. If you’re a web developer, take the slew of problems that
GWA uncovered as a wake-up call. Even if Google works around your
problems, other user agents may not. As developers, it’s time to admit
our mistakes and fix the stupid things that our web applications do.
First, let’s drive a stake in the notion that dangerous links are OK
if we’re “careful.” They’re not. Dangerous links are
lazy. “Confirming” them with Javascript or “hiding” them behind
authorization doesn’t work.
Second, let’s clean house. Let’s find those places where we have laced
our web applications with dangerous links and remove them. Break out
the forms! Long live the POST!
Third, let’s take a look at how we got into this mess and try to learn
from our mistakes. Do we value sexiness more than substance? We like
to think that form follows function and that good design and good
implementation go hand in hand, but the reality of this debacle
suggests otherwise. I think the truth is that on the web, sexiness and
hype are what gets attention, and we seek attention more than we like
to admit.
Maybe the best thing for us is a good dose of humility. And, come to
think of it, that’s just what Google’s Web Accelerator offered us.
Posted in web development
Tags get, gwa, post, rails, safe, unsafe
no comments
no trackbacks

Posted by Tom Moertel
Tue, 18 Jan 2005 17:00:00 GMT
Google recently proposed a scheme to deprive comment and referrer spammers of Google juice. Right now, spammers employ evil programs that crawl the innumerable blogs on the web and post bogus comments and push fake referrer information. The comments and referrer information link back to the spammers’ sites. The spammers hope that when Google crawls the blogs and sees these links, their sites will be unduly elevated in search-results rankings because, supposedly, somebody has taken the time to link to them.
Google’s proposed scheme ends this abuse by having all such links branded with a “do not follow” indicator that tells search engines not to count the links toward site rankings, thereby depriving spammers of any benefit from their wicked deeds. For this proposal to be effective, the creators of blog software must modify their code so that untrusted links are properly branded. Fortunately, the modifications are easy to make. (I have already modified the copy of SnipSnap that powers the Community Projects site.) Most vendors of major blog software have signed on to Google’s proposal, and so it seems likely to have widespread effect shortly.
One interesting side effect of this anti-spam proposal is that it may also clear up the blog-generated noise that often crowds out more relevant search results. Remember, the reason that spammers attack blogs in the first place is because it is burdensome to weed out their fake posts from real posts. It most cases, the weeding must be done by hand. Google’s proposal eliminates this manual labor by assuming that all comment links and referrer information are worthless. The reality is that these links – at least the non-spam subset – do provide value, but not much. Thus Google’s proposal is a better approximation of reality than is the present situation, which is to assume that blog-generated links carry the same weight as first-class links that were carefully created by human editors.
I count this proposal as a double win for Google. First, they remove all incentive for spammers to target blogs. Second, they eliminate the unduly high search rankings that blogs receive because of their artificially high link density.
And it’s not just a win for Google. It’s a win for everybody who uses the web. I love it!
Posted in web development
no comments
no trackbacks

Posted by Tom Moertel
Wed, 11 Aug 2004 16:00:00 GMT
I have Sprint PCS Vision, which means that my cell phone provides a small web browser that I can use to surf the web while on the go. Sprint, in keeping with the fine tradition of phone-company weaselry, has provided its Vision customers with a home page that links to a number of crippled services in order to promote their “premium,” for-pay versions of the services.
For example, Sprint has partnered with The Weather Channel (TWC) for its Vision weather. If you want anything other than the most fundamental weather information, say a radar snapshot of your home’s geographical region, you must fork over $3.99 per month – that’s almost fifty bucks per year! – for the privilege.
Yeah, I’ll be doing that.
Am I supposed to be impressed by the ability to retrieve “detailed” weather information on my cell phone? O Corporate Masters, thank you for solving the Mobile Weather Problem! I hand you my tribute of $3.99 this month with delight, for the value of your technical prowess is beyond priceless. [Opens wallet.]
No, I think that the correct solution to the Mobile Weather Problem is for me to write a small Perl script, which, having just done it, I can say with confidence is a simple task. How hard is it to fetch the forecast and radar image from the National Weather Service and drop the results into an XHTML Basic page? Let’s see, it takes fewer than 150 lines of code, including the code to handle caching and downed NWS servers, focus the radar image on my home and scale it down to cell phone–screen size, and perform text-messaging style word abbreviation.
If I’m going to spend fifty bucks on weather-related purchases this year, it will not be on “premium” mobile-phone services. I would much rather use the money to buy a mighty fine umbrella.
P.S. If you’re curious, here’s my mobile-weather Perl script. It has a few specializations for my geographical region, but it should be easy to adapt to your needs.
Posted in perl, web development
Tags cgi, perl, weather, web
no comments
no trackbacks
