Prev | Current Page 217 | Next

Brad Ediger

"Advanced Rails"


The best way to protect against malicious user input making it to the shell is to use
the multiparameter version of system, only passing the command name in the first
parameter. The subsequent parameters are shell-escaped and passed in, which makes
it much harder to slip something into the command line unnoticed:
def svn_commit(message)
system("/usr/local/bin/svn", "ci", "-m", message)
end
146 | Chapter 5: Security
The message passed in to that method will always be the third parameter to svn, no
matter what kind of shell metacharacters it contains.
Object Tainting
Tainting is an idea that came to Ruby from Perl. Because data that comes from the
outside is not to be trusted, why not force it not to be trusted by default? Any data
read from the environment or outside world is marked as tainted. Depending on the
current value of a special Ruby global, $SAFE, certain operations are prohibited on
tainted data. Objects may only (officially) be untainted by calling their untaint
method.
This is a good idea that, because of implementation details, has not gained much
traction in the Rails community. It can become a pain to deal with every piece of
data that was derived from user input. There is one Rails plugin, safe_erb, which
leverages tainting to ensure that all user-supplied data is HTML-escaped before being
displayed again. Request parameters and cookies are tainted upon each request, and
an error is raised if tainted data is attempted to be rendered.


Pages:
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229