Fixing version not approved on Habitica-Chat-Extension (FireFox)
Tags: javascript, security, hacktoberfest
Published: 2019-10-02 19:50:43

I've created [my first open source pull request](https://dev.to/heymarkkop/my-first-open-source-contribution-21dh) ever, but it couldn't be accepted because the firefox extension I was referencing hadn't its last version approved.

{% github https://github.com/HabitRPG/habitica-chat-extension/issues/49 %}

Since I'll be literally working with Javascript soon, this seems a great opportunity to practice the language.

## :rice_scene: Environment

Ok, so the first challenge is to understand how to create/maintain a Firefox extension. Of course Mozilla would have a nice documentation about it

:smiley_cat: [Mozilla - Your first WebExtension](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension)

It seems that `manifest.json` is the extension's heart.
And to [make it live](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension#Installing), we have to go to `about:debugging` in Firefox, click "Load Temporary Add-on" and select our `manifest.json`.
Beware to not select the zip file as this will be our deployed version later.

Then we visit Habitica.com and check it out. It's working!

![habitica chat extension](http://i.imgur.com/LR0Q0WD.png)

## :wrench: Fixing issues

### :straight_ruler: Minified Code

Firefox complains the following:

> This version contains minified, concatenated or otherwise machine-generated code. Please provide the original sources, together with instructions on how to generate the final XPI. Source code must be provided as an archive and uploaded using the source code upload field, which can be done during submission or on the version page in the developer hub.
> Please read through the instructions at https://developer.mozilla.org/en-US/Add-ons/Source_Code_Submission.
> Here are some examples that were discovered:
> resources\habitica-markdown.min.js

It seems that minified code is not allowed, therefore we just have to convert this `habitica-markdown.min.js` to a not-minified version.

![](http://i.imgur.com/dvydg7a.png)

I've simply pasted the code in this [UglifyJS](http://lisperator.net/uglifyjs/) and selected `Beautify`. Then I've created a new `habitica-markdown.js` and pasted the new beautified code in it.

Sure we have to fix some imports, such as in `manifest.json` and `chat.js`

```javascript
// chat.js
// Call markdown to html script
var s = document.createElement("script");
s.src = browser.extension.getURL("resources/habitica-markdown.js");
s.onload = function() {
  this.parentNode.removeChild(this);
};
(document.head || document.documentElement).appendChild(s);
```

### :passport_control: Ajax Permission

> Please remove all unused permissions from your manifest.
> Here are some examples that were discovered:
> https://ajax.googleapis.com/

This is as simples as removing the string `https://ajax.googleapis.com/` from manifest's `permissions` key.

It didn't break anything, so it was indeed unused.

### :shower: Sanitize HTML Strings

> This add-on is creating DOM nodes from HTML strings containing potentially unsanitized data, by assigning to innerHTML, jQuery.html, or through similar means. Aside from being inefficient, this is a major security risk. For more information, see https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Safely_inserting_external_content_into_a_page .
> Here are some examples that were discovered:
> mainChat\chat_inPage.js line 147, 194, 199 and possible more.

This is where I most had to search about. Which was great because it was something I was very curious since I had contact with Javascript and Security.

As some might already know, creating DOM nodes using HTML strings (such as [innerHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML), jQuery.html) with user input data is very dangerous because it can suffer XSS (Cross Site Scripting) attacks.
To verify this with my own hands, I've taken a line of code from the extension and tried to insert some malicious code in it.

{% codepen https://codepen.io/kopmark/pen/XWrwyLE default-tab=js,result %}

In the [code](https://codepen.io/kopmark/pen/XWrwyLE) above, I've also converted the HTML String to DOM node methods to confirm if they would indeed be safer.

We could convert all unsafe lines to DOM methods, but there's another way to solve this issue that's with [HTML sanitization](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Safely_inserting_external_content_into_a_page#HTML_sanitization).

We add `purify.js` from [DOMPurify](https://github.com/cure53/DOMPurify) in our resources files, reference it in `manifest.json`, import it in `chat.js` and use it with the following example:

```javascript
var elem = document.createElement("div");
var cleanHTML = DOMPurify.sanitize(externalHTML);
elem.innerHTML = cleanHTML;
```

(when using with JQuery, the flag `{ SAFE_FOR_JQUERY: true }` is required)

In the `chat_InPage.js` I had to use `DOMPurify` 24 times. 
I didn't find an easier way to do this than manually, so if you know other solutions, feel free to share in the comments.

## :email: Submitting the PR

As instructed in the `README.md`, we need to replicate the changes to Chrome port and test them. Luckily everything worked just fine.
We also need to bump the version in `manifest.json` and write down the release notes in the README itself.
We can't forget to zip files (not folder) with all the changes we've made to package the [extension](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Package_your_extension_).

{% github https://github.com/HabitRPG/habitica-chat-extension/pull/50 %}

## :hammer: Conclusion

Working on this issue was pretty interesting, because it involved Javascript, Browser Extensions and Security. I've even had the opportunity to learn more about XSS attacks and how to prevent them.
Now I have to wait for a review and for Habitica's staff to handle the privacy policy which is another requirement for Firefox.