Go Back   SitePoint Forums > Forum Index > Program Your Site > PHP
Newsletter FAQ Members List Calendar Mark Forums Read

New to SitePoint Forums? Register here for free!

SitePoint Sponsor
 
Reply
 
Thread Tools Display Modes
Old Nov 1, 2009, 16:04   #1
douglerner
SitePoint Member
 
Join Date: Oct 2009
Location: Tokyo
Posts: 22
Is it true that it is unsafe to have links perform actions?!

In the Sitepoint book on PHP and MySQL I'm reading now, there is a warning about something I never thought of before.

The author says never to use links to perform actions - just use them for their intended purpose, which is to go to related content.

For example, he says you should never have "delete this" links on a page. Instead you should use form submissions for such actions.

The reason, the author says, is because some modern browsers will automatically follow hyperlinks present on a page in the background so the target pages will be ready for immediate display if clicked. Thus you may end up having some of your coded actions occurring even if the user never actually clicks on them!

I never thought of this before, and I'm sure I have lots of code where, instead of a form submission, I decided for convenience to use a URL with query parameters instead, like ..../delete?id=2323. Or links to toggles certain settings.

I wonder how prevalent this problem really is.

Since I read this we've been debating this at my company where all the developers have had links like this for years. Our software doesn't use PHP, but the same principle would hold if true.

The other developers are incredulous about the claim basically saying, "we would have had bug reports for years now if that was really true."

Is it true? Does anybody know of a browser that really does that? And wouldn't such a browser generally overwhelm servers with all the excess get requests that are never used?

I feel like I would have noticed such a problem before while testing because I have links that do things like "toggle a setting," etc.

doug
douglerner is offline   Reply With Quote
Old Nov 1, 2009, 16:19   #2
Force Flow
Computer Slayer
 
Force Flow's Avatar
 
Join Date: Jul 2003
Location: Northeastern USA
Posts: 1,287
Search engine spiders follow links, so if you have a "delete this" link that actually deletes content, you will find that content will get deleted randomly.

The way around this is to either use an onlick javascript/AJAX event or use an actual input button or button element.

I had a webapp I built a while back with an image link which was an enable/disable toggle for certain items. Unless it was behind a password prompt, search engine spiders would randomly enable and disable those items through that link.
Force Flow is offline   Reply With Quote
Old Nov 1, 2009, 16:24   #3
SpacePhoenix
SitePoint Guru
 
SpacePhoenix's Avatar
 
Join Date: May 2007
Location: Poole, UK
Posts: 821
I've never seen any sites where having actions in links has been a problem, SitePoint's site has actions in links all over.
SpacePhoenix is offline   Reply With Quote
Old Nov 1, 2009, 16:27   #4
douglerner
SitePoint Member
 
Join Date: Oct 2009
Location: Tokyo
Posts: 22
Quote:
Originally Posted by Force Flow View Post
Search engine spiders follow links, so if you have a "delete this" link that actually deletes content, you will find that content will get deleted randomly.

The way around this is to either use an onlick javascript/AJAX event or use an actual input button or button element.

I had a webapp I built a while back with an image link which was an enable/disable toggle for certain items. Unless it was behind a password prompt, search engine spiders would randomly enable and disable those items through that link.
Presumably links that can delete things, etc., are behind some user authentication and require privileges. So I wouldn't worry about guests and robots.

But even if I go into sites I've developed with the highest superuser privilege I have never noticed actions suddenly being taken without me clicking on them.

doug
douglerner is offline   Reply With Quote
Old Nov 1, 2009, 16:29   #5
sk89q
Call me "esskay"!
 
sk89q's Avatar
 
Join Date: Mar 2008
Posts: 969
I haven't either. Many of the popular forum packages have links that perform actions too, vBulletin (which SitePoint uses) included, and no one has complained, and there are millions of installations.
sk89q is offline   Reply With Quote
Old Nov 1, 2009, 16:30   #6
douglerner
SitePoint Member
 
Join Date: Oct 2009
Location: Tokyo
Posts: 22
Quote:
Originally Posted by SpacePhoenix View Post
I've never seen any sites where having actions in links has been a problem, SitePoint's site has actions in links all over.
That's a good point. So is the reference (the book is "Build your own database driven web site using PHP & MySQL" by Kevin Yank, 4th edition, page 146, last paragraph) just incorrect about this particular item?

Thanks,

doug
douglerner is offline   Reply With Quote
Old Nov 1, 2009, 16:34   #7
sk89q
Call me "esskay"!
 
sk89q's Avatar
 
Join Date: Mar 2008
Posts: 969
It's a concern if the page is public.

For a while, Firefox, and perhaps other browsers, was toying with the idea of prefetching links. Firefox eventually settled on only prefetching explicit requests for prefetching (and some edge cases).
sk89q is offline   Reply With Quote
Old Nov 1, 2009, 16:37   #8
SpacePhoenix
SitePoint Guru
 
