Writing Secure Code

Overview

While Vanilla has a bug bounty program, which has been incredibly helpful in finding and patching numerous security issues, it is important to write code that is secure from the start. This is a working document that represents best practices for writing secure code in Vanilla.

XSS (General)

One of the most common vulnerabilities reported is XSS (Cross Site Scripting). XSS is the injection of a malicious script into a trusted or benign site. This generally occurs when user inputs are not properly sanitized.

User content may only be placed in the following positions and requires normal escaping for both:

<div someAttribute='$HERE'>$OR_HERE</div>

There are a few exceptions to this.

  • User content MUST NEVER be inserted into the contents of a <script> tag.
  • User content MUST NEVER be inserted into the contents a javascript event handler attribute. This includes but is not limited to
    • onclick
    • ontouch
    • onkeydown
  • User content MUST NEVER be inserted into the contents of a <style> tag.
  • User content MUST NEVER be inserted into the contents of a style attribute.
  • User content that is inserted into an href attribute requires additional escaping. See Escaping links in JS and Escaping links in PHP for more details.

XSS (Javascript)

For Javascript normal escaping SHOULD be provided by React which escapes all attributes and contents by default. Even small javascript components SHOULD be written as a React component and mounted using ReactDOM.render() from the react-dom library. The overhead of mounting multiple components is negligable.

If React cannot be used for a particular view (and it likely can), the escapeHTML() function from @dashboard/dom should be used for escaping.

href attributes containing user input MUST be escaped using one of the following two methods in addition to normal escaping:

  • sanitizeUrl() method in @dashboard/utility - For entering user input that is expected to already have a protocol, such as use generated link.
  • formatUrl() method in @dashboard/application - For generating a vanilla link from a path. One case where “user-generated” content may be used for this is constructing a url from query parameters in the URL such as a target.

Additional rules

  • The React property dangerouslySetInnerHTML MUST NOT be used.
  • If dealing directly with DOM a Element - innerHTML and outerHTML MUST NOT be used.

XSS (PHP)

Regular escaping of user content SHOULD be done using the htmlspecialchars() function.

href attributes containing user input MUST be escaped using one of the following two methods in addition to normal escaping:

  • Gdn_Format::sanitizeUrl() - For entering user input that is expected to already have a protocol, such as use generated link.
  • url() - For generating a vanilla link from a path. One case where “user-generated” content may be used for this is constructing a url from query parameters in the URL such as a target.

Additional rules

  • All HTML attributes MUST have surrounding quotes.
  • User content MUST be escaped before being inserted into HTML content. This SHOULD be done inside of the view and NOT in the data layer.

Cloud Hosting

We believe that online communities should be intuitive, engaging and true to your brand. Vanilla allows you to create a customized community that rewards positive participation, automatically curates content and lets members drive moderation.

Learn More …