Security
Important: Security and Secure Coding is a much bigger topic that I can cover here. (Or, in fact, much bigger than I am qualified to cover.) * Recognize my limits, and don’t assume you know more than you think you do. * Make friends with an expert.
Code injection
- Keep code and data separate.
- Don’t allow user input to become executable code.
- If you come from a C/C++/Java background, this may sound trivial. But, in the world of scripting languages, it is frighteningly easy.
- Consider the
expressMVC
example.- Enter the following as a description: `You should sanitize your input.
- Notice that you see the tags when you show this new toy.
- Now change
<%=
to<%-
intoyShow.ejs
. - Notice that we can see the formatting.
- That may sound cool; but, edit it to forget the closing tag.
- Now, edit it to include
<img src='https://cis.gvsu.edu/~kurmasz/Images/buzz1.jpg'>
- What if that image src was
https://evil.com/evil.php?evilParameters
- Now, how about
<script>console.log("Uh oh")</script>
- Can you see how this is a bad idea that could get worse?
- Rails sanitizes output by default
- to override, append
.html_safe
to string
- to override, append
- Another approach would be to sanitize the data as soon as it comes into the app.
- See
express-validator
package for JavaScript Express - Sanitizing input for Rails seems less necessary since the output is so well sanitized. But, it could still be a good idea in certain situations.
- Think carefully how/when/whether you want the data sanitized. Turning
<>
into<>
won’t have the intended effect when using<%= %>
in EJS.
- See
- Beware of calls that will “execute” strings
- JavaScript’s
eval
–eval('console.log("Hello, there")')
; - Ruby’s
eval
- Never allow user input into
eval
calls. - Better yet, avoid them altogether.
- JavaScript’s
SQL Injection
- SQL Injection is another way user input can sneak into executable code.
-
Consider this line of code:
sqlStmt =
SELECT * from Authors where name="${nameInput}"
; - Now imagine that
nameInput
is pulled directly from an HTML form and containsFred"; DROP TABLE Authors; SELECT * from Authors where name="
- The resulting value of
sqlStmt
will beSELECT * from Authors where name="Fred"; DROP TABLE Authors; SELECT * from Authors where name=""
- The user has managed to inject his own SQL code into your application.
- In other words, the user was able to run an arbitrary SQL statement.
- Protections
- Sanitizing input (e.g., escaping quotation marks, semi-colons, etc.)
- SQL libraries that will only run one command per call (unless overridden)
- SQL libraries that contain query builders.
- Active Record (used by Rails) lets you write queries this way:
Client.where(first_name: nameInput)
- These query builder libraries presumably check the parameters carefully and/or are structured in such a way that malicious parameter values generate invalid SQL.
- Active Record (used by Rails) lets you write queries this way:
- https://xkcd.com/327/