Hacker News new | ask | show | jobs
by davesims 5223 days ago
It's an easy mistake to make, but arguably no easier than, for instance, not escaping input strings to guard against SQL injection. IMO it falls to the developer to set protected on vulnerable attributes. This is pretty basic Rails security practice.

EDIT: not 'escaping', but using hashes or formatted strings, etc., you get the idea.

3 comments

I am glad you fixed this in your post btw, but I still think the initial thought of using escaping to solve issues like SQL injection shows the way we think about security is flawed.

In general we tend to see security flaws as programming flaws. In other words, the programmer makes a mistake and therefore there is a security hole. The problem with this approach is that programmers make mistakes all the time.

Certainly it is impossible to take all the weight off the programmer's shoulders. Mistakes will always allow a program to be misused, misdirected, and so forth. However, most security issues are best solved as architecture problems, not as developer problems.

For example input sanitation is generally a bad idea* beyond certain things we should never see in inputs. It's far better to find ways of making the input safe to the database and to the web interface that doesn't depend on it being sanitized on input.

* This is because you can only sanitize based on how you want things to go on output, whether you are outputting from your program to the db or to a user interface of some sort. If you sanitize for HTML, you can't use the same info reasonably well for LaTeX, etc.....

So I am of the considered opinion that data should be checked for basic sanity on input (no termination sequences in the middle of input strings, etc), and escaped on use or output. If you have a framework to do this, then you centralize that logic so you don't have to think about it every time. This drastically cuts down on things like XSS, SQL Injection, and the like.

This sort of thing again strikes me as something the framework should prevent. That's not necessarily a flaw of Rails if you use Rails as a toolkit for your own application frameworks. However, it is an architectural flaw, not a programming mistake.

I'm not a Rails/Ruby user but any decent database abstraction layer or ORM should be using bound parameters for all literal values. "Escaping" of SQL strings is best left to the database driver.
You're correct and Rails does do this (handle parameters in such a way as to prevent SQL injection attacks), however it is always possible to circumvent these protections and code things up in such a way (concatenate your own raw SQL string and push it through) as to shoot yourself in the foot.
Or you could disallow raw SQL strings and always construct programmatically (e.g. building ASTs). All of these recurring holes are due to bad design, period. Imagine if your microwave manufacturer said "ultimately it's up to the consumer to avoid irradiating himself". Nobody expects you to be saved from sticking a drill into your face, but nor should it electrocute you by forgetting to do something.
This kind of sums up the point of contention.

Rails, by default, does things like escaping input and output strings, CSRF protection, masking password fields in the logs, etc. So why doesn't it do the same with attribute assignment?

I'll take a guess and say it's because it's not possible to magically generate that code. If I wrote a code generator, there's no way that program could know which attributes should be accessible. The only way to get a scaffold to work out of the box is to require some user configuration or allow all attributes to be modifiable.

It's a case of ease-of-use trumping security.

As homakov suggested, you could at least define *_id attributes as "protected" by default. Only being able to change attributes on your own records probably causes a lot less grieve.