SpacePhoenix's Avatar
 
Join Date: May 2007
Location: Poole, UK
Posts: 821
Quote:
Originally Posted by douglerner View Post
That's a good point. So is the reference (the book is "Build your own database driven web site using PHP & MySQL" by Kevin Yank, 4th edition, page 146, last paragraph) just incorrect about this particular item?

Thanks,

doug
It might be referring to installs of browsers such as FireFox which have addons installed which "accelerate" the browsing by following all links. Chances are that the average user won't have them installed and I think i've seen some sites in the past have rules which ban the use of web accelerators with them (probably down to the unnecessary server load caused).
SpacePhoenix is offline   Reply With Quote
Old Nov 1, 2009, 16:59   #9
Cups
So Prized A Nitwit
 
Cups's Avatar
 
Join Date: Oct 2006
Posts: 4,102
By creating links that use GET to change the state of something on your server you are breaking a HTTP principle. (HTTP is something I, like many, probably know too little about).

GET should do just that retrieve readonly data.

If you want to change the state of something then you should POST it back.

GET requests appear in your log files, and in the address of users' browsers.

I'm not trying to start a flame war, I am just pointing out that it is a really basic principle, thats all.

The googling of /index.php?action=delete&id=23 style links is one side effect of breaking the principle, but you just like everyone else, are free to break the principle whenever you feel like it.
Cups is offline   Reply With Quote
Old Nov 1, 2009, 17:40   #10
Kevin Yank
SitePoint resident know-it-all
SitePoint Award Recipient
 
Kevin Yank's Avatar
 
Join Date: Apr 2000
Location: Melbourne, Australia
Posts: 2,876
Hi all,

I am the author of the book in question.

It is true that few if any browsers will prefetch hyperlinks out-of-the-box, but some “web accelerator” software will do this. A few years back, Google’s initial release of Google Web Accelerator wreaked havoc on many sites that used action links. I will admit that situations like this are relatively rare, however; browser makers have learned to assume that web developers will use action links, even though they shouldn’t.

In practice, the biggest reason to avoid action links is because they are vulnerable to Cross-Site Request Forgeries (CSRFs). A CSRF is a malicious attack that works on the same principle as the link-prefetching problem described in the book.

If a password-protected area of your site contains a "Delete" hyperlink, this will usually be a security hole. Here’s how a CSRF attack works:
  1. A user visits your site and logs in. Perhaps a cookie is set to enable that user to remain logged in for an extended period.
  2. Later, while still logged into your site, the user is lured into visiting a malicious web site set up by the attacker.
  3. The malicious web site contains an <img> or <script> tag, the src attribute of which points to the URL of one of your “Delete” links.
  4. The user’s browser dutifully (and invisibly) requests the URL in an attempt to load it as an image or script.
  5. Your server, seeing a request for the “Delete” URL from a logged-in user, deletes the content without question.

Replacing your action links with form POSTs prevents simple CSRF attacks like this. More sophisticated CSRF attacks (commonly called “clickjacking” attacks) that trick the user into submitting a form are possible, and require more extensive measures to guard against. Such attacks are relatively difficult to develop, however, so anti-clickjacking measures are only really needed on highly sensitive or attack-prone sites.
Kevin Yank is offline   Reply With Quote
Old Nov 1, 2009, 17:53   #11
douglerner
SitePoint Member
 
Join Date: Oct 2009
Location: Tokyo
Posts: 22
Thanks very much for the detailed info, Kevin. That was definitely useful to know!

doug
douglerner is offline   Reply With Quote
Old Nov 1, 2009, 19:18   #12
douglerner
SitePoint Member
 
Join Date: Oct 2009
Location: Tokyo
Posts: 22
By the by, I am greatly enjoying Kevin's book. I am actually a professional programmer and have for years developed in server-side JavaScript using a proprietary object-oriented database (so I never had to deal directly with SQL).

Even though I have wide experience (developed online educational systems, social networking systems, done professional training seminars around the world, etc.) I am a newbie to PHP and MySQL.

While getting up to speed in the language (which fortunately is conceptually a lot like server-side JavaScript) Kevin's book is teaching me a lot of best practices I never really paid rigorous attention to before.

For example, he starts right out separating controller from view, using PHP templates. This is very nice. I admit I've been sloppy over the years, just mixing everything together. Even now it's tempting to just put everything in one file rather than separating it out when I'm in a hurry. But our own customers have been requesting we separate things out for years so their designers can easily work separately from my "innards development."

His book is definitely worth a complete read-through, even for people who are experienced in scripting.

doug
douglerner is offline   Reply With Quote
Old Nov 1, 2009, 21:10   #13
cranial-bore
SitePoint Wizard
 
