Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XSS CS Update #103

Merged
merged 3 commits into from
May 16, 2019
Merged

XSS CS Update #103

merged 3 commits into from
May 16, 2019

Conversation

rdela
Copy link
Contributor

@rdela rdela commented May 9, 2019

This PR covers issue #101

Update JS/Node.js libs in Cross Site Scripting Prevention Rule 6 "Other libraries that provide HTML Sanitization":

Line 344 linked to ecto/bleach as "JavaScript/Node.js Bleach"

Now Line 344-5 link to:

...as:

Copy link
Member

@righettod righettod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK for me.
Thank you very much for the PR 😃

Copy link
Collaborator

@mackowski mackowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR.

I like that you added DOMPurify from cure53 (in fact I am very surprised that it was not there)
I am even more happy that you spotted old, unsupported library on that list.
But I think that we should not add here https://github.com/punkave/sanitize-html.

Libraries on that list should be designed to clean potentially malicious HTML from untrusted source to prevent XSS. HTML sanitizer from Closure, PHP HTML Purifier, Python Bleach and DOMPurify from cure53 do that but I never heard of https://github.com/punkave/sanitize-html.

Documentation for this library tells that "sanitize-html is tolerant. It is well suited for cleaning up HTML fragments such as those created by ckeditor and other rich text editors. It is especially handy for removing unwanted CSS when copying and pasting from Word.". This is not our use case. IIn addition, from what I saw, it does not sanitize javascript code by default. User have to specify what should be allowed (tags, attubutes, etc.) and what not. Summarising this is not security library and we cannot guarantee that it will protect users from XSS.

As I wrote before I never heard of this library and I only checked documentation so if I am wrong somewhere and this library can delete javascript please tell me :)

@rdela
Copy link
Contributor Author

rdela commented May 10, 2019

First off, I completely defer to your decisions about what goes in. I wrote in #101:

My cursory research into currently maintained libraries yielded two options [...] If OWASP contributors find both libraries adequate and satisfactory [...]

If the security posture of punkave/sanitize-html is not sufficiently intolerant and obvious enough to warrant inclusion, then I think we should leave sanitize-html out and encourage Node.js devs to use DOMPurify with JSDOM. The fact that you have heard of DOMPurify and were surprised it was not there speaks volumes.

That said, sanitize-html does remove JS. From the README opening section:

If a tag is not permitted, the contents of the tag are still kept, except for script, style and textarea tags.

Further down in "What are the default options?":

allowedTags: [ 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
  'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div',
  'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre', 'iframe' ],
allowedAttributes: {
  a: [ 'href', 'name', 'target' ],
  // We don't currently allow img itself by default, but this
  // would make sense if we did. You could add srcset here,
  // and if you do the URL is checked for safety
  img: [ 'src' ]
},
// Lots of these won't come up by default because we don't allow them
selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta' ],
// URL schemes we permit
allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ],
allowedSchemesByTag: {},
allowedSchemesAppliedToAttributes: [ 'href', 'src', 'cite' ],
allowProtocolRelative: true

Later on:

Allowed URL schemes

By default we allow the following URL schemes in cases where href, src, etc. are allowed:

[ 'http', 'https', 'ftp', 'mailto' ]

You can override this if you want to:

sanitizeHtml(
  // teeny-tiny valid transparent GIF in a data URL
  '<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />',
  {
    allowedTags: [ 'img', 'p' ],
    allowedSchemes: [ 'data', 'http' ]
  }
);

You can also allow a scheme for a particular tag only:

allowedSchemes: [ 'http', 'https' ],
allowedSchemesByTag: {
  img: [ 'data' ]
}

