I propose ALWAYS specify HTTP verb for action - because you always know which way controller#action should be used. If you dont - you are doing it wrong.
Russian speaker here - moved to US when I was ten, haven't had much opportunity to practice. Your English is much better than my Russian, so don't worry about this too much :P
Also, could you tone down the site theme? The scrolling sidebar/topbar etc is really buggy and keeps getting in the way of your text. I'd suggest just using jekyll or something with Github pages or maybe just run your own HTTP server to serve it up.
They're not new attact vectors but I enjoy Egor's posts and call outs. If you're a web dev making these mistakes then you need to take the time to learn about basic web security. You can't count on frameworks to abstract it all away for you, you have to understand how it works.
The same CSRF rules apply to GET and POST requests. If you're using proper CSRF protection it doesn't really matter if you do a GET or POST. The only real difference is that GET requests will be visible to every piece of hardware between the user and your server whether you're using SSL or not and will most likely be logged. Also you can upload files via POST.
While it's easier to make users send harmful GET requests by putting the URL in an image you can simply use JS to POST a hidden form. Thinking POST is inherently more secure is a false assumption. Both are equally vulnerable to CSRF.
I am not 100% convinced. I would have thought GET would be slightly less secure than POST. You use the JS example. If I were running NoScript or something where JS didn't work someone could use <img src="follow?username=value" > and it would run. While if it used POST, it would be slightly more secure (for a user being exploited).
It's entirely possible I mis-understand the whole thing and please correct me if I am wrong (and explain why).
you just rewrote my post in other words. Of course I know how to send POST and I call this a little bit "new" vector only because even good developers(check showcases to make sure) use 'match' and forget to specify :via. And it looks OK to them because they miss the point - all GET requests skip protect_from_forgery filter in Rails - this is how it works.
>If you're a web dev making these mistakes then you need to take the time to learn about basic web security.
Honestly, I didn't say it loudly but I meant it. Not understanding GET/POST makes person low skilled dev.
> all GET requests skip protect_from_forgery filter in Rails
Now that's interesting, I wasn't aware of that. It makes sense due to the Rails convention being GET is only for fetching data. So this does make GET more insecure than POST for Rails.
I think the fact that Django's url mapper doesn't make it easy to dispatch based on the method means that Django wouldn't score to highly against this particular issue. It's easy to put
if request.method not in ('POST', 'PUT', 'DELETE', 'PATCH'):
...
at the top of every method (or use a decorator), but it'd definitely be nice if this were part of the url dispatcher.
This is true, but at the same time Django doesn't make it easy to mix up get and post params. Calling request.POST['param'] will raise an exception on a GET request.
Finding rails issues and then saying "they kinda sorta apply to Django" isn't as interesting as finding real Django issues.
Thanks for this information! Really, it is $_REQUEST as in PHP.
To yummyfajitas - your message is 50% trolling. Will you allow me to troll a little bit? I used django and scrapy few years ago and despite the fact it was better than PHP I would not even dare to compare it with Rails. Rails is that superior I don't even have words to explain it :D Conclusion: I'm not interested in Django and its bug because I love rails and wanna make it more secure anyways. Sorry, but Django is way less convinient to use. Security is another story though.
Sorry, I didn't intend to sound like I was trolling, my comment "I'm feeling very superior" was intended to be facetious.
Also, if you ever manage to put into words why you prefer Rails, I'd love to read it. Django and rails seem pretty similar to me, but I didn't put much effort into learning rails. But maybe I'm just experiencing the blub paradox.
So I don't think yummyfajitas was trolling, but he obviously likes Django. Like him, I like Django as well, but I happen to think that a healthy criticism of any popular framework is worthwhile. I think it's telling that AFAIK all more recent python frameworks bake in method dispatching to the url dispatcher.
It's not in the URL dispatcher in Django, but the class based views have separate methods that are called depending on the HTTP verb such as get(), post() etc.
It was a problem with the older function based views, and there was a lot of boilerplate to ensure the correct HTTP verb was being used.
Would love to see some more information on best practices for routing. I've always used http://guides.rubyonrails.org/routing.html as a go-to resource on routing, and it uses 'match' statements throughout. Is the suggestion here to just change all match statements to the intended REST verb?
You should be using resource-based routes if you've already got the RESTful controller thing going.
The match statement is good for the occasional odd cases, but it has an :via option that can be used to restrict which HTTP actions it is allowed to match.
Fix - not :as but :via. Using match :via => :post is worse than just post 'data', it is obvious btw :)
and there are almost no odd cases in fact. I would propose special route named "not_found" or "default" like route to be called if no routes found. Nice idea IMO, what do you think?
I had to use match when moving from Rails 2 to Rails 3 and parts of the route did not match the controller at all. But I think it was mostly because the upgrade plugin recommended it.
The only thing I don't like about the Rails routing guide is how much it talks about having a default route of `match ':controller/:action/:id'`. I would still use `match`, but any actions that are meant to be posts should add `:method => :post` to them. And ideally use `resources` where ever it makes sense.
Right, so what this post is saying is that for the most part the evil is in using this default route, leaving open controller actions that should only be accessible as posts. Will have to look more into the docs, but it's good to know that the methods specified in the guide have some caveats.
Which is the "correct" way to do verb-constrained non-resource routes. Not ever routing the wrong verb is even better than checking it in the controller.
call me a bad coder but when I used rails 2.3 I had never seen it in production code.
Ok, then you're a bad coder. All Rails applications I've ever worked on had those checks and the documentation for Rails made it pretty clear that verify :method should be used for non-GET requests.
Anyways rails 2.3 had no csrf protection
You really need to check your facts. Rails has had protect_from_forgery since at least 2.2 and it was enabled by default in ApplicationController. Rails < 2.3.10 did not do the verification for AJAX requests, but this was changed in 2.3.11.
Appreciate your info! Really, I messed with facts - in 2011 it was made for AJAX :) You are right!
Ops FIX: you should call bad coder not me but people whom code I had been reading years ago.
And anyways burke is right:
>Supposed to be, but rarely was. Throw a bunch of new programmers at a framework, and insecure-by-default becomes insecure.
btw verify method: :post is nice to have but obviously uglier than current routes.rb DSL.
Security aside, the catchall routing directive is a maintenance nightmare. The router is precisely where you should catch buggy routes, as well as document valid ones so they come up in rake routes.
Instead of writing:
He's suggesting you write: ?Sounds good to me.