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
- 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.
Escaping links in JS
href
attributes containing user input MUST be escaped using one of the following two methods in addition to normal escaping:
- Use
<SmartLink />
instead of `<a />`. sanitizeUrl()
method from @vanilla/utils
.
Additional rules
- The React property
dangerouslySetInnerHTML
MUST NOT be used. - If dealing directly with a DOM
Element
- innerHTML
and outerHTML
MUST NOT be used.
XSS (PHP)
Use Twig Templates
Vanilla has full support for twig templates. These should be used whenever rendering HTML from PHP. Twig will automatically escape most content.
Escaping links in PHP
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 a user generated link.
User Content
- User content that may contain HTML should use the
FormatService
. This can be easily access using Gdn::formatService()
. - User content from simple form elements, like
input
should be escaped in the view layer using twig, React or htmlspecialchars
.
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.