This is a friendly reminder about old problem with JSONP.
We need JSONP to receive some data on domain1 from domain2 because of cross origin restrictions. We put <script src="domain2?callback=CALLBACK"></script> where CALLBACK is name of Javascript function which handles received data. Here comes the rule: JSONP Should Never Be Used For Personal Data.(unless you have a special token, different for every user).
Knowledge "Who am I" is a secret. When I visit new website it's not supposed to know who I am, my email, name or sometimes my private messages. With JSONP a common vector can be:
<script src=data_provider/me.json?callback=leak></script>
By inserting this script any website can automatically receive information about me from data_provider.
Some showcases:
Stripe(fixed): https://manage.stripe.com/ajax/api/customers?count=20&callback=leak
Shopify(fixed): https://SITE.myshopify.com/admin/payments.json?callback=leak
Disqus(api_key is same for all users): http://disqus.com/api/3.0/users/listActivity.json?include=user&limit=10&api_key=Y1S1wGIzdc63qnZ5rhHfjqEABGA4ZTDncauWFFWWTUBqkmLjdxloTb7ilhGnZ7z1&callback=leak
Disqus refused to fix it explaining that "exposed data is not private", lol, but it's still personal.
Why this happens? Sometimes JSONP for private data applied by purpose - this means developers are bad at web security. But more interesting case when, for example, team adds Rack::JSONP middleware for Feature1 but it is designed to add callback in all JSON responses. You should know your stack well.
API must not detect user by his cookies (about "broken" cookies' nature). If you "proxy" your API through website make sure to add additional CSRF token in the headers. Yes, for GET too. Because CSRF token's main goal is to protect your cookies. This is not about POST or GET, this is about your cookies == credentials.
By the way people often forget to filter and sanitize "callback" parameter. It can lead to XSS in IE6-8, because it detects content type from file extension:
URL/api.html?callback=<script>...</script>
It's also a handy Content Security Policy (denying 3rd party script sources) bypass - <script src="local.json?callback=payload//">
I recommend to allow [a-zA-Z0-9] callbacks only and use HTML5 cross domain sharing techniques rather than this insecure trick. Thanks for reading, share your ideas
Friday, February 15, 2013
Monday, February 11, 2013
Rails Vulnerabilities: Learning The Lesson
previous: Rails is [Fr]agile. Vulnerabilities Will Keep Coming
JSON exploit: http://www.zweitag.de/en/blog/ruby-on-rails-vulnerable-to-mass-assignment-and-sql-injection
JSON exploit: http://www.zweitag.de/en/blog/ruby-on-rails-vulnerable-to-mass-assignment-and-sql-injection
Today we got 3 new vulns, IMO only JSON-related is dangerous, but I want to look at the lesson we all should learn.
attr_protected must be removed at all because it leads to DoS easily.
I guess this method is extremely unpopular anyway - nobody cares.
I guess this method is extremely unpopular anyway - nobody cares.
Regexps
use /m flag to match with newlines with .
"aa(cc\nbb".to_s.gsub(/\(.+/, '')
=> "aa\nbb"
YAML
Wasn't it absolutely obvious to keep YAML.load away from "input"? It was, then why rubygems (Gemfile.lock) and 'serialize' were waiting for "personal" exploits? I knew about potential vuln through SQL injection, but I was on rails 4 codebase. Even direct assignment leads to RCE in older rails. This is bad and silly :(
Don't Put Magic Params Into Magic Methods
just a few examples(you probably read them if you're following @homakov)
Any parameter in rails app can be: Integer, Date, Time, StringIO, Boolean, BigDecimal, Float, Array or Hash. thanks to alternative inputs and rack query parser!
1) validates :field, length: 2..10
it is not safe because param can be an array: field[]=123123123123123123123&field[]
2) redirect_to user_input
can lead to XSS if user_input[status]=200&user_input[protocol]=javascript:...
3) create(!) accepts arrays and can create thousands of records with one call! It can be used with JSON params and your service will be full of spam.
4) your mailer can be used for bad because :to accepts an array and it can be a long array with other people's addresses.
5) mysql compares "string" with integers by casting strings to 0. Yes, "randomtoken"==0 for it. Thanks @joernchen for the find but it's WONTFIX. 0 can be easily passed via JSON and XML.
JSON
If you ask me what I trust in I reply God JSON. It looks like such a simple format, so reliable and obvious. Until today. Today I learned that "json_class" attribute makes json parser to "const_get" the value. This is non sense. JSON::GenericObject is double non sense. Sad panda.
backports
there are some vulns fixed in 4 but they were not ported on old versions. For example escape_html_entities_in_json - if you do JSON.dump(user_input) it can lead to XSS in < 4.
And CSRF for routes.rb match method.
default_headers to prevent clickjacking
And bunch of other stuff.
And CSRF for routes.rb match method.
default_headers to prevent clickjacking
And bunch of other stuff.
hardening
rails codebase contains too many features not used in everyday development. Multiparameters, alternative inputs, aliases(alias in named route collection leading to RCE) and so on. It needs hardening, to reduce such enormous surface for attacks.
P.S. don't blame Rails again. You can blame rails for mass assignment (i'm kidding, blame yourself for this), but for RCEs - blame JSON/YAML gems.
So far, Rails itself is pretty safe.
So far, Rails itself is pretty safe.
Thursday, February 7, 2013
Rethinking Cookies: originOnly
Hacker news, reddit
TL;DR this post is full pain, theory and utopia. Don't mind to read if you don't care about better designed web.
What are Cookies now? This is a custom set of data, sent with every request from Client to Server in HTTP headers, mostly used for authentication purposes. Client-side(javascript) can set cookies, but this is a rare use case. Usually cookies are set on server-side, and it contains a special string to determine who is user: signed session, session_id, whatever.
All client side vulnerabilites in web security are because of cookies.
I repeat:
Cookies. They made web broken.
We invented httpOnly to make critical auth information inaccessible from client side and XSS. We were too stupid to make everything httpOnly by default and only few, really needed on client side httpAccessible or something.
We invented X-Frame-Options to deny "showing" of actually *received* private information. Cool, huh? Response with message: "don't read it if you're wrong person". And, look at some PoC.
Bonus question: Why ClearClick(checks visibility of frame on click) technology is not built-in? It is so easy, isn't it.. But Google has AdSense. AdSense is multibillion business and they have powerful tools to detect clickjacking - people, bots, data mining. Other companies( newbies in web advertising) are easily clickjackable. It's called competitive advantage
What is CSRF, in a nutshell? Is this just a request from domain1 to domain2? No, if you want such request you can use curl, so core 'benefit' of CSRF is usage of User's cookies for domain2.
This is how cookies work from its creation: you set them once and they are sent automatically, from all hosts/origins and for all kinds of requests(<script>, <img>, <iframe>).
Requests are always sent with your cookies. The very core, key problem.
We invented CSRF Token to make sure that Cookie was sent from proper origin intentionally, not from unknown malicious website. This is just so damn stupid: token to protect another, automatically-sent token.
Auth cookie is "key", CSRF token is "another key", proof that "key" was used intentionally. U MAD
It all happened because information was actually received by malicious website. All it needs is a trick to extract it. Previously people could reload Array constructor. Who knows what's next? Stealing plain text tokens through ECMAScript Proxy object(analog of method_missing)? Through styleSheet definitions? Through <audio>/<video> stream or canvas? about:blank referrer? Yet another flash vuln?
Jesus, I'm tired of this.
Maybe we are doing it all wrong..?
It's never too late to make something right.
Don't use my Cookies until I decide to use it myself.
Why I wrote this?
I want web to be ideal. I want web to be like Mona Lisa: perfect or close to it (in terms of architecture)
Yes, this post is utopic, I just want more people to think about the problem, not about yet another workaround.
"It will break "like" buttons and sometimes useful cross POST whatever..."
If you don't need this flag - don't set it. Just let other 99% of websites to be safe-by-default, not waiting for yet another 0day "trick".
Would love to discuss it with web security minded people! Please, write your thoughts!
TL;DR this post is full pain, theory and utopia. Don't mind to read if you don't care about better designed web.
What are Cookies now? This is a custom set of data, sent with every request from Client to Server in HTTP headers, mostly used for authentication purposes. Client-side(javascript) can set cookies, but this is a rare use case. Usually cookies are set on server-side, and it contains a special string to determine who is user: signed session, session_id, whatever.
All client side vulnerabilites in web security are because of cookies.
I repeat:
Cookies. They made web broken.
Problem 0 [solved, unrelated]: tampering.
You can sign cookie with session_secret or store only random string associated with session to prevent tampering.Problem 1 [solved]: XSS(Cross Site Scripting)
It can steal cookies because Javascript has access to cookies. This is why we invented 'httpOnly' flag. This flag disallows reading httpOnly cookie from javascript. There is also similar "secure" flag to transfer cookies only via secure connection(MITM)We invented httpOnly to make critical auth information inaccessible from client side and XSS. We were too stupid to make everything httpOnly by default and only few, really needed on client side httpAccessible or something.
Problem 2 [worked around] Clickjacking, framing.
Framed website received your cookies. There is nothing bad in framing any website without sending auth cookies.We invented X-Frame-Options to deny "showing" of actually *received* private information. Cool, huh? Response with message: "don't read it if you're wrong person". And, look at some PoC.
Bonus question: Why ClearClick(checks visibility of frame on click) technology is not built-in? It is so easy, isn't it.. But Google has AdSense. AdSense is multibillion business and they have powerful tools to detect clickjacking - people, bots, data mining. Other companies( newbies in web advertising) are easily clickjackable. It's called competitive advantage
Problem 3 [worked around]: CSRF
My old articles: CSRF Is Vulnerability in All Browsers and CSRF in 15 Popular WebsitesWhat is CSRF, in a nutshell? Is this just a request from domain1 to domain2? No, if you want such request you can use curl, so core 'benefit' of CSRF is usage of User's cookies for domain2.
This is how cookies work from its creation: you set them once and they are sent automatically, from all hosts/origins and for all kinds of requests(<script>, <img>, <iframe>).
Requests are always sent with your cookies. The very core, key problem.
We invented CSRF Token to make sure that Cookie was sent from proper origin intentionally, not from unknown malicious website. This is just so damn stupid: token to protect another, automatically-sent token.
Auth cookie is "key", CSRF token is "another key", proof that "key" was used intentionally. U MAD
Problem 4: [not solved]: Advanced CSRF
Remember JSON leakings? Discovered 4-5 years ago, it was on Hacker News again yesterday.It all happened because information was actually received by malicious website. All it needs is a trick to extract it. Previously people could reload Array constructor. Who knows what's next? Stealing plain text tokens through ECMAScript Proxy object(analog of method_missing)? Through styleSheet definitions? Through <audio>/<video> stream or canvas? about:blank referrer? Yet another flash vuln?
Jesus, I'm tired of this.
Maybe we are doing it all wrong..?
It's never too late to make something right.
Don't use my Cookies until I decide to use it myself.
originOnly flag
with such flag the Cookie will be sent only when request's origin is equal this cookie's domain. If it was set on site.com than it's sent only if element(<img>, <form>, <script>, style, <iframe> etc) or XHR was executed on this domain. Or if user navigated to this website(opened in a new tab or clicked link somewhere else)Why I wrote this?
I want web to be ideal. I want web to be like Mona Lisa: perfect or close to it (in terms of architecture)
Yes, this post is utopic, I just want more people to think about the problem, not about yet another workaround.
"It will break "like" buttons and sometimes useful cross POST whatever..."
If you don't need this flag - don't set it. Just let other 99% of websites to be safe-by-default, not waiting for yet another 0day "trick".
Would love to discuss it with web security minded people! Please, write your thoughts!
Sunday, February 3, 2013
Hacking With XSS Auditor
on Hacker News and reddit
Previously I wrote how you can use XSS Auditor for Great Good(report to administrator about detected XSS exploits) and how to destroy framebrakers/other scirpts with it(just passing script's code in a random parameter).
Today's topic is really interesting. We are not hacking XSS Auditor anymore, we are hacking with it.
I'll tell you how to steal referers with sensitive information.
First of all, there are three values of 'X-XSS-Protection' header which control XSS Auditor: 0; 1; and 1;mode=block.
First one just switches it off(I recommend it, lol).
1; is default, it detects XSS and tries to remove malicious code.
1;mode=block means basically if anything has been detected - redirect to about:blank. People used to think about it as the most secure one. Actually, no!
Steps for the hack are very simple(TL;DR is point 5):
There are some restrictions of course! The most obvious - it won't work for https:// pages because they don't send Referrer. But as a new vector sounds pretty awesome.
The fix is gonna be very simple - clear document.referrer for about:blank redirect.
[this guy, who wrote the article... you can hire him for a penetration test or security consulting btw. affordable price, cutting edge hacks: homakov@gmail.com]
Previously I wrote how you can use XSS Auditor for Great Good(report to administrator about detected XSS exploits) and how to destroy framebrakers/other scirpts with it(just passing script's code in a random parameter).
Today's topic is really interesting. We are not hacking XSS Auditor anymore, we are hacking with it.
I'll tell you how to steal referers with sensitive information.
First of all, there are three values of 'X-XSS-Protection' header which control XSS Auditor: 0; 1; and 1;mode=block.
First one just switches it off(I recommend it, lol).
1; is default, it detects XSS and tries to remove malicious code.
1;mode=block means basically if anything has been detected - redirect to about:blank. People used to think about it as the most secure one. Actually, no!
Steps for the hack are very simple(TL;DR is point 5):
- choose URL which redirects automatically(or with some user interaction) to another URL, and also carries both Private Info and Custom Payload.
For OAuth and Single Sign On implementations Private Info is code/token/signed_request. It can be also kind of SID if it was added automatically to original URL, not removing Custom Payload.
Custom Payload - part of redirect_uri if it's not static or some kind of 'state', which is used in OAuth to prevent CSRF and basically returned back along with code(And I found the Most Common Vulnerability with it another day). - Look at the source code of the final page which user is redirected to. Choose some <script src=...></script> or <script>code</script> or <meta http-equiv..> or <a href=javascript:..> etc. Anything, that will look like an "injection" for Mr. Auditor. Copy it and encode.
- Now put it in the original URL in your Custom Payload. for example 'state=%3Cscript%3Esetup()%3C%2Fscript%3E'
- create MalloryPage. You can use <iframe> if target has no X-Frame-Options or use window.open if it has.
- when User visits MalloryPage he opens your crafted URL with Custom Payload, website redirects him to final page with both Private Info and Custom Payload, chrome XSS Auditor detects XSS because Custom Payload was found in source code, redirects him again to about:blank, which is easily accessible from opener's domain - now you got document.referrer with Private Info!
There are some restrictions of course! The most obvious - it won't work for https:// pages because they don't send Referrer. But as a new vector sounds pretty awesome.
The fix is gonna be very simple - clear document.referrer for about:blank redirect.
[this guy, who wrote the article... you can hire him for a penetration test or security consulting btw. affordable price, cutting edge hacks: homakov@gmail.com]
Thursday, January 31, 2013
Rails is [Fr]agile. Vulnerabilities Will Keep Coming.
This post is just a thought, with some minor vulnerabilities(all of them are reported). Everyone knows these "January events":
1) find_by_* can be tricked to use user input's :select as injection
2) XML can be tricked to use YAML
3) YAML can be tricked to initialize arbitrary objects
4) AGAIN! JSON can be tricked to use YAML(see point 3..)
Is it over? No, I guess.
This is just a short demo, how FAR this [Fr]agileness can lead to:
There is "redirect_to" method and it accepts:
# * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
# * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
# * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) or a protocol relative reference (like <tt>//</tt>) - Is passed straight through as the target for redirection.
# * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
# * <tt>Proc</tt> - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+.
# * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
Agile, huh?
Let's assume there is open redirect(it's bad but it happens): 'redirect_to params[:next]'
Here is generated response for /path?next[status]=200&next[protocol]=javascript:alert(document.domain)
<html><body>You are being <a href="javascript:alert( document.domain)//HOST/">re directed</a>.</body></html>
Status 200 - no redirect happened. URL has XSS. Now you just need to make user to click it. You can use clickjacking, but he can also decide to click by himself. And you can also set custom :alert, :notice - flash messages.
Another one - famous arrays with nils, which was patched in JSON/XML parsers too and it broke some apps. If you pass [nil] to find_by_ methods you can also find records where this field IS NULL(It wasn't set, intentionally). This is a good vulnerability for all kinds of APIs, spree example: https://github.com/spree/spree/pull/2492
(I'm sorry about this PR and I behaved irresponsibly. Following bugs were disclosed privately.)
Conclusion: keep an eye on your 'params'. Don't put it in 'agile' methods. It hurts.
Another conclusion: should we (Rails) start using less magic and more predictable behavior? I'm not sure.
P.S. Most likely this is the last technical post in the blog. I am starting a yet another security agency(core service is the Ruby/Rails audit), doing pen-test and code review for some cool startups and it's awesome when you can hack/help people and get paid for it.
Want to make your Ruby application super secure? Drop a line: homakov@gmail.com
Following security posts will be published on another website, some of old posts will be probably rewritten, with nifty design etc. I got a lot of delicious stuff in my drafts ;)
1) find_by_* can be tricked to use user input's :select as injection
2) XML can be tricked to use YAML
3) YAML can be tricked to initialize arbitrary objects
4) AGAIN! JSON can be tricked to use YAML(see point 3..)
Is it over? No, I guess.
This is just a short demo, how FAR this [Fr]agileness can lead to:
There is "redirect_to" method and it accepts:
# * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
# * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
# * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) or a protocol relative reference (like <tt>//</tt>) - Is passed straight through as the target for redirection.
# * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
# * <tt>Proc</tt> - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+.
# * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
Agile, huh?
Let's assume there is open redirect(it's bad but it happens): 'redirect_to params[:next]'
Here is generated response for /path?next[status]=200&next[protocol]=javascript:alert(document.domain)
<html><body>You are being <a href="javascript:alert(
Status 200 - no redirect happened. URL has XSS. Now you just need to make user to click it. You can use clickjacking, but he can also decide to click by himself. And you can also set custom :alert, :notice - flash messages.
Another one - famous arrays with nils, which was patched in JSON/XML parsers too and it broke some apps. If you pass [nil] to find_by_ methods you can also find records where this field IS NULL(It wasn't set, intentionally). This is a good vulnerability for all kinds of APIs, spree example: https://github.com/spree/spree/pull/2492
(I'm sorry about this PR and I behaved irresponsibly. Following bugs were disclosed privately.)
Conclusion: keep an eye on your 'params'. Don't put it in 'agile' methods. It hurts.
Another conclusion: should we (Rails) start using less magic and more predictable behavior? I'm not sure.
P.S. Most likely this is the last technical post in the blog. I am starting a yet another security agency(core service is the Ruby/Rails audit), doing pen-test and code review for some cool startups and it's awesome when you can hack/help people and get paid for it.
Want to make your Ruby application super secure? Drop a line: homakov@gmail.com
Following security posts will be published on another website, some of old posts will be probably rewritten, with nifty design etc. I got a lot of delicious stuff in my drafts ;)
Friday, January 18, 2013
XSS Hunter: Using XSS Auditor For Great Good
discussion: Hacker News, reddit
What is XSS Auditor?
It's a built in chrome(and IE) tool, switched on by default(you can control it with X-XSS-Protection header, either 0;, 1; or 1;block), which inspects all request params and response body trying to find if any of param present as malicious script inside of body. If it detects anything odd - by default it just removes it from HTML. It can lead to weird things..
First of all we will use it for some evil.
I am telling nothing new, but a trick from my previous post - slicing scripts and events you don't like in some page
You can remove any event "on*", any javascript:... link and any <script> tag. Best targets: confirms(to make clickjacking easier) and framebuster scripts, sending them in request params(?removal=<script>remove_me();</script>). Without them life of hacker gets easier.
Don't touch my framebuster!
I created a neat trick to disallow such things to happen. Just put some random code in your code(<script src="framebuster.js?<%=rand(1,9999)%>"></script>) - nobody knows how code looks in response so it's impossible to 'cut' it off.
XSS Auditor is a pain in ass for scriptkiddies.
This is out of question. They just hate it. So let's use it even for greater good!
I wrote a demo script which detects if XSS Auditor removed any inject and if it did - we fire up document.onxssprotection event(which will notify the administrator of website for example).
Don't touch my auditor of XSS Auditor!
And we don't want our XSS auditor removed either - so when you use it be sure to write src="auditor.js?RANDOM"
I like it more than any WAF - "native" environment detects XSSes better than server side middlewares(take into account performance too).
This code is rather demo and may content bugs, I did not test it in all browsers and IE. Feel free to contribute.
What is XSS Auditor?
It's a built in chrome(and IE) tool, switched on by default(you can control it with X-XSS-Protection header, either 0;, 1; or 1;block), which inspects all request params and response body trying to find if any of param present as malicious script inside of body. If it detects anything odd - by default it just removes it from HTML. It can lead to weird things..
First of all we will use it for some evil.
I am telling nothing new, but a trick from my previous post - slicing scripts and events you don't like in some page
You can remove any event "on*", any javascript:... link and any <script> tag. Best targets: confirms(to make clickjacking easier) and framebuster scripts, sending them in request params(?removal=<script>remove_me();</script>). Without them life of hacker gets easier.
Don't touch my framebuster!
I created a neat trick to disallow such things to happen. Just put some random code in your code(<script src="framebuster.js?<%=rand(1,9999)%>"></script>) - nobody knows how code looks in response so it's impossible to 'cut' it off.
XSS Auditor is a pain in ass for scriptkiddies.
This is out of question. They just hate it. So let's use it even for greater good!
I wrote a demo script which detects if XSS Auditor removed any inject and if it did - we fire up document.onxssprotection event(which will notify the administrator of website for example).
Don't touch my auditor of XSS Auditor!
And we don't want our XSS auditor removed either - so when you use it be sure to write src="auditor.js?RANDOM"
I like it more than any WAF - "native" environment detects XSSes better than server side middlewares(take into account performance too).
This code is rather demo and may content bugs, I did not test it in all browsers and IE. Feel free to contribute.
Thursday, January 10, 2013
Rails 'params' #2
I discovered [1, nil] attack, but while i was checking unsafe query generation and DoS with symbols people on twitter found RCE for YAML through instancing some class that will eventually eval attribute from user input! Sweet!
IMHO this article is best on topic, and explains the whole chain of exploitation.
I told you, didn't i?
IMHO this article is best on topic, and explains the whole chain of exploitation.
I told you, didn't i?
Thursday, January 3, 2013
Rails Security Digest. 'params' Case
On HN
Old tricks, new workarounds. In this post I gave mitigation advice and some explanation of WTH IS GOING ON.
1. https://groups.google.com/forum/?fromgroups=#!topic/rubyonrails-security/DCNTNp_qjFM
You need to send keys as symbols! It's not that easy. While you can use symbols in HashWithIndifferentAccess, those symbols params[:id][:symbol] is not the case - only 'symbol' key will be used by find_by_* method.
2. Maybe put poisoned payload in your session cookie?
Tenderlove explains:
3. Maybe craft poisoned payload in params? Normal application/x-www-form-urlencoded won't work, because keys are strings. JSON decodes to strings either. params is always HWIA. Injection is never going to happen through params[:id]
Old tricks, new workarounds. In this post I gave mitigation advice and some explanation of WTH IS GOING ON.
1. https://groups.google.com/forum/?fromgroups=#!topic/rubyonrails-security/DCNTNp_qjFM
The issue can be mitigated by explicitly converting the parameter to an expected value. For example, change this:HOW CAN I USE IT?
Post.find_by_id(params[:id])
to this:
Post.find_by_id(params[:id].to_s)
You need to send keys as symbols! It's not that easy. While you can use symbols in HashWithIndifferentAccess, those symbols params[:id][:symbol] is not the case - only 'symbol' key will be used by find_by_* method.
2. Maybe put poisoned payload in your session cookie?
Tenderlove explains:
>However, this exploit does not require session secrets. The person who wrote the blog post wrote about essentially two vulnerabilities: session forging and SQL injection.You will need to know session_secret, which is hard to steal. Forget about it.
3. Maybe craft poisoned payload in params? Normal application/x-www-form-urlencoded won't work, because keys are strings. JSON decodes to strings either. params is always HWIA. Injection is never going to happen through params[:id]
Thursday, November 29, 2012
XSS + "Save your password" = pwned
(on HNews)
Basically, browsers often suggest you to save your password and prefill it automatically.
The bug I just discovered: This value can be retrieved from JS side easily(and this means XSS can steal it). Your REAL password. It's not fucking yet-another-CSRF or SQL injection(server side is pwned) or other trivial. YOU are pwned. Kind of a serious issue.
Very similar to old issue with 'highlighted' visited links, when attacker could know did you visit certain link or not.
Also, XSS can be on any page and user can be signed in or signed out. It will just open iframe or window and get values because of same origin.
Basically, browsers often suggest you to save your password and prefill it automatically.
The bug I just discovered: This value can be retrieved from JS side easily(and this means XSS can steal it). Your REAL password. It's not fucking yet-another-CSRF or SQL injection(server side is pwned) or other trivial. YOU are pwned. Kind of a serious issue.
Very similar to old issue with 'highlighted' visited links, when attacker could know did you visit certain link or not.
Also, XSS can be on any page and user can be signed in or signed out. It will just open iframe or window and get values because of same origin.
DEMO
Browsers should deny access to prefilled passwords from JS.(UPD: not helpful)
P.S. I'm alive and in Asia(now Kuala Lumpur). Don't worry, new stuff will be published soon ;)
Authentication: username:password
and to do so you have to use XHR. If you cannot retrieve password from autofilled input authentication will get broken.
2. There is one more workaround - XSS can change 'action' field to 3rd party website and then .submit(). JS doesn't need access to .value - browser itself will send it to attacker's server. Should we restrict sending passwords only to actions on the current page domain(same origin)? Sounds ugly.
Possible solutions:
1. restricting 'action' value to same origin. Ugly?
2. using Autocomplete only when user is interacting with the website e.g. by typing the first letters of the nickname.
3. Ask in the top bar notification "Should we use autocomplete on example.com?" or smth like this. Looks not bad to me.
4. BEST ONE: do not use any autofill. At least for passwords.
Because security of autofills is fucked. The more websites you use - the more probability to be XSSed on the one of them.
P.S. I'm alive and in Asia(now Kuala Lumpur). Don't worry, new stuff will be published soon ;)
I WAS WRONG. (About these two things)
1. Proposed solution will break the AJAX-based authentications since JS will not have access to password anymore. For example you might want to send password in a header:Authentication: username:password
and to do so you have to use XHR. If you cannot retrieve password from autofilled input authentication will get broken.
2. There is one more workaround - XSS can change 'action' field to 3rd party website and then .submit(). JS doesn't need access to .value - browser itself will send it to attacker's server. Should we restrict sending passwords only to actions on the current page domain(same origin)? Sounds ugly.
Possible solutions:
1. restricting 'action' value to same origin. Ugly?
2. using Autocomplete only when user is interacting with the website e.g. by typing the first letters of the nickname.
3. Ask in the top bar notification "Should we use autocomplete on example.com?" or smth like this. Looks not bad to me.
4. BEST ONE: do not use any autofill. At least for passwords.
Because security of autofills is fucked. The more websites you use - the more probability to be XSSed on the one of them.
Thursday, September 6, 2012
The Story About Two OAuth2 Vulnerabilities
Facebook Connect Reply Attack
There is a blatant issue in facebook connect. It's vulnerable to replay attack.
Authorization 'code' expires as soon as access_token expires - approximately 60-80 minutes, during this period it can be used many times to obtain access_token. Every time you visit example.org/fb_callback?code=123qwe... you are authenticated for example.org.
FB Connect doesn't follow clear and concise countermeasures from Threat Model. Here they are with annotations:
Logs.
For example if you use omniauth with rails check your logs for
GET "/auth/facebook/callback?code=..."
I recommend to filter this parameter with built-in tool:
config.filter_parameters += [:password, :code]
Sniff
Callback is located on Client's website - and it is not always HTTPS. Your URL with code may be sniffed with MITM, browser plugins, browser history(if it has not redirects) etc
XSS
Here is a neat exploit to extract callback URL for proper redirect_uri.
<iframe src="https://www.facebook.com/dialog/permissions.request?app_id=159618457465836&display=page&next=http://magru.net/users/auth/facebook/callback&response_type=code" name="refcontainer" onload="alert(refcontainer.document.referrer)"></iframe>
1) Load authorize URL with proper redirect_uri as callback in iframe
2) get redirected on proper redirect_uri with code
3) another redirect, usually to root
4) fires up 'onload' event
5) since we are on the same origin we just go into iframe and extract 'document.referrer' - redirect_uri with code.
6) leak code and use it for replay attacks.
Mitigation:
One time usage of 'code', please. There is no sense to keep 'code' if Client already obtained access_token for it.
Vkontakte Referrer Leak
Vkontakte has one time usage of 'code'. No replay attack here... Wait, there is a similar one. VK OAuth2 has a huge flaw.
They do not require 'redirect_uri' to exchange code for token. It means there is no verification, was certain 'code' issued for proper redirect_uri or any other URL (on Client's domain).
You can get a code for
SITE.com/fake_callback_leaking_referrer?code=123qwe
and then just use it on
SITE.com/real_callback?code=123qwe
You will be authenticated.
There are literally dozens of ways to leak code: browser history, hot linked images leak referrer, clickjacking with clicking on external URL, sniffing, open redirectors(feature on some sites site.com?url=http://other.com) etc
Mitigation:
There is a blatant issue in facebook connect. It's vulnerable to replay attack.
Authorization 'code' expires as soon as access_token expires - approximately 60-80 minutes, during this period it can be used many times to obtain access_token. Every time you visit example.org/fb_callback?code=123qwe... you are authenticated for example.org.
FB Connect doesn't follow clear and concise countermeasures from Threat Model. Here they are with annotations:
o Limited duration of authorization codes - Section 5.1.5.3 [60-80 minutes are more than enough]
o The authorization server should enforce a one time usage restriction (see Section 5.1.5.4). [unlimited]There are couple of ways to get 'code':
Logs.
For example if you use omniauth with rails check your logs for
GET "/auth/facebook/callback?code=..."
I recommend to filter this parameter with built-in tool:
config.filter_parameters += [:password, :code]
Sniff
Callback is located on Client's website - and it is not always HTTPS. Your URL with code may be sniffed with MITM, browser plugins, browser history(if it has not redirects) etc
XSS
Here is a neat exploit to extract callback URL for proper redirect_uri.
<iframe src="https://www.facebook.com/dialog/permissions.request?app_id=159618457465836&display=page&next=http://magru.net/users/auth/facebook/callback&response_type=code" name="refcontainer" onload="alert(refcontainer.document.referrer)"></iframe>
1) Load authorize URL with proper redirect_uri as callback in iframe
2) get redirected on proper redirect_uri with code
3) another redirect, usually to root
4) fires up 'onload' event
5) since we are on the same origin we just go into iframe and extract 'document.referrer' - redirect_uri with code.
6) leak code and use it for replay attacks.
Mitigation:
One time usage of 'code', please. There is no sense to keep 'code' if Client already obtained access_token for it.
Vkontakte Referrer Leak
Vkontakte has one time usage of 'code'. No replay attack here... Wait, there is a similar one. VK OAuth2 has a huge flaw.
They do not require 'redirect_uri' to exchange code for token. It means there is no verification, was certain 'code' issued for proper redirect_uri or any other URL (on Client's domain).
You can get a code for
SITE.com/fake_callback_leaking_referrer?code=123qwe
and then just use it on
SITE.com/real_callback?code=123qwe
You will be authenticated.
There are literally dozens of ways to leak code: browser history, hot linked images leak referrer, clickjacking with clicking on external URL, sniffing, open redirectors(feature on some sites site.com?url=http://other.com) etc
Mitigation:
Every time you create code you must save for which redirect_uri it was issued. When code will be exchanged for token, ensure that given redirect_uri parameter is equal stored.
Result
Fixed on facebook, 2 grands $ bounty, fixed on vkontakte (for new apps only).
Wednesday, August 29, 2012
How To Cheat On Facebook Apps Permissions
Facebook doesn't care about your privacy, but you should. Facebook implements OAuth2 - readers of my blog know how shitty OAuth2 is and how awesome OAuth2.a will be.
Apps actually cannot require permissions ('scope' param). They propose it, but you can choose them - update authorization URL.
Example - you are redirected to:
https://www.facebook.com/dialog/oauth?client_id=130409810307796&redirect_uri=http%3A%2F%2Fapps.facebook.com%2Ftetris_battle%2F%2F%3Fkt_track_apa%3D1%26reload%3D1%26reloadTime%3D1346239416%26localJS%3Dfalse&state=6997cb601838cb0fb65d53aecbebcd21&scope=publish_actions%2Cemail%2Cuser_location%2Cuser_birthday
Just change 'scope' param
https://www.facebook.com/dialog/oauth?client_id=130409810307796&redirect_uri=http%3A%2F%2Fapps.facebook.com%2Ftetris_battle%2F%2F%3Fkt_track_apa%3D1%26reload%3D1%26reloadTime%3D1346239416%26localJS%3Dfalse&state=6997cb601838cb0fb65d53aecbebcd21&scope=
And authorize the app. You permitted nothing special but app works - enjoy.
UPDATE:
The post had nothing to do with security. I was annoyed with terrible fact "you can ask permissions, it will look legit and user cannot uncheck them in UI. Well if he's smart enough to change URL - you have to check permissions in your code"
There are two ways to fix it (OAuth2.a deals with the issue this way):
1) when app has "frozen" scope. This is not param in URL anymore, just a field in the database. Developer doesn't need to make sure what is allowed anymore - he is sure.
2) when app has "agile" scope. Client 'proposes' scope and User can uncheck not desired permissions. App should check explicitly what was permitted.
Apps actually cannot require permissions ('scope' param). They propose it, but you can choose them - update authorization URL.
Example - you are redirected to:
https://www.facebook.com/dialog/oauth?client_id=130409810307796&redirect_uri=http%3A%2F%2Fapps.facebook.com%2Ftetris_battle%2F%2F%3Fkt_track_apa%3D1%26reload%3D1%26reloadTime%3D1346239416%26localJS%3Dfalse&state=6997cb601838cb0fb65d53aecbebcd21&scope=publish_actions%2Cemail%2Cuser_location%2Cuser_birthday
Just change 'scope' param
https://www.facebook.com/dialog/oauth?client_id=130409810307796&redirect_uri=http%3A%2F%2Fapps.facebook.com%2Ftetris_battle%2F%2F%3Fkt_track_apa%3D1%26reload%3D1%26reloadTime%3D1346239416%26localJS%3Dfalse&state=6997cb601838cb0fb65d53aecbebcd21&scope=
And authorize the app. You permitted nothing special but app works - enjoy.
UPDATE:
The post had nothing to do with security. I was annoyed with terrible fact "you can ask permissions, it will look legit and user cannot uncheck them in UI. Well if he's smart enough to change URL - you have to check permissions in your code"
There are two ways to fix it (OAuth2.a deals with the issue this way):
1) when app has "frozen" scope. This is not param in URL anymore, just a field in the database. Developer doesn't need to make sure what is allowed anymore - he is sure.
2) when app has "agile" scope. Client 'proposes' scope and User can uncheck not desired permissions. App should check explicitly what was permitted.
Tuesday, August 28, 2012
OAuth2: One access_token To Rule Them All
One access_token to rule them all...
I demonstrated The Most Common OAuth2 Vulnerability in Authorization Code Flow a while ago – signing in the Victim's account(followed by getting an access to Victim's resources on that website) by connecting Attacker's oauth account through CSRF-callback URL with Attacker's code. Despite popularity of that attack, it can be easily mitigated with 'state' param(to prevent CSRF) – and now it's fixed in popular ruby/python libraries.
Now I want to share a very straightforward attack for Implicit Flow based websites(realized in brainstorming with @isciurus). There is no proper mitigation so far.
Generally speaking:
- 'access_token' is a string that identifies your Resources on Provider. No other parameters are required to call Provider's API. There is no guarantee user's access_token1 for client1 is not used by client2 or client75 - nothing stops them.
- Let's assume I create a website: e.g. superfunnypicturez.com. I ask my users to authorize my Client on facebook and I don't ask any scopes at all - I need only "/me" endpoint with "uid" param to be available. They authorize my Client because superfunnypicturez.com requires only 'read' access and nothing seems to be dangerous. I get their 'access_token's and now I can request /me endpoint and get their "uid"(often used for authentication)
- Let's assume there is another site: e.g. weuseimplicitflow.com and yep, it uses Implicit Flow(receives token via CALLBACK#access_token=123qwe...). It's a pity - this website authenticates users by given access_token. Most likely it sends access_token on server-side and invokes /me endpoint from there.
- Since I am admin of superfunnypicturez.com and you authorized my Client and gave me an access_token from your account I just put that access token in callback URL: CALLBACK#access_token=YOUR_TOKEN and now weuseimplicitflow.com's Client authenticates me as you because that token I just provided returns your 'uid' when /me endpoint is called. I need only one access_token from your Provider's account to rule all your accounts on 3rd party websites that use Implicit Flow.
Recap:
OAuth2 is extremely insecure for authentication goals by default.
- Auth Code Flow: You must use 'state' parameter and verify - is this user the same user you sent to authorization URL by checking state value from session and returned one.
- Implicit Flow: You must ensure that access_token you are going to use is issued for your Client. Please, use this URL for Facebook: https://graph.facebook.com/app?fields=id&access_token=TOKEN. Not all providers support this feature though. If access_token is anyhow obtained from User (not from Provider) - you must verify is this access_token issued for your Client.
Oh, also:
As I mentioned in my previous post on stupidity of OAuth2 - if Provider has Implicit Flow as an option - lots of Users can be compromised someday. If a single XSS is found on Client's domain - hackers can steal all access_tokens with it even if your website uses Auth Code Flow by just changing response_type param in authorize URL.
Author of this article is awesome - you can actually hire him.
Wednesday, August 1, 2012
SaferWeb: OAuth2.a or Let's Just Fix It
Eran and others, chill out. We should stop whining to nobody. I prefer rather "we gotta fix this, this and discuss that" than "it is bad"-attitude. Some people were surprised because they like OAuth2.
What about me? I was not surprised because OAuth2 is far from perfect. But there is no reason to give up, it's in our hands. ( By the way I'm waiting for comments on Hacker News OK?)
Below I explain some security and usability concerns about current OAuth2 and propose(I do, not just say 'it is bad') improvements to make it more agile and safe-by-default. OAuth2.a is going to be easier to implement and more secure.
What about me? I was not surprised because OAuth2 is far from perfect. But there is no reason to give up, it's in our hands. ( By the way I'm waiting for comments on Hacker News OK?)
Below I explain some security and usability concerns about current OAuth2 and propose(I do, not just say 'it is bad') improvements to make it more agile and safe-by-default. OAuth2.a is going to be easier to implement and more secure.
TL;DR:
- redirect_uri can be on any domain and amount of redirect_uri-s is unlimited. They are whitelisted and only exact match verification is applied(redirect_uri IS NOT flexible domain.com/*). Client sets redirect_uri-s on his admin page in Provider.
- for every redirect_uri MUST be defined certain response_type - token or code. It must not be possible to set response_type in authorize URL. Every redirect_uri has its own defined response_type
- Most Common OAuth2 CSRF Vulnerability from my previous post. We should either introduce a new *compulsory* param(e.g. csrf_token) or just raise awareness about the issue.
- We need either assign 'scope' to certain redirect_uri as well as response_type(it MUST not be in URL) or allow user to choose what parts of scope to allow. It's up to Provider's implementation.
- We should introduce 'mass refreshing' of access_token-s. Client sends an array of refresh_token-s and client's credentials and get's hash with refresh_token=>access token.
- We need to define some DEFAULT URL paths and error codes to add a little bit more "interoperability". Really, is it so damn hard to keep your endpoints and error codes similar to other services?
![]() |
Tuesday, July 3, 2012
The Most Common OAuth2 Vulnerability

TL;DR
If website uses OAuth multi-logins there is an easy way to log into somebody's account, protection is almost never implemented and people don't take into account that OAuth is also used for authentication.
OAuth2 is an authorization framework. Apparently it's very popular now. Disregards its popularity a lot of people don't understand it deeply enough to write proper and secure implementation.
OAuth1.a and OAuth2 are incompatible, some services use former(twitter, wtf, come on!), some latter, some of them have insufficient and poor documentation(in terms of security) etc. It took me a few hours to read OAuth2 draft thoroughly and I found a few interesting vectors. One of them I am exposing in this post.
It's really dangerous but very common vulnerability for multi-login OAuth websites.
A little bit of theory:
- response_type = code is server-side auth flow, should be used when possible, more secure than response_type = token. Provider returns 'code' with User's user-agent and Client sends along with client's credentials the code to obtain 'access_token'. Callback when user is redirected looks like site.com/oauth/callback?code=AQCOtAVov1Cu316rpqPfs-8nDb-jJEiF7aex9n05e2dq3oiXlDwubVoC8VEGNq10rSkyyFb3wKbtZh6xpgG59FsAMMSjIAr613Ly1usZ47jPqADzbDyVuotFaRiQux3g6Ut84nmAf9j-KEvsX0bEPH_aCekLNJ1QAnjpls0SL9ZSK-yw1wPQWQsBhbfMPNJ_LqI
- I remind you, OAuth is all about authorization, not authentication. What's the difference, you might ask. OAuth just gives to Client access to User's resources on Provider.
But very often Client authenticates you by 'profile_info' resource, thus we can call it authentication framework either.
Hacking, Step-by-step:
- Choose Client which suits hack's "condition" - some site.com(we will use Pinterest as showcase) Start authentication process - click "Add OAuth Provider login". You need to get callback from Provider but should not visit it. It's quite difficult - all modern browsers redirect you automatically. I recommend bundle Firefox + NoRedirect extension.
- Do not visit the last URL(http://pinterest.com/connect/facebook/?code=AQCOtAVov1Cu316rpqPfs-8nDb-jJEiF7aex9n05e2dq3oiXlDwubVoC8VEGNq10rSkyyFb3wKbtZh6xpgG59FsAMMSjIAr613Ly1usZ47jPqADzbDyVuotFaRiQux3g6Ut84nmAf9j-KEvsX0bEPH_aCekLNJ1QAnjpls0SL9ZSK-yw1wPQWQsBhbfMPNJ_LqI#_=_), just save and put it into <img src="URL"> or <iframe> or anything else you prefer to send requests.
- Now all you need is to make the User(some certain target or random site.com user) to send HTTP request on your callback URL. You can force him to visit example.com/somepage.html which contains <iframe src=URL>, post <img> on his wall, send him an email/tweet, whatever. User must be logged in site.com when he sends the request.
Well done, your oauth account is attached to User's account on site.com. - Voila, press Log In with that OAuth Provider - you are logged in directly to User's account on site.com.
Enjoy: read private messages, post comments, change payment details, have lulz, whatever. In fact account is yours now.
After you had enough fun you can just Disconnect that OAuth Provider and log out. Nobody will have an idea what has happened, you left no fingerprints!
How to detect, is certain OAuth implementation vulnerable?
If site doesn't send 'state' param and redirect_uri param is static and doesn't contain any random hashes - it's vulnerable.I know at least 10+ popular vulnerable sites: e.g. pinterest, digg, soundcloud, snip.it, bit.ly, stumbleupon etc. If you know more sites - please drop me a line at homakov@gmail.com
Also all Rails + Omniauth are vulnerable. Have fun(about 23,300 results)
updates:
- fixed for django https://github.com/omab/django-social-auth/issues/386
- fixed in omniauth https://github.com/intridea/omniauth/issues/612
- reported and fixed in soundcloud.com
- checking public libraries..
Mitigation:
You are supposed to send special optional param 'state' - any random hash you get back by Provider in User's callback: ?code=123&state=HASH. Before adding OAuth account you MUST verify session[state] is equal params[state].
Classic: Insecure-by-default means insecure. Majority of developers don't use it at all - nobody pays for "optional" weird param :trollface:
MUST READ SECTION.
Notices:
- $_SESSION['state'] == $_REQUEST['state'] is vulnerable code, was used a while ago in FB examples. Emtpy string equals empty string.
- I recommend you to filter 'code' in logs config.filter_parameters += [:code]
- state should not be equal form_authenticity_token(session[:csrf_token]) in rails
- if you implemented response_type=token flow w/o FB JS library, it's most likely vulnerable too.
At the moment I am working on "OAuth2 Security Proposal". The Proposal aims to make OAuth2 safer by changing its policies, rules and workflows. Most of the points are supposed to be backwards compatible but some of them are quite difficult to apply. Stay tuned, I am publishing it in a few days.
Friday, June 22, 2012
With New Features Come New Vulnerabilites. The Web is Broken.
I spam in twitter and RSS.
HN discussi0n
Security Digest:
HN discussi0n
Security Digest:
- Rails coders, I remind you the very last time :) Run command Find ".to_json" agains your 'app/views' and please sanitize it, I stumble upon case 2 from my Rails & Security talk really often.
- Use JSONP only with unique token per user. Don't give out private data via static URL.
- It goes without saying but.. Seriously, Regexp /^http://www.site.com/ is not enough to mitigate CSRFs (Yeah, also if you are rubyist you should use \A instead of ^! Rails has reminder now https://github.com/rails/rails/pull/6671) Why? Because http://www.site.com.hacker.com and http://www.site.com@hacker.com both are legit domains too. Do add "\/" in the end of your Regexp. Anyway, don't rely on Referer.
- X-Frame-Options (XFO) Detection from Javascript
- I found out that 'autofocus onfocus=inject' is a really nice vector and works great. Thanks .mario's html5sec.org, some of cases over there are really worth getting addressed.
- This is new section, please drop me a line homakov@gmail.com if you have any epic thing about security :3
Current status:
On the left - Me, pointing various problems, starving to get feedback and proposing some fixing in a painless way.
On the right - browsers, ruby, community, whatever's response :)
On the left - Me, pointing various problems, starving to get feedback and proposing some fixing in a painless way.
On the right - browsers, ruby, community, whatever's response :)
Look, web security is all about philosophy and concept. Root of plenty of the problems is a poor problem solution/design or irresponsible adding of new features.
When browsers implement a new feature they should also care how it'll work along with existing websites, in terms of security too.
Wednesday, June 6, 2012
x-www-form-urlencoded VS json - Pros and Cons. And Vulns.
In this short post I want to remind you how agile HTTP requests are. By "requests" we all mean GET and POST - these are the majority. POST contains "message", which is encoded in Internet media type etc - on wiki
By default <form method="post"> tag submits request with this header:
Content-Type:application/x-www-form-urlencoded
This is the default encoding format among HTTP requests. It was suffice just a few years ago - when all people have been sending nothing bigger and more complex than "email=my@mail.com&name=John".
It's 2012 now, web became much more comprehensive, more rich and data sets are huge now. Developers scope related params in hashes/arrays - in a "tricky" way. If you want to have user["email"] on the server side you are supposed to send
<input name="user[email]">
but if you want user[emailS"] - array of emails, you should send
<input name="user[emails][]">
By default <form method="post"> tag submits request with this header:
Content-Type:application/x-www-form-urlencoded
This is the default encoding format among HTTP requests. It was suffice just a few years ago - when all people have been sending nothing bigger and more complex than "email=my@mail.com&name=John".
It's 2012 now, web became much more comprehensive, more rich and data sets are huge now. Developers scope related params in hashes/arrays - in a "tricky" way. If you want to have user["email"] on the server side you are supposed to send
<input name="user[email]">
but if you want user[emailS"] - array of emails, you should send
<input name="user[emails][]">
Application accumulates all params one by one and put them in the corresponding variables. This attitude is full of bugs and incompatibilities. Let me give you a hence.
Saturday, May 19, 2012
Injects in Various Ruby Websites Through Regexp.
On HN
You are a web developer. Let's assume you are building a website using Ruby(and probably Rails or any other Ruby framework). This is why you need to validate some input params - to make sure that they don't contain any crap you don't want to be there. Come on, you are going to google it, right?:
You are a web developer. Let's assume you are building a website using Ruby(and probably Rails or any other Ruby framework). This is why you need to validate some input params - to make sure that they don't contain any crap you don't want to be there. Come on, you are going to google it, right?:
Tuesday, April 24, 2012
"match" in Rails and CSRF
Related:
CSRF afterparty & MUST READ rules
Playing With Referer & Origin + disqus.com and yfrog.com Vulnerability)
Sometimes developers use GET for state-changing requests by purpose. This determines low-skilled developer. In this post I want to describe another vector of attack - GET Accessible Actions(GAA) - when framework abstractions + bad practices make "Good Guys' apps" insecure.
There is a thing I found exploring DSL's and engines' internals - many frameworks do "dirty work" for developer - they merge GET(stored in URL string)+POST(stored in Body) params into one unified hash. IMO it's cool and awesome to use - "params" for Rails and $_REQUEST for PHP.
But! As I found out it often confuses mechanism of handling GET requests from others(POST-like - PUT/DELETE/etc).
Same "state-changing" code is accessible via GET either, it is GAA, opening the easiest to use hole: <img src=URL/create_message?message[body]=SPAM>
Playing With Referer & Origin
(related: CSRF afterparty & MUST READ rules )
If you read owasp you should know that Referer has never been a good protection. If user submits form from https:// URL than referer header is omitted due to security reasons - it's known fact. But having https page is a big deal for hacker - very uncomfortable for massive attacks(rapidly banned/reported, expensive certificates).
I found a way(in fact two ways) to omit this header from any page - it is the trick with about:blank.
Monday, April 2, 2012
CSRF examples
Remark: Post is published on April 2(but was expected yesterday) coz Berlin haz no free wifi cause I'm not joking and I figured out that Sunday is the worst day for urgent updates. Well, who cares the date, enjoy:
TL;DR:
I'm trying hard to prove my point that statement "CSRF is only the developers' problem" is not true. I provided some examples and I want you to check them out. I really appreciate any viewpoint at this problem. Thank you for your attention in advance!
Subscribe to:
Posts (Atom)

.jpg)








