You are viewing the technical documentation for Sharetribe. If you are looking for our no-code documentation, see our new help center.

Last updated

Sanitizing user-generated content

This guide describes how to sanitize user-generated content to prevent XSS vulnerabilities.

Table of Contents

User-generated content can expose your marketplace to Cross-Site Scripting (XSS) attacks. Therefore, it is essential to take precautions when working with a website that allows users to generate and input content.

By default, React DOM escapes any values embedded in JSX before rendering them. The feature prevents injection attacks, and it is generally safe to embed user input in JSX.

However, there are other XSS vulnerabilities to consider. User-generated content should be validated if passed to component props. For example, the href attribute in a <a> tag could contain an XSS attack vector since it allows JavaScript execution.


You can find a collection of functions you can use to sanitize data in your marketplace in the sanitize.js file. The template sanitizes user and listing data fetched from the API by calling the sanitizeEntity function. The template calls this function when listing or user data is fetched from the API and stored in the Redux store.

When to sanitize user-generated content

If you add new fields to extended data, we highly recommend modifying the sanitization functions to reflect those changes. This is particularly important if you use extended data somewhere other than wrapped in JSX.

Here is an example of public data wrapped in JSX, where the React DOM handles sanitization:


Here is an example of when you should sanitize extended data yourself:

<div attr={publicData.saunaRules}>content).

Any listing extended data attributes specified through the configListings.js file are sanitized automatically. A similar configuration does not exist for user extended data attributes, and to sanitize that data, you will need to update the functions in the sanitize.js file.

It is a good practice to use wrapper components around elements that might need extra safety measures. It makes it easier to add those extra measures if needed in the future. For example, instead of <a> component, we recommend using <ExternalLink> component when you want to link outside of your web app. It adds a noopener handling for external links (since target="_blank" attribute is vulnerable for XSS).

There is also Field* components around <input> elements (e.g. FieldTextInput) since the Sharetribe Web Template uses Final Form. Those could be used in a similar fashion to validate content or just format it before saving.

Further reading