Airbnb clone, safe HTML for the house description

This post is part of a new series where we build a clone of Airbnb with Next.js. See the first post here.

Our form is great, but we have a problem: the house description.

It is handling the description as HTML:

Unless our target audience for house owners is people that know HTML, this is not going to do a good job.

We need a more user friendly editor.

Second thing, even more important, is that we still don’t have it in the single page view, in the pages/houses/[id].js file.

I deferred this task until now, because I want to show you something.

If we add the house description to pages/houses/[id].js:

...
<p>{props.house.title}</p>
<div>{props.house.description}</div>
...

We’ll find a bad surprise:

The HTML is fully visible, and not interpreted! Just like in the editor above.

The reason is that JSX escapes all content by default, which is great to prevent XSS for example, but not great in this case.

What we must do is, we have to use dangerouslySetInnerHTML:

pages/houses/[id].js

<div
  dangerouslySetInnerHTML={{
    __html: props.house.description
  }}></div>

to make the description interpreted as HTML.

But if we don’t do any kind of filtering to the description, a house owner could also write JavaScript into the description, for example:

<script>alert('test')</script>

And this would run on the house page to people browsing for houses.

This is an XSS vulnerability.

Let’s do the first step first – we add an editor.

Add the Pell editor

The editor I chose is Pell.

It’s easy to use and small in size.

There’s also a React wrapper available at https://github.com/bpetetot/react-pell.

Install it using npm:

npm install react-pell

then go into components/HouseForm.js and import it:

import Editor from 'react-pell'

Now change

<p>
  <label>House description</label>
  <textarea
    required
    onChange={event => setDescription(event.target.value)}
    value={description}></textarea>
</p>

to this:

<div>
  <Editor
    onChange={html => setDescription(html)}
    defaultContent={description}
    actions={['bold', 'underline', 'italic']}
  />
</div>

and add this CSS block at the bottom, before the closing </div> tag of the component:

<style jsx global>{`
  .pell-container {
    border: 1px solid #ccc;
  }
  .pell,
  .pell-content {
    box-sizing: border-box;
  }
  .pell-content {
    height: 300px;
    outline: 0;
    overflow-y: auto;
    padding: 10px;
  }
  .pell-actionbar {
    background-color: #fff;
    border-bottom: 1px solid hsla(0, 0%, 4%, 0.1);
  }
  .pell-button {
    background-color: transparent;
    border: none;
    cursor: pointer;
    height: 30px;
    outline: 0;
    width: 30px;
    vertical-align: bottom;
    color: black;
  }
  .pell-button-selected {
    background-color: #f0f0f0;
  }
`}</style>

This is the end result:

You should now be able to save the house description.

Solving the XSS problem

Now off to the second part – the XSS vulnerability caused by the use of dangerouslySetInnerHTML.

How do we solve that? In the backend we are going to whitelist some tags in the description, eliminating all other tags. I’m going to use the sanitize-html npm package.

Run

npm install sanitize-html

Now in server.js we add this line at the top:

const sanitizeHtml = require('sanitize-html')

and before saving the house using Sequelize in the /api/host/edit and /api/host/new endpoints, we add:

houseData.description = sanitizeHtml(houseData.description, {
  allowedTags: [ 'b', 'i', 'em', 'strong', 'p', 'br' ]
})

This will clean the description and remove all tags except the ones we specifically allow.


This content originally appeared on flaviocopes.com and was authored by flaviocopes.com

This post is part of a new series where we build a clone of Airbnb with Next.js. See the first post here.

Our form is great, but we have a problem: the house description.

It is handling the description as HTML:

Unless our target audience for house owners is people that know HTML, this is not going to do a good job.

We need a more user friendly editor.

Second thing, even more important, is that we still don’t have it in the single page view, in the pages/houses/[id].js file.

I deferred this task until now, because I want to show you something.

If we add the house description to pages/houses/[id].js:

...
<p>{props.house.title}</p>
<div>{props.house.description}</div>
...

We’ll find a bad surprise:

The HTML is fully visible, and not interpreted! Just like in the editor above.

The reason is that JSX escapes all content by default, which is great to prevent XSS for example, but not great in this case.

What we must do is, we have to use dangerouslySetInnerHTML:

