#10294 closed defect (bug) (invalid)
CSRF through the img tag
Reported by: |
|
Owned by: |
|
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | |
Component: | Security | Keywords: | |
Focuses: | Cc: |
Description
The filtered HTML should be more ... well, filtered. Although Since WordPress 2.8 you can't do CSRF with a link like this: http://example.com/?logout=true&action=logout (where example.com holds a WP installation) because the logout requires the _wpnonce parameter to be specified into the GET request (2.7.1 has this issue), the installation is still vulnerable to this type of CSRF against other sites. While this kind of stuff is mostly annoying (as example <img src="http://wordpress.org/extend/plugins/bb-login.php?logout" alt="" /> within a blog's post), it can be used for more severe actions.
I didn't started with the "filtered HTML" state by accident. This kind of vulnerability can be triggered by blog users who actually have lower privileges, thus using the filtered HTML feature which turns out to be inefficient for this kind of issue.
Change History (10)
#3
@
16 years ago
- Milestone Unassigned deleted
- Resolution set to invalid
- Status changed from new to closed
marking as invalid then
#4
follow-up:
↓ 6
@
16 years ago
- Resolution invalid deleted
- Status changed from closed to reopened
The fact that WordPress is unaffected by this issue, it doesn't mean that WordPress is safe for others. This slip from properly parse the HTML can be used as attack vector against other sites, thus making WordPress kinda useless for creating an open publishing platform where anyone can sign up and provide content. Isn't this one of those Web 2.0 thingy, the user generated content? Well, that user generated content should better be safe for others.
Please do us all a favor: fire up a WordPress instance, create a new article as an unprivileged user who has filtered HTML on, then embed these couple of 'images'. In order to work you need to be authenticated on wordpress.org and core.trac.wordpress.org:
<img src="http://wordpress.org/extend/plugins/bb-login.php?logout" alt="" />
<img src="http://core.trac.wordpress.org/logout" alt="" />
Then please visit wordpress.org and core.trac.wordpress.org again. Do you notice something? This demonstration has minimal effects, but the potential is greater. Please remember that WordPress roles can be changed, thus someone with contributor privileges may post content without the approval of an admin/editor if the site is designed for that purpose.
#5
@
16 years ago
SaltwaterC: What is your proposed solution to a 3rdparty issue (Of not having some sort of "are you sure you wish to do this" action
Its impossible.
bb-login.php?logout
compared to image.php?image=1234
How is wordpress to know the latter is a image and not a malicious link?
#6
in reply to:
↑ 4
@
16 years ago
- Resolution set to invalid
- Status changed from reopened to closed
Replying to SaltwaterC:
Please do us all a favor: fire up a WordPress instance, create a new article as an unprivileged user who has filtered HTML on, then embed these couple of 'images'. In order to work you need to be authenticated on wordpress.org and core.trac.wordpress.org:
<img src="http://wordpress.org/extend/plugins/bb-login.php?logout" alt="" />
<img src="http://core.trac.wordpress.org/logout" alt="" />
this is a problem with the used trac as well the used bb version. This is not related to WordPress. You can do this with a static HTML file as well containing these links.
You can prevent such security risks if you configure your browser to not load linked files like images. I guess it is not the web you want to use, but those are the implications of automatically requested URLs in your browser. This is actually how it works (e.g. the html IMG element).
Again: This is not a WordPress Issue. Feel free to report this security related stuff for the other projects, like trac.
#7
@
16 years ago
I do have a solution. It may not be bullet proof, it depends on ext/curl, but it's quite fast and reliable. Here's a CLI snippet which can be easily converted to a proper procedure for image checking:
This piece of code uses the HEAD HTTP request to take a peek at the headers of a given URI, thus no need for downloading the whole file. This makes the whole checking process much faster.
The HTTP status code should be 200 for a valid image. Any other HTTP status code must be rejected. Don't get fooled by 304. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Also the mime type should be an image mime type. A spoofed script which sends an image type header wouldn't request an action within the browser since the browser expects binary image output.
@hakre: I would if I could configure everyone's browsers, or make them to use proper browsers. Actually the proper solution would be to: a) either patch to WordPress all the right solutions for the wrong usage of the Web (at least for the issues that I know of, and I do know a few); or b) code my own platform which sounds reasonable from all points of view except for the time part. Since I constantly discover flaws in various 3rd party plug-ins, and you can't deny the fact that WordPress was widely adopted because of the availability of such plug-ins, then maybe this second (b) solution sounds reasonable - period.
Correction: the 2.7.1 'issue' which I discovered (the http://example.com/?logout=true&action=logout kind of URL) is actually a plug-in issue (http://wordpress.org/extend/plugins/sidebar-login/), not a WordPress related issue.