SitePoint Sponsor |
|
User Tag List
Results 1 to 25 of 35
-
Nov 1, 2009, 17:04 #1
- Join Date
- Oct 2009
- Location
- Tokyo
- Posts
- 36
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
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
-
Nov 1, 2009, 17:19 #2
- Join Date
- Jul 2003
- Location
- Northeastern USA
- Posts
- 4,617
- Mentioned
- 56 Post(s)
- Tagged
- 1 Thread(s)
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.Visit The Blog | Follow On Twitter
301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
Can be hosted on and utilize your own domain
-
Nov 1, 2009, 17:24 #3
- Join Date
- May 2007
- Location
- Poole, UK
- Posts
- 5,077
- Mentioned
- 103 Post(s)
- Tagged
- 0 Thread(s)
I've never seen any sites where having actions in links has been a problem, SitePoint's site has actions in links all over.
Community Team Advisor
Forum Guidelines: Posting FAQ Signatures FAQ Self Promotion FAQ
Help the Mods: What's Fluff? Report Fluff/Spam to a Moderator
-
Nov 1, 2009, 17:27 #4
- Join Date
- Oct 2009
- Location
- Tokyo
- Posts
- 36
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
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
-
Nov 1, 2009, 17:29 #5
- Join Date
- Mar 2008
- Posts
- 1,149
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
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.
-
Nov 1, 2009, 17:30 #6
- Join Date
- Oct 2009
- Location
- Tokyo
- Posts
- 36
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
-
Nov 1, 2009, 17:34 #7
- Join Date
- Mar 2008
- Posts
- 1,149
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
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).
-
Nov 1, 2009, 17:37 #8
- Join Date
- May 2007
- Location
- Poole, UK
- Posts
- 5,077
- Mentioned
- 103 Post(s)
- Tagged
- 0 Thread(s)
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).
Community Team Advisor
Forum Guidelines: Posting FAQ Signatures FAQ Self Promotion FAQ
Help the Mods: What's Fluff? Report Fluff/Spam to a Moderator
-
Nov 1, 2009, 17:59 #9
- Join Date
- Oct 2006
- Location
- France, deep rural.
- Posts
- 6,869
- Mentioned
- 17 Post(s)
- Tagged
- 1 Thread(s)
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.
-
Nov 1, 2009, 18:40 #10
- Join Date
- Apr 2000
- Location
- Melbourne, Australia
- Posts
- 2,571
- Mentioned
- 2 Post(s)
- Tagged
- 0 Thread(s)
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:
- 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.
- Later, while still logged into your site, the user is lured into visiting a malicious web site set up by the attacker.
- 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.
- The user’s browser dutifully (and invisibly) requests the URL in an attempt to load it as an image or script.
- 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
CTO, sitepoint.com
I wrote: Simply JavaScript | BYO PHP/MySQL | Tech Times | Editize
Baby’s got back—a hard back, that is: The Ultimate CSS Reference
-
Nov 1, 2009, 18:53 #11
- Join Date
- Oct 2009
- Location
- Tokyo
- Posts
- 36
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Thanks very much for the detailed info, Kevin. That was definitely useful to know!
doug
-
Nov 1, 2009, 20:18 #12
- Join Date
- Oct 2009
- Location
- Tokyo
- Posts
- 36
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
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
-
Nov 1, 2009, 22:10 #13
- Join Date
- Jan 2002
- Location
- Australia
- Posts
- 2,634
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Replacing your action links with form POSTs prevents simple CSRF attacks like this.
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.
-
Nov 2, 2009, 02:07 #14
- Join Date
- Sep 2005
- Location
- Sydney, NSW, Australia
- Posts
- 16,875
- Mentioned
- 25 Post(s)
- Tagged
- 1 Thread(s)
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.Stephen J Chapman
javascriptexample.net, Book Reviews, follow me on Twitter
HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
<input name="html5" type="text" required pattern="^$">
-
Nov 2, 2009, 03:31 #15
- Join Date
- Oct 2009
- Location
- Tokyo
- Posts
- 36
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
-
Nov 2, 2009, 03:54 #16
- Join Date
- Jan 2007
- Posts
- 344
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
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.
-
Nov 2, 2009, 03:59 #17
- Join Date
- Jan 2007
- Posts
- 344
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
-
Nov 2, 2009, 04:12 #18
- Join Date
- Oct 2009
- Location
- Tokyo
- Posts
- 36
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
-
Nov 2, 2009, 04:15 #19
- Join Date
- Jan 2007
- Posts
- 344
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
-
Nov 2, 2009, 04:36 #20
- Join Date
- Oct 2009
- Location
- Tokyo
- Posts
- 36
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
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
-
Nov 2, 2009, 06:36 #21
- Join Date
- Oct 2009
- Posts
- 1,852
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
-
Nov 2, 2009, 08:28 #22
- Join Date
- Feb 2005
- Location
- was rainy Oregon now sunny Florida
- Posts
- 1,104
- Mentioned
- 2 Post(s)
- Tagged
- 0 Thread(s)
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.What I lack in acuracy I make up for in misteaks
-
Nov 2, 2009, 13:30 #23
- Join Date
- May 2007
- Location
- Poole, UK
- Posts
- 5,077
- Mentioned
- 103 Post(s)
- Tagged
- 0 Thread(s)
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.
- Many mobile phones now are capable of accessing the Internet but not all of them can run javascript.
- 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.
Community Team Advisor
Forum Guidelines: Posting FAQ Signatures FAQ Self Promotion FAQ
Help the Mods: What's Fluff? Report Fluff/Spam to a Moderator
-
Nov 2, 2009, 14:10 #24
- Join Date
- Sep 2005
- Location
- Sydney, NSW, Australia
- Posts
- 16,875
- Mentioned
- 25 Post(s)
- Tagged
- 1 Thread(s)
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.
Stephen J Chapman
javascriptexample.net, Book Reviews, follow me on Twitter
HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
<input name="html5" type="text" required pattern="^$">
-
Nov 2, 2009, 16:05 #25
- Join Date
- Jun 2005
- Posts
- 436
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
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
Bookmarks