And you can forbid the use of protocol-relative URLs (starting with //) to access another site using the current protocol, which is allowed by default:

allowProtocolRelative: false

Discarding the entire contents of a disallowed tag

Normally, with a few exceptions, if a tag is not allowed, all of the text within it is preserved, and so are any allowed tags within it.

The exceptions are:

style, script, textarea

If you wish to expand this list, for instance to discard whatever is found inside a noscript tag, use the nonTextTags option:

nonTextTags: [ 'style', 'script', 'textarea', 'noscript' ]

Note that if you use this option you are responsible for stating the entire list. This gives you the power to retain the content of textarea, if you want to.

The content still gets escaped properly, with the exception of the script and style tags. Allowing either script or style leaves you open to XSS attacks. Don't do that unless you have good reason to trust their origin.

So by default...

  • script, style, and textarea tags are removed and the entire contents are discarded.
  • All attributes are removed from all tags except href, name, and target on a tags. On href only http, https, ftp, and mailto protocols are allowed.
  • iframe tags are allowed by default but the src attribute is not. There is an open issue about this from 10 April where contributor Tom Boutell suggests iframe will be removed in the 2.x release since it is a breaking change and says:

    as it currently stands the configuration does not make much sense because iframe is allowed, but src is not allowed for iframe.

Thought I would clarify all that to clear up any misunderstanding, but I will add a commit that removes sanitize-html on Monday unless I hear differently from @mackowski before then.

@mackowski
Copy link
Collaborator

mackowski commented May 10, 2019

Thank you for detailed answer!
I was obviously wrong and this library does sanitize javascript/xss paylods by default.
Many thanks for clarification.
DOMPurify and Google Closure are well know and de facto standard javascript libs for this job.
But the fact that I didn't know about sanitize-html does not mean that this is a wrong library!
On one side I am not sure if we have to have 3 js libs but on the other hand why not :)

@ThunderSon what do you think?

@rdela
Copy link
Contributor Author

rdela commented May 10, 2019

I am all for sticking to the de facto standard libs already familiar to OWASP contributors. While we are on the subject, should we rearrange the order to keep languages together and possibly add (JavaScript/Node.js) to the end of the Closure listing to be super explicit?

Like so:

Other libraries that provide HTML Sanitization include:

@rdela
Copy link
Contributor Author

rdela commented May 10, 2019

Looks like maybe we should not capitalize jsdom either, and maybe we should lose "DOM-only" and link that too?

So:

Other libraries that provide HTML Sanitization include:

@rdela
Copy link
Contributor Author

rdela commented May 10, 2019

We could also probably save lazy devs tons of time by linking to the HTML sanitizer docs, not easy to find from the main Closure link. Although https://github.com/google/closure-library/blob/master/closure/goog/html/sanitizer/htmlsanitizer.js has a simple usage example currently on Line 23.

So maybe adjust HTML sanitizer link to htmlsanitizer.js and add docs link at end?

Other libraries that provide HTML Sanitization include:

@jmanico
Copy link
Member

jmanico commented May 10, 2019 via email

@jmanico
Copy link
Member

jmanico commented May 10, 2019 via email

@mackowski
Copy link
Collaborator

No worries Jim we did not deleted https://www.owasp.org/index.php/OWASP_Java_HTML_Sanitizer_Project it is recommended for Java :)

@mackowski
Copy link
Collaborator

@rdela I like your ideas about rearrange the order and improve linking to the closure docs and example.

@jmanico
Copy link
Member

jmanico commented May 10, 2019 via email

@rdela
Copy link
Contributor Author

rdela commented May 15, 2019

@mackowski Updated with suggested changes from my last comment #103 (comment)

Travis build is failing but looks like that is only missing newlines in other cheatsheets?
https://travis-ci.com/OWASP/CheatSheetSeries/builds/111902594#L510

Want me to add them?

@righettod
Copy link
Member

Give some time, i will fix it.
Ticket #105 assigned to me

@righettod
Copy link
Member

I have added info about the TravisCI job issue to fix it in existing PR.

* upstream/master:
- Update policy according to new rules added by https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md
- Fix iteration_count number typo (#100)

sync .markdownlint.json with master

#105 (comment)

> In fact new audit rules has been added to the markdownlint  plugin, precisely MD046 and MD047.
>
> As I take the latest version of the plugin during the CI job then these new rules are enabled by default and have caused rejection on existing CS.
>
> I have updated the policy and tested it against the master branch and it's OK now:
>
> $ bash Apply_Linter_Check.sh
> [+] No error found by the Linter.
> Existing PR must sync their version of the file .markdownlint.json  with the one from the master branch (override PR content of this file with the content coming from the master branch).
@rdela
Copy link
Contributor Author

rdela commented May 15, 2019

Thanks @righettod! PR updated and Travis is passing now ✅

Copy link
Collaborator

@mackowski mackowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome thanks!

@mackowski mackowski merged commit d1c72d1 into OWASP:master May 16, 2019
@OWASP OWASP deleted a comment from jmanico Jun 17, 2019
@OWASP OWASP deleted a comment from jmanico Jun 17, 2019
@OWASP OWASP deleted a comment from jmanico Jun 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants