Ruby on Rails 4.0.0.beta1 released
weblog.rubyonrails.org
weblog.rubyonrails.org
Please note that this is a beta, not an rc, so some things may be a bit wonky. Please file an issue on GitHub and I will do everything I can to help you help us iron out all the kinks.
❤❤❤
(Also, I am on a plane and my battery is almost dead, so I may drop out of this thread soon. Ill read it when I'm home.)
(The security team is a subset of the core team, in accordance with least privilege and all that.)
Thanks for contributing Rails 4.0 - I'm excited to try it out, in particular the new caching looks great.
What would you like to have changed here? The methods work fine as long as you do not explicitly embed a user-supplied string in a larger SQL fragment.
Order.calculate(:sum, params[:column])
I've just checked in Rails 3.2.12 and this is still possible, haven't checked against Rails 4.0. If I pass in: http://localhost:3000/adverts/1?column=id) FROM users WHERE name = 'Bob' SUM(id;And do a simple sum in the controller:
sum = Advert.calculate(:sum, params[:column])
# or
sum = Advert.sum(params[:column])
I get: SELECT SUM(id) FROM users WHERE name = 'Bob' SUM(id) FROM "adverts"
Which is not good as it is injecting sql - with judicious use of sql comments etc it could probably be made to execute any sql statement (apparently it does on sqlite with this particular test, but it fails in postgresql which I tested with). Other queries work with psql though [deleted example and reported]. I've reported this with a working example of sqli just in case it is an unreported problem.Now the intended use of sum, count etc is to deal with symbols chosen by the programmer, but a naive implementation of say an admin form for summing some record attributes might use a param from a form, and pass that in to the sum method for column name, just as they might use params[:id] with find. I think Rails should deal with that.
Also the example given of User.exists? params[:id] is probably commonly used, but vulnerable to manipulation of results at the very least.
I'm not the original author of this page (which is already public and probably has been for some time), and am aware this is not an appropriate place to report bugs, but it would be reassuring if the Rails team looked at this link and fixed anything which is dangerous like the usage above.
IMHO all rails ActiveRecord methods should guard against sqli as much as possible, not just the commonly used ones, and if they don't currently it needs to be fixed.
If you actually learn Rails and aren't just piecing things together until it works, it isn't a secret that most methods accept raw SQL as the first argument, with optional placeholders for expected values, so if you want escaping you either pass an array ["col1 = ?", params[:val1]] and the values will be quoted or you have to quote explicitly. Methods like .where(), .joins(), .having(), .order() etc. would be crippled if they escaped this first string argument so I am not sure how a "fix" should like here, you have to demarcate somehow which input is trusted and which is untrusted and those methods are 95% of the time used to deal with trusted input.
This kind of defensive attitude isn't helpful, I'm quite familiar with Rails since 1.x thanks and want to see it improve, particularly on security issues. I use it every day. I've only quickly looked at this page but as it contains many common antipatterns, and some straight up vulnerabilities, I think it'd be worth fixing everything on it if possible. Having read the above list I'm starting to think I'd be best to convert all params explicitly to the expected type before use, as Rails accepts many varying types for params and this has increased the attack surface. I'm actually pleased there is a spotlight on Rails security right now though as things will improve - much better than no-one but blackhats being interested.
I highlighted two vulns from the list, one in Model.exists? which is expected to take an id param straight from user input, and one in Model.sum,count etc which is more serious but less likely to be encountered as it requires using a column name straight from user input (not advisable). Neither of them take sql as the first argument, one is intended to be an id, and the second a column name. While the above example is a misuse of sum in my opinion, I think Rails should still be a good citizen and deal with it, given the common pattern of Model.query(params[:xxx]) which can be very useful and which many people will pattern their other usage on - any method which takes params directly and not raw sql (i.e. not the ones you list) should I feel be protected against sqli, even or especially if it is not a commonly used one.
Taking security seriously (even if it means inconvenience or working around common user errors) is not FUD, it's a worthwhile process and one which Rails should continue with.
If there is anything I can do to make this more clear, please let me know. Documentation is something I enjoy.
Look for places the code might not currently be clear, and try to improve clarity without changing behavior.
Once you've done that kind of thing, sky's the limit as far as I am concerned. I'm working on understanding and improving the parameter parsing behavior at the moment.
That's one of the only things I'm frustrated about - I wish there were a clearer list so that I didn't have to troll for tasks that need doing, or ask a core member on IRC/campfire
One of the most common places where that's true is in the ActiveRecord issues, which are about half of the open ones: https://github.com/rails/rails/issues?direction=asc&labe...
Even just making a little Rails app or script that re-produces the bug would be helpful. Writing a test case that's failing would be mega helpful. Fixing the bug would be incredibly helpful. :)
Once you have that installed, you basically don't have to worry about dependencies that you need to bootstrap the Rails test suite.
I suppose it's a lot less of an issue now anyways, but in 3.2, using fetch with memcache with raw objects is super gross since you get totally incompatible responses depending on whether an item existed in cache or not.
I personally read every single issue, comment, and commit that goes into Rails. But often tickets come up that I don't know anything about, so I don't say anything. This suggestion is one of them; I'm not mega familiar with that part of the codebase.
I think you meant "cue", otherwise please help a foreigner with this english expression's meaning.. queue onto what?
With external observers, it's not always obvious whether they are enabled or not. Service objects make this more explicit and are easier to test as well.
Personally I just use Backbone and try to structure things in whatever way seems natural. It looks like there's been a lot of work done in integrating Ember.js if you want to look into that.
Backbone for single page mini-apps.
Frankly, I'm a server-side guy, so I prefer that kind of development, but there are advantages to SPAs, and like any good engineer, you should use the right tool for the job. Rails is modular enough that you can do whatever you want, Turbolinks is just a gem, so if you don't want to use it, you can just pull it out of the Gemfile.
If be willing to bet that the less dynamic interaction per page, the less an SPA makes sense. ;)
That said, I can also see how something like Ember gives you a nice way to do API-first development, so even if your site is more static, it could make sense.
As always: It Depends. Don't believe anyone who tells you they have a silver bullet.
Having JS heavy web page will slow down the browsers. That even includes Chrome, you just need a larger number of tabs. On Firefox a few JS heavy site with a slow computer will make your site experience sucks.
Although not a single user would blame the site ( It is always the browsers' fault. ) but to me, most of the time, the less JS the better.
Discourse is pretty fast, but to say 300K zipped JS file is peanuts just doesn't cut it for me ( How about 100K? That is peanuts. ) And again, slow JS execution and loading is something i have zero control of.
The big change is that instead of getting a clean slate every request, you now have one, long-running JavaScript environment. That's where Turbolinks derives its speed from, but it's the biggest change, and this difference in assumption has been where the issues have popped up.
Honestly, I have not followed turbolinks' development very much, so I'd look through the Issues if I were you to get a better idea of what kinds of things have cropped up so far.
> Discourse is pretty fast, but to say 300K zipped JS file is peanuts just doesn't cut it for me
Sure. I think you'd be surprised how quickly you can get up to 300k of assets in a site, though. Plus, you're only fetching it once, it's all cached afterwards. Regardless, as far as I'm concerned, the practice beats the theory. Turbolinks and Ember have both been show to speed up web sites in practice.
Backbone is a pretty slender library, you can pretty much use it however makes sense to you. You could go really hardcore and do a site that's client-side-everything, or you could do hybrid approach like we did.
So instead of having to deal with plenty of small ajax calls you just build an app as it would work in plain HTML and just use turbolinks to leverage AJAX.
Sure it can be very efficient, but it's a terrible default.
When DHH state: > except, maybe, compatibility issues with some existing JavaScript packages
Some ? Don't you mean most ? Even Twitter Bootstrap will leak memory if used in a turbolink app.
When coffeescript is pushed as default, I'm ok, at worst you don't use it and you have a useless gem. But turbolink is harmful if you don't know what you are doing.
TurboLink always replace the whole body, not just part of the page. There's no input focus to maintain. Server side render a page the same regardless of whether it's fetched normally or through TurboLink. Links fallback correctly on JS-disabled client.
This does not seem like a super great idea, like merry-christmas mentioned too much like ASP.NET.
I'll do some reading on turbolinks and see if there's something super I'm missing.
Apparently, even though the browser doesn't re-download the assets, it does re-parse and re-execute all of it. Which makes sense. This is where Turbolinks adds the speedup.
Others mentioned Turbolinks, but they forgot about remote_form_for and friends.
If you _are_ building a full JavaScript application, Ember.js works really well with Rails + ActiveModel::Serializers. There might be some rough patches until Ember hits 1.0 final, but most of the pieces are in place.
JS in Rails had gotten confusing lately, with changes being made over time to supported options and 'golden paths', but insufficient docs on what Rails expected/recommended.
Thanks for working to rectify that!
(I don't use either Ruby, RoR, Coffeescript or Ember.)
> Does all RoRists use CS instead of JS, or is it considered best practice?
It is currently considered best practice to use CS instead of JS, which is why the gem is included in your Gemfile by default. Not every Rails project uses it; Discourse just ported all their stuff to JS, even though they started with CS.
Phusion Passenger Enterprise 4 is also thread-oriented.
Even without this, there are MANY use cases where multi-threaded concurrent request dispatch makes a LOT of sense. For instance, the recent controversy about heroku routing, right?
With MRI or another interpreter with the GIL, you'd want to run one app process per CPU core -- but having each of those processes also do multi-threaded request handling can still even out latency (that is, avoid those awful ~95th+ percentile latencies in the heroku routing debacle), and increase overall throughput.
Especially if your app, like most but not all web apps, is more I/O bound than CPU bound (waiting on DB, disk, or external APIs).
Even if Rails3, though, Rails supported multi-threaded request dispatching IF you had an app server stack that supported it.
In Rails3, you just had to explicitly turn it on with `config.threadsafe!`. Rails4 makes that the default, always on. That's really the only difference. There are at least a few concurrency-related bugs that have been fixed in Rails4 (I'm actually not sure how many), but even Rails3 was officially documented to do multi-threaded concurrent request dispatch just fine. (Actually even Rails 2.2 was!)
Finding a mature, reliable, well-documented app server stack that supports multi-threaded concurrent request dispatch may be harder. I can not say which do and which don't, but there are at least some potential options (including puma, which, if I understand it right, has multi-threaded concurrent request handling as part of it's original core use case).
I AM hoping that Rails4's "multi-threaded request dispatch on by default" situation will make the community pay more attention to this use case, result in more app servers supporting it first-class robustly, and any remaining bugs around concurrency being found and fixed. While Rails3 was documented to support this anyway (since Rails 2.2!), it has been mostly ignored by the community, for some reason.
(Sadly, while Passenger Enterprise 4 will support multi-threaded concurrent request dispatch, the Passenger folks are intentionally reserving this feature for Enterprise, the free one won't)
Try Jruby and Puma.
But what you probably meant with "multiple instances" is "multiple threads". You can't do multiple threads with Unicorn, it's explicitly designed not to handle multithreading. Instead you should use an app server that's capable of multithreading, e.g. Phusion Passenger Enterprise 4 which is hybrid multi-process/multithreaded.
The Phusion Passenger Enterprise 4 multithreaded stack is already being tested or used in production by multiple organizations. We've been using it in production for months without problems.
Also, multithreading does not require Ruby 2.0. Ruby 1.9 works just fine.
I think Rails is great, but this is one area where it's not a good choice.
The only mentions of WebSockets I've seen from people invested in Rails are mostly made of people actually deriding them and passive-aggressively making fun of people that use them or want to (generally in a bunch with MongoDB, Hadoop, Cassandra or other modern big data tools that don't fall naturally in the Rails ecosystem).
But then again, it's not like they have an infinite amount of time to invest into everything and anything and they worked on SSE for Rails 4 on top of shitloads of additional goodies, patched a lot of security issues so overall I'm pretty happy as an end-user.
Edit: aaand steveklabnik knows more about this than me; listen to him.