cranial-bore's Avatar
 
Join Date: Jan 2002
Location: Australia
Posts: 2,092
Quote:
Replacing your action links with form POSTs prevents simple CSRF attacks like this.
Yes, a certain number of CSRF attacks will be thwarted if the victim website is strict about only deleting in response to a POST request.
Unfortunately there is a simpler option for attackers than setting up a click-jack attack (the invisible overlay type anyway).
That is to create an invisible form on their own page with the action attribute set to your delete action, and the appropriate form fields in place. That form can be submitted with Javascript, or even via Ajax so that the victim user never leaves the malicious site to have their suspicions aroused.
cranial-bore is offline   Reply With Quote
Old Nov 2, 2009, 01:07   #14
felgall
SitePoint Mentor
SitePoint Award Recipient
 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, NSW, Australia
Posts: 9,611
One thing to remember is that any GET call to the server is not supposed to perform updates. The browser is allowed to cache the result from one call and serve that same result if the same GET call is repeated. All updates are supposed to use POST. That iis why GET and POST exist since that is the only difference between them that matters.

Any spambot set to follow ALL links on a page would automatically trigger any actions attached to links and that would be the page author's own fault for using the wrong protocol.
felgall is online now   Reply With Quote
Old Nov 2, 2009, 02:31   #15
douglerner
SitePoint Member
 
Join Date: Oct 2009
Location: Tokyo
Posts: 22
Quote:
Originally Posted by felgall View Post
One thing to remember is that any GET call to the server is not supposed to perform updates. The browser is allowed to cache the result from one call and serve that same result if the same GET call is repeated. All updates are supposed to use POST. That iis why GET and POST exist since that is the only difference between them that matters.

Any spambot set to follow ALL links on a page would automatically trigger any actions attached to links and that would be the page author's own fault for using the wrong protocol.
Of course the spambot would have to also need proper access privileges to such a page. In that case, isn't it more of an issue of the author not coding in proper authentication and access privileges rather than merely having links?

doug
douglerner is offline   Reply With Quote
Old Nov 2, 2009, 02:54   #16
plumsauce
SitePoint Addict
 
Join Date: Jan 2007
Posts: 345
Quote:
Originally Posted by douglerner View Post
Is it true? Does anybody know of a browser that really does that? And wouldn't such a browser generally overwhelm servers with all the excess get requests that are never used?
FIREFOX does it/can do it. Depending on version.

The word that the authors of the RFC used for separating the effects of GET/POST was IDEMPOTENT. It means invariant.

The use of hyperlinks can be quite convenient. You just need to know *exactly* how the system will behave in the event of multiple invocations of the link.

For example, if it is delete a record with ID=xxxx. It can be argued that the resulting returned page will be IDEMPOTENT because once the record with ID=xxxx is gone, it is gone, and all subsequent retrievals will not return *that* record.

Adding is an entirely different story.

But, using it to unhide a content div, enable a form, are some useful things it can do that add to the usability of the page.

One method of ensuring that what you want is achieved is to include an onclick event handler in the link that returns false if you don't want it fired yet. This requires javascript, so it is best used in thngs likie control panels after the user is logged in. Check for javascript on the way through the login, and refuse a login until it is available. While javascript/ajax should not be required in publicly available pages, javascript + session cookies are fair game in private areas.
plumsauce is offline   Reply With Quote
Old Nov 2, 2009, 02:59   #17
plumsauce
SitePoint Addict
 
Join Date: Jan 2007
Posts: 345
Quote:
Originally Posted by douglerner View Post
By the by, I am greatly enjoying Kevin's book. I am actually a professional programmer and have for years developed in server-side JavaScript using a proprietary object-oriented database (so I never had to deal directly with SQL).

You might like the ASP/JSCRIPT or ASP.NET/JSCRIPT combination then. It is very fluid moving between client side and server side code.
plumsauce is offline   Reply With Quote
Old Nov 2, 2009, 03:12   #18
douglerner
SitePoint Member
 
Join Date: Oct 2009
Location: Tokyo
Posts: 22
Quote:
Originally Posted by plumsauce View Post
You might like the ASP/JSCRIPT or ASP.NET/JSCRIPT combination then. It is very fluid moving between client side and server side code.
Isn't that Windows-specific? Or am I thinking of something else?

doug
douglerner is offline   Reply With Quote
Old Nov 2, 2009, 03:15   #19
plumsauce
SitePoint Addict
 
Join Date: Jan 2007
Posts: 345
Quote:
Originally Posted by douglerner View Post
Isn't that Windows-specific? Or am I thinking of something else?

doug
Yes it is, on the server side. It is used in place of, or beside vbscript or C#.

Unless someone has written a javascipt handler for apache.
plumsauce is offline   Reply With Quote
Old Nov 2, 2009, 03:36   #20
douglerner
SitePoint Member
 