pages/houses/[id].js

<div
  dangerouslySetInnerHTML={{
    __html: props.house.description
  }}></div>

to make the description interpreted as HTML.

But if we don’t do any kind of filtering to the description, a house owner could also write JavaScript into the description, for example:

<script>alert('test')</script>

And this would run on the house page to people browsing for houses.

This is an XSS vulnerability.

Let’s do the first step first - we add an editor.

Add the Pell editor

The editor I chose is Pell.

It’s easy to use and small in size.

There’s also a React wrapper available at https://github.com/bpetetot/react-pell.

Install it using npm:

npm install react-pell

then go into components/HouseForm.js and import it:

import Editor from 'react-pell'

Now change

<p>
  <label>House description</label>
  <textarea
    required
    onChange={event => setDescription(event.target.value)}
    value={description}></textarea>
</p>

to this:

<div>
  <Editor
    onChange={html => setDescription(html)}
    defaultContent={description}
    actions={['bold', 'underline', 'italic']}
  />
</div>

and add this CSS block at the bottom, before the closing </div> tag of the component:

<style jsx global>{`
  .pell-container {
    border: 1px solid #ccc;
  }
  .pell,
  .pell-content {
    box-sizing: border-box;
  }
  .pell-content {
    height: 300px;
    outline: 0;
    overflow-y: auto;
    padding: 10px;
  }
  .pell-actionbar {
    background-color: #fff;
    border-bottom: 1px solid hsla(0, 0%, 4%, 0.1);
  }
  .pell-button {
    background-color: transparent;
    border: none;
    cursor: pointer;
    height: 30px;
    outline: 0;
    width: 30px;
    vertical-align: bottom;
    color: black;
  }
  .pell-button-selected {
    background-color: #f0f0f0;
  }
`}</style>

This is the end result:

You should now be able to save the house description.

Solving the XSS problem

Now off to the second part - the XSS vulnerability caused by the use of dangerouslySetInnerHTML.

How do we solve that? In the backend we are going to whitelist some tags in the description, eliminating all other tags. I’m going to use the sanitize-html npm package.

Run

npm install sanitize-html

Now in server.js we add this line at the top:

const sanitizeHtml = require('sanitize-html')

and before saving the house using Sequelize in the /api/host/edit and /api/host/new endpoints, we add:

houseData.description = sanitizeHtml(houseData.description, {
  allowedTags: [ 'b', 'i', 'em', 'strong', 'p', 'br' ]
})

This will clean the description and remove all tags except the ones we specifically allow.


This content originally appeared on flaviocopes.com and was authored by flaviocopes.com


Print Share Comment Cite Upload Translate Updates
APA

flaviocopes.com | Sciencx (2022-01-08T05:00:00+00:00) Airbnb clone, safe HTML for the house description. Retrieved from https://www.scien.cx/2022/01/08/airbnb-clone-safe-html-for-the-house-description/

MLA
" » Airbnb clone, safe HTML for the house description." flaviocopes.com | Sciencx - Saturday January 8, 2022, https://www.scien.cx/2022/01/08/airbnb-clone-safe-html-for-the-house-description/
HARVARD
flaviocopes.com | Sciencx Saturday January 8, 2022 » Airbnb clone, safe HTML for the house description., viewed ,<https://www.scien.cx/2022/01/08/airbnb-clone-safe-html-for-the-house-description/>
VANCOUVER
flaviocopes.com | Sciencx - » Airbnb clone, safe HTML for the house description. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/01/08/airbnb-clone-safe-html-for-the-house-description/
CHICAGO
" » Airbnb clone, safe HTML for the house description." flaviocopes.com | Sciencx - Accessed . https://www.scien.cx/2022/01/08/airbnb-clone-safe-html-for-the-house-description/
IEEE
" » Airbnb clone, safe HTML for the house description." flaviocopes.com | Sciencx [Online]. Available: https://www.scien.cx/2022/01/08/airbnb-clone-safe-html-for-the-house-description/. [Accessed: ]
rf:citation
» Airbnb clone, safe HTML for the house description | flaviocopes.com | Sciencx | https://www.scien.cx/2022/01/08/airbnb-clone-safe-html-for-the-house-description/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.