7

In addition to scanning user uploaded files, I would also like to ensure that forms for user profiles, comments, etc. cannot be misused to submit malicious script. What are some known good methods of doing so? Should checking for script injection attacks (XSS and SQLi) be done client-side or server-side?

I have checked a few security-related modules in NPM, but they mostly seem to concern the security of other modules, and its possible I have missed something useful.

One way I am aware of is to strip out all HTML tags, but I think it is a bit heavy-handed as well as probably not effective in all cases.

4
  • 2
    Client side = no security at all. Commented Aug 17, 2015 at 11:06
  • 4
    Please read OWASP. Commented Aug 17, 2015 at 11:07
  • Are you using a template engine to generate your html? Commented Aug 18, 2015 at 21:35
  • At the moment, no, but it will be the case shortly. And as to which engine, that's not been completely decided yet (the security discussion comes first); mustache/handlebars are currently being considered. Any other suggestion is welcome too.
    – ahron
    Commented Aug 19, 2015 at 3:59

5 Answers 5

2

SQL

Protection against SQL injections is done using prepared statements. Generally speaking, it is best practice to avoid manual concatenation of user generated strings in SQL statements.

Instead use the ? annotation and provide the input string as a parameter. The driver makes sure to block any SQL injection attempts, as well as unexpected user input.

MySQL example -

PreparedStatement ps = connection.prepareStatement("INSERT INTO tbl VALUES (?)");
ps.setString(1, "'abc'); TRAUNCATE TABLE users; SELECT (1");
ps.executeUpdate();

The injection attempt will fail.

XSS

You can HTML escape user generated strings or just replace < with &gt; and > with &lt;, before sending it to the client or when writing it to the database.

Also, check out the Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet guide.

7

Stripping out HTML tags is not a sufficient approach to protecting yourself from XSS. Consider the following input:

<scri<script>pt>

If you strip out the <script> tag, another script tag is created. This is just one example - there are many other attacks that could be used.

You should look into protecting yourself from XSS on the server side - this way users do not have the ability to modify/bypass your client side code.

Protecting yourself against XSS is totally doable, but you should make sure you are using the correct approach. As usual OWASP's instructions on how to protect yourself is probably the best way to go.

1
  • Thank you. It (OWASP instructions) seems to deserve a very close and careful look indeed. If I understood correctly, the guidelines are mainly best practices to be followed while coding, and a couple of suggested packages. I was wondering if there was some tool to test existing code against those guidelines...
    – ahron
    Commented Aug 17, 2015 at 16:49
2

There are two main methods that are commonly discussed when dealing with user input. These two methods are validation and sanitisation.

Both of these should be most definitely done on the server side. Client side protections will not prevent attacks such as cross-site scripting or SQL injection.

In particular, I think you're talking about cross-site scripting attacks. It seems that this node module (https://github.com/theSmaw/Caja-HTML-Sanitizer) may be suitable for what you're trying to achieve.

Stripping out all HTML tags is not necessarily a great idea. This is because event based cross-site scripting may still be possible. For example:

<a href="/yourprofilename">yourprofilename</a>

If the user has the ability to change the yourprofilename section, consider the following input:

" onfocus="prompt(document.location); autofocus"

This would turn the link into this:

<a href="/" onfocus="prompt(document.location);" autofocus">yourprofilename</a>

This would trigger cross-site scripting without the use of HTML tags.

1
  • Many thanks! I had a look and will check out in detail the Caja HTML module. By the way, I was asking about for xss as well as injection (there was the injection tag). Would you mind throwing some light on that too?
    – ahron
    Commented Aug 17, 2015 at 16:44
0

Many of the answers now refer to unmaintained packages. Caja seems to be semi-abandoned is browser side and its node port (node-google-caja) is formally unmaintained. express-validator is fine but there's a fair amount of heavy lifting you have to do (i.e. figure out which types of sanitisation you want to carry out which will require security research).

The answers above seem to suggest rolling out your own but will require a fair amount of a study so perhaps try DOMPurify. This is actively maintained (update 1 hr ago as of writing), it has 60 contributors and is supported extensively.

For SQL injection, I would suggest using knex which automatically escapes your SQL. Also, if you have the option to constrain your input so that your well-meaning users don't need to think then you should be able to validate your data more simply. Ideally, the purpose of your inputs should be focussed so that you don't have the risk of your sanitisation messing up the user's content.

Sanitise on the browser so you can show the preview the content, then also sanitise it server-side.

-1

Try out the npm module strip-js. It removes all JavaScript code from some HTML text by doing the following:

  • Sanitizing HTML
  • Removing script tags
  • Removing attributes such as "onclick", "onerror", etc. which contain JavaScript code
  • Removing "href" attributes which contain JavaScript code

https://www.npmjs.com/package/strip-js

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .