Closed Bug 604265 Opened 15 years ago Closed 15 years ago

Cross origin bypass silent POST request using <form> inside <iframe>

Categories

(Firefox :: Security, defect)

x86
All
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: cagret, Unassigned)

References

(Blocks 1 open bug)

Details

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 (.NET CLR 3.5.30729) I am able to make a silent (not visible to the user) POST request to a different origin using a <form> hidden inside an <iframe>. Example below: <iframe id="ifr" src="data:text/html,<form method='post' id='fm' action='http://www.google.com/'></form><script>setTimeout(function(){document.getElementById('fm').submit();},1000); </script>"></iframe> I've tested XMLHttpRequest object, it does not allow POST method to a different origin. Using this hack I am able to make such requests and the user is not aware of it, the iframe can be hidden. Reproducible: Always
Summary: Cross origin silent POST request using <form> inside <iframe> → Cross origin bypass silent POST request using <form> inside <iframe>
Unfortunately this is totally expected, known and definitely not a bug. I also guess many web applications rely on this "feature" (I wrote some myself). Applications which don't want to process spurious cross-site POST requests must deploy robust anti-CSRF defenses, such as submission tokens and, where implemented, checking the Origin header. On a side note, and important difference with XMLHttpRequest is that this form-based technique is blind when used cross-site, i.e. it does not allow you to read back the response (which may or may not be important in an attack scenario).
Group: core-security
Status: UNCONFIRMED → RESOLVED
Closed: 15 years ago
Resolution: --- → INVALID
Take a look at this scenario: I am able to make POST requests to local addresses (http://127.0.0.1/). Imagine a PHP developer running a local server and mysql (there are millions of them), he has installed phpmyadmin to administer his database to http://127.0.0.1/phpmyadmin/ (a very common practice), I am able able execute queries on his local database! Imagine www.evilwebsite.com running "DROP DATABASE important_stuff" on his computer. Isn't that a security issue?
(In reply to comment #2) > I am able able execute > queries on his local database! Imagine www.evilwebsite.com running "DROP > DATABASE important_stuff" on his computer. Isn't that a security issue? Yes it is. It is called CSRF and it's well known. It's not due to a browser bug, though. You might argue it's due to an inherent flaw in how HTTP works today, but since server-side defenses are already available today (in the form of anti-CSRF tokens), this is definitely a bug in the web application (phpmyadmin, in this case). BTW, if you're concerned about the (many) buggy web applications out there, the specific case of CSRF against a local address is handled by NoScript's ABE module ( http://noscript.net/abe ) by default, even if you've got scripts globally allowed, and in its default configuration NoScript prevents also cross-site post requests of any kind from untrusted sites to trusted sites.
Many people are not aware of it. I am a developer for many years with much experience, but just now I am aware of this risk. Why can't we fix that in the browser? It shouldn't be that hard. We can identify local IP addresses (127.* 192.* 10.* 172.*), and block POST requests that come from a different (internet) origin. Even if you think that it will break some applications, we could at least block the "silent" requests, block the form submits that are not initiated by the user click and the target is a local machine, at least that we could do. Cheers, Cezary.
(In reply to comment #4) > Many people are not aware of it. I am a developer for many years with much > experience, but just now I am aware of this risk. > Why can't we fix that in the browser? This is scary and sad, but unfortunately not uncommon. Unfortunately, though, it cannot be "fixed" in the browser for the general case (at least not without server-side awareness and cooperation) because it would break the existing web. > It shouldn't be that hard. We can identify local IP addresses (127.* > 192.* 10.* 172.*), and block POST requests that come from a different > (internet) origin. As I said the specific LAN case is covered by default in NoScript/ABE, and it's (slowly) being worked on in bug 354493 On a side note, your report is quite similar to a very old one, bug 246476. I'm not marking this one as a dupe because of the silent/iframe variant.
Blocks: csrf
Giorgio thanks for the explanation. But could we resolve this issue by having an option in the browser, (tools > options > security > protect me from csrf post requests)? I am talking only about csrf using post requests. Good written applications allow modification of data only by post requests, so crsf using get is not so dangerous as crsf using post. All sites I use would not break when using this option, so why not give us more security for those who care? And even more. You talking about breaking the web, but I have solution: why not display a security message when a site tries to make a POST request to a different origin, with 2 options: Allow or Deny. The user decides if he trusts this site to make this request.
OS: Windows XP → All
Just an information : Chromium handle this case.
You need to log in before you can comment on or make changes to this bug.