14 ms·
CSRF in Doorkeeper OAuth2 gem
- Rygu 12y agoThis is why it's increasingly important to not only test your code, but also develop useful vulnerability scanners. I know, it sounds impossible to write a complete vulnerability scanner, but many companies would pay for such a thing. Existing solutions are either lacking or way too difficult to operate.
- homakov 12y agoThat's true, checking all `rake routes` for proper CSRF handling is a trivial job but would help to spot the bug in 5 seconds.
- sasas 12y ago> Existing solutions are either lacking or way too difficult to operate Give Netsparker[1] a go.. couldn't get much easier then this! [1] https://www.netsparker.com/ https://www.netsparker.com/
- lmm 12y agoAny sufficiently advanced vulnerability scanner contains an contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of a type system. Seriously, the solution isn't better scanners or better tests, it's better languages. Make whether something is taking a potentially-destructive action part of its type, and then the compiler ensures that all such routes are appropriately protected; you can do this today in e.g. Spray (which I'm using in production, so this is not some ivory-tower theoretical solution).
- michaelmior 12y agoAssuming the application code is completely secure, then that's a big part of the problem solved. But there's also the application server and any other services running on the machine hosting it.
- lmm 12y agoSo what, we give up entirely? Most times I'm aware of a site being hacked it's been through a hole in their application code, not the stack they're running on top of.
- michaelmior 12y agoI was not suggesting we give up entirely. I'm just pointing out that it isn't a complete solution of the problem. But I agree that application code is probably the bigger problem to solve.
- dsacco 12y agoThis suggestion eliminates bugs that are introduced by unsafe typing, sure. But race conditions, logic flaws, misconfigured tools and almost every class of web vulnerability wouldn't be eliminated just by implementing this. Most vulnerabilities do not derive from a single faulty tool or framework, but the incorrect combination of several (faulty or not!) tools over a sufficiently large attack surface.
- lmm 12y ago> This suggestion eliminates bugs that are introduced by unsafe typing, sure. But race conditions, logic flaws, misconfigured tools and almost every class of web vulnerability wouldn't be eliminated just by implementing this. How often are security flaws a subtle, complex thing that couldn't have been caught by a sensible type system? Almost all of the flaws we hear about, at least here, are the really simple dumb mistakes that a better language absolutely would have caught.
- kofalt 12y agoAgreed. I try to explain sometimes that I'm merely tired of experiencing the same problem, over and over, for years. I would like to experience the next problem, please. If only for variety's sake.
- rudolf0 12y agoDo you mean a language with a very strong type system like Haskell, where you could create a web framework in which things like user input have different types associated with them? Those can offer some real advantages by never mixing untrusted input with page output and various calls to other systems. But you don't get a lot of web application security advantages when you compare, say, Python and Java. Of course, a very weak type system like PHP's can definitely introduce additional security flaws.
- jfoutz 12y agoA common pattern (at least getting there) in Scala/F#/Haskell is to have paired types, UserInput and ValidatedUserInput. All the business logic requires the Validated kind. A programmer can be certainly be lazy and just return the supplied value, but this is a conscious choice to do the wrong thing. You can't accidentally forget to validate form parameters. It won't compile. This is pretty easy to do in Java. On the weaker side, I would assume php and python have something like perl's taint mode. It's such a simple thing and it avoids so many xss problems.
- JoachimSchipper 12y agoTypes are not that useful for security - it's as easy to create a MutatingController in Ruby as it is to concatenate some strings containing SQL and a string containing raw input in Haskell. Better typing can help, and Ruby programs are more likely to be "stringly typed" than Haskell programs in practice - but the difference is a lot more subtle than one might expect.
- mej10 12y agoThe issue is that Ruby can't give you the tools you need to catch such things before runtime. Haskell can.
- michaelmior 12y agoI think it is impossible to write a complete vulnerability scanner. If by complete you mean that your application should be guaranteed "secure" after running the scanner. Security has always been a moving target. However, I've heard great things about the job that Acunetix[0] does. [0]
- acangiano 12y agoHave you looked at IBM AppScan? It does a pretty good job.
- dsacco 12y agoThere is a fine line between automating fully-automatable penetration testing tasks and automated scanning. Unfortunately, there is a very idealistic drive to feature-creep penetration testing tools away from "useful when used by a professional" to "half as useful when used by anybody and full of false positives." The real solution is not more or better security software, but rather more secure coding practices. People generally don't accept this idea, but the state of software security is such a moving target that no amount of automation short of strong AI will find every bug. The onus is on developer education.
- danielweber 12y ago> "useful when used by a professional" to "half as useful when used by anybody and full of false positives." Where I work we have a desire for both. We want developers to be able to scan their own code -- preferably automatically as part of a CI process -- for things that are clearly wrong, without needing to be appsec experts, and clear out a lot of the low-level brush. We also want complex tools that are used by appsec to be able to do their jobs faster. This is timely since I'm about to do a search for tools for this. I'd love, for example, a way to see the permissions for all lines returned by "rake routes", whether those are resolved by CanCan or where CSRF is disabled or whether it's been overruled by some skip_authorization_check.
- miah_ 12y agoOr use mutation testing: http://en.wikipedia.org/wiki/Mutation_testing http://en.wikipedia.org/wiki/Mutation_testing
- deleted 12y ago[deleted]
- getsat 12y agoLooks like it was fixed a week ago? https://github.com/doorkeeper-gem/doorkeeper/commit/c1b5c45e2c42c0191ca9f12a2836e31ee1a8de57 https://github.com/doorkeeper-gem/doorkeeper/commit/c1b5c45e...
- cpg 12y agoOops, I deleted the comment. I had filed a bug[1], without realizing 2.0.0 was released a few hours ago with the fixes in it. https://github.com/doorkeeper-gem/doorkeeper/issues/524 https://github.com/doorkeeper-gem/doorkeeper/issues/524
- andrewsomething 12y agoRight. When Sergey Belove originally reported this to DigitalOcean, one of our engineers reported and fixed this in upstream Doorkeeper.
- rplnt 12y agoIs there a browser extension (or browser) that could either open each new tab "clean" (no cookies or anything) or even better lock it on the first domain visited? Example: I open a new tab with example.com, and with this a new session would be created which only contains data relevant to example.com. Anything I open later on in this tab won't see anything else. I can always open link in a new tab to start a "relevant" session (though that would require browser that can work with tabs, i.e. not Chrome).
- cornewut 12y agoYou can disable third-party cookies in most browsers.
- eli 12y agoChrome supports multiple users pretty well, but it's per-window not per-tab. (I think that might be better anyway, it seems like it would be easy to lose track of which tab is logged into what)
- jrochkind1 12y agoDo you just mean the "incognito" feature, or is there another way that Chrome deals with "multiple users" (multiple sets of cookies?), cause if there is I'm interested!
- saulr 12y agoChrome added the concept of different user profiles recently, there's more info here: https://support.google.com/chrome/answer/2364824?hl=en-GB https://support.google.com/chrome/answer/2364824?hl=en-GB
- eli 12y agoIndeed and once you enable it, it's very easy to switch between profiles. It's one feature I miss since switching back to firefox.
- tutec 12y agoHey there! You may upgrade to 1.4.1 or 2.0.0 to avoid this. Thanks for posting.
- Gepsens 12y agoAnother show of the blatant amateurism of the Ruby community. I don't even count the number of pull requests on gems considered cannon I've had to do since I started coding in that language.
- skrebbel 12y agoOh boohoo. Security is difficult, not just in Ruby.
- matthewmacleod 12y agoStop being a dick. Security problems exist in any language, and I've seen no evidence that they're any more prevalent in Ruby projects than elsewhere.
- alinajaf 12y agoI think you probably mean canon.
- skj 12y agoNo, cannon. Like, really solid and made out of explosion-resistant iron.
- alinajaf 12y agoAh, sorry, my mistake.
- wlll 12y agoPretty sure he meant "canon" in that context. 1) A general law, rule, principle, or criterion by which something is judged 2) A collection or list of sacred books accepted as genuine (http://www.oxforddictionaries.com/definition/english/canon http://www.oxforddictionaries.com/definition/english/canon)
- slater 12y ago
- boracay 12y agoAs long as we keep treating security as a purely technical problem the state of software isn't going to improve significantly. Responsibility tends to catch up with things. It's mostly a question if it's going to benefit software or not.
- pvnick 12y agoI disagree. Preventing vulnerabilities is not primarily an "attitude problem." Writing code is hard enough as it is, and writing flawless code that can withstand hostile attacks is really hard. Odds favor vulnerability existence, and when bad ones are inevitably discovered in production systems people always claim the whole process is broken. That being said, this one is pretty bad.
- boracay 12y agoThe demand for "safe"[0] software is going to reach critical mass sooner or later. The question is if it's going to be solved by good tools, processes and education or app stores, insurance ratings and regulation. Software isn't much different from other types of infrastructure.
- ploxiln 12y agowell, except for the rate of change
- deleted 12y ago[deleted]
- VLM 12y agoCan someone provide a better "forwardable" explanation of CSRF than the wikipedia version of "let me f-ing google that for you"? I already unsuccessfully searched for a XKCD treatment. Something I can forward to non-devs not written at dev level. Also no videos (who has time for that?). It sounds like a graphics arts type project, like a xkcd topic, so I guess something like that is what I'm looking for. The wiki explanation is pretty good, just curious if anyone has anything better for non-technical-ish people.
- madgar 12y ago"It's expected that I can send you a link to facebook.com. But it's not okay if I can send you a link that immediately deletes your account."
- grimtrigger 12y agoIsn't this easily mitigated by making all request that change state (update data in any way) as post requests?
- defen 12y agoThe way CSRF works is that I put a form on evil.com that submits to example.com. If there's no CSRF protection, example.com will accept that form submission as if it had actually come from a page on example.com. GET/POST has nothing to do with it.
- adamdoupe 12y agoNo. Check out the example in the article, an attacker can make your browser submit a form with a POST request using JavaScript. It's slightly harder to exploit, as the attacker can't just send you a link to facebook.com, but they can send you a link to example.com which has the form and uses JavaScript to submit the form.
- danielweber 12y ago<form method=POST action=FACEBOOK><input name=DELETEMYACCOUNT></form> <script>document.forms[0].submit();</script> (The above code may contain bugs.)
- afiedler 12y agoThis is pretty bad, but I believe it is only possible to get an access token if you also allow malicious/non-trusted users to either create new OAuth client registrations (`Doorkeeper::Application` models) or modify the redirect URI of an existing OAuth client registration. The reason is that the access token is delivered over a redirect, not in the response to the form POST. Doorkeeper does check for a valid redirect URI.
- Synthpixel 12y agoWhile I believe that allowing CSRF is terrible practice, as a user of Doorkeeper, I think the problem here is Digital Ocean's atypical usage of OAuth2. When you request an access token for a resource owner in OAuth2, you are supposed _actually authenticate_ the owner. According to the OAuth2 spec[1], username and password are REQUIRED fields. Allowing clients to generate tokens based off of cookies is reckless. Useful CSRF exploits depend on the server to trust session data to authenticate client actions. OAuth2 is designed for allowing external (third-party) applications to communicate with you. Cross-site requests are an expectation in OAuth2. If you ignore the spec and skip proper authentication, you're in a bad spot anyway. [1] https://tools.ietf.org/html/rfc6749 https://tools.ietf.org/html/rfc6749 (page 37 & 38)
- diafygi 12y agoI can't name a single OAuth2-enabled website that does this. Facebook, Twitter, Dropbox, Google, LinkedIn, ... They all let you approve if you are already logged in.
- Synthpixel 12y agoI can say that recently LinkedIn has asked me to reauthenticate on multiple occasions in the same session. I've had the same for Google but I have not tried recently. I'm aware that Twitter and Facebook allow you to do so, but I propose that none of the above give scopes without authentication that allow you to perform actions that charge an account. That said, I agree that some of the giants are fine with using cookies for auth in OAuth2. And while that indicates that this is a possible use case, OAuth2 is capable of being used in many ways and Digital Ocean's usage still doesn't make much sense.
- jfarmer 12y agoGitHub and LinkedIn do this, I believe.
- ewang1 12y agoUsually those implementations redirect the user to a separate authentication system. OAuth2 only handles authorization and not authentication. Upon successful authentication, the user gets redirected back to the OAuth2 request which then generates the authorization code. When the user is already logged in via a cookie set by the authentication system (i.e. an existing valid session), they don't get prompted for a password again; the authentication system will simply redirect to the OAuth2 request url. The typical OAuth2 implementations shouldn't be reading the authentication cookies directly. The "password flow" in OAuth2 is really a special case for those who want to bypass the separate authentication system and use OAuth2 directly for both authentication and authorization.
- mcbetz 12y agoEven if it is critical for some, for me it feels exactly how open source works: someone uses an application in a way that was not intented or thought about. And it turns out, that there is a problem with that approach. Someone will blog about it, write a bug ticket or send a pull request. And gone is the problem and the application got better. That's applied wisdom of the crowd.
- Stefan-H 12y agoAm I missing something? While there does not seem to be a reason to allow CSRF here, doesn't the fact that you need to have a client Id and client secret for the oath endpoint make it so that this is a non-issue? https://github.com/doorkeeper-gem/doorkeeper/wiki/authorization-flow https://github.com/doorkeeper-gem/doorkeeper/wiki/authorizat... I don't see a way to get the access token without having the client ID and client secret.
- homakov 12y agoyou just need to create a client. Then you will have ID+secret. Most providers allow anyone to get them