Join Date: Oct 2009
Location: Tokyo
Posts: 22
Quote:
Originally Posted by plumsauce View Post
Yes it is, on the server side. It is used in place of, or beside vbscript or C#.

Unless someone has written a javascipt handler for apache.
Ah, I see. I'm not a Mac vs Windows religious fanatic but I don't happen to use Windows, except for necessary testing of my stuff in IE for customers.

Basically I use OS X for my main work, and also use Linux or FreeBSD for deployed sites.

I also like cross-platform compatibility.

doug
douglerner is offline   Reply With Quote
Old Nov 2, 2009, 05:36   #21
Shrapnel_N5
SitePoint Evangelist
 
Shrapnel_N5's Avatar
 
Join Date: Oct 2009
Posts: 453
Quote:
Originally Posted by sk89q View Post
I haven't either. Many of the popular forum packages have links that perform actions too, vBulletin (which SitePoint uses) included, and no one has complained, and there are millions of installations.
May be you didn't notice it was a javascript on this links which sends data with POST method.
Shrapnel_N5 is online now   Reply With Quote
Old Nov 2, 2009, 07:28   #22
lorenw
SitePoint Guru
 
lorenw's Avatar
 
Join Date: Feb 2005
Location: was rainy Oregon now sunny Florida
Posts: 757
I can see where this could cause major problems. Say you are logged into your own control panel and it had a list of users with a link to delete each user. If you had a browser that pre fetched all links, poof, all users are deleted.

I may create links to edit users which takes you to a page of forms which is safe but never thought about the pre fetch links until now.

Could be pretty scary though because it would be you that deleted everything.
lorenw is offline   Reply With Quote
Old Nov 2, 2009, 12:30   #23
SpacePhoenix
SitePoint Guru
 
SpacePhoenix's Avatar
 
Join Date: May 2007
Location: Poole, UK
Posts: 821
Quote:
Originally Posted by plumsauce View Post
FIREFOX does it/can do it. Depending on version.

The word that the authors of the RFC used for separating the effects of GET/POST was IDEMPOTENT. It means invariant.

The use of hyperlinks can be quite convenient. You just need to know *exactly* how the system will behave in the event of multiple invocations of the link.

For example, if it is delete a record with ID=xxxx. It can be argued that the resulting returned page will be IDEMPOTENT because once the record with ID=xxxx is gone, it is gone, and all subsequent retrievals will not return *that* record.

Adding is an entirely different story.

But, using it to unhide a content div, enable a form, are some useful things it can do that add to the usability of the page.

One method of ensuring that what you want is achieved is to include an onclick event handler in the link that returns false if you don't want it fired yet. This requires javascript, so it is best used in thngs likie control panels after the user is logged in. Check for javascript on the way through the login, and refuse a login until it is available. While javascript/ajax should not be required in publicly available pages, javascript + session cookies are fair game in private areas.
What do you mean by "quite convenient"? Do you mean for the formatting of buttons?

A site should never rely on the user having javascript installed or active/unlocked.

  1. Many mobile phones now are capable of accessing the Internet but not all of them can run javascript.
  2. Javascript is client-side and client-side data should never be trusted, it should always be check and validated by server-side code. A person could write a GreaseMonkey script which could use the javascript to mess with a site's database.
SpacePhoenix is offline   Reply With Quote
Old Nov 2, 2009, 13:10   #24
felgall
SitePoint Mentor
SitePoint Award Recipient
 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, NSW, Australia
Posts: 9,611
Quote:
Originally Posted by SpacePhoenix View Post
A person could write a GreaseMonkey script which could use the javascript to mess with a site's database.
Note that Greasemonkey is the name of the extension used to add such scripts to Firefox. There are several plugins that can do the same for Internet Explorer (my favourite is IE7Pro) and with Opera you don't need a plugin/extension as Opera supports user JavaScripts directly.
felgall is online now   Reply With Quote
Old Nov 2, 2009, 15:05   #25
e39m5
SitePoint Evangelist
 
Join Date: Jun 2005
Posts: 566
Has anyone thought of a way to prevent CSRFs for PHP developers? The only method coming to my mind is checking referrers, either through scripting or .htaccess (kind of a twist on the way image theft is prevented).

Out of interest, are .NET developers immune to these kinds of attacks? I often hear .NET referred to as a bulletproof form validation, but does that include CSRFs?

e39m5
e39m5 is offline   Reply With Quote
Reply

Bookmarks

Tags
http get

« Previous Thread | Next Thread »

Thread Tools
Display Modes

 
Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Sponsored Links
 
Forum Jump


All times are GMT -7. The time now is 00:51.


Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Copyright 1998-2009, SitePoint Pty Ltd. All Rights Reserved