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

{allowedTags:null} allows <script> #176

Closed
mikesamuel opened this issue Oct 31, 2017 · 4 comments · Fixed by #577
Closed

{allowedTags:null} allows <script> #176

mikesamuel opened this issue Oct 31, 2017 · 4 comments · Fixed by #577
Labels

Comments

@mikesamuel
Copy link
Contributor

mikesamuel commented Oct 31, 2017

'<script>alert(1)</script>' ==
sanitizeHtml(
    '<script>alert(1)</script>',
    { allowedTags: null });

'<script>alert(1)</script>' ==
sanitizeHtml(
    '<script>alert(1)</script>',
    { allowedTags: undefined });

The docs say

"What if I want to allow all tags or all attributes?"

Simple! instead of leaving allowedTags or allowedAttributes out of the options, set either one or both to false:

allowedTags: false,
allowedAttributes: false

The internal check checks whether allowedTags is falsey, not false.

Treating null equivalently to false is problematic since null is
much more likely as an output from a function that otherwise
returns an array than false, so treating null and undefined
as equivalent to false is a corner-case with very serious security consequences.

For example,

const MY_POLICY = {
  allowedTags: computeAllowedTags()
};

function computeAllowedTags() {
  if (complexCondition) {
    return INLINE_ELEMENTS;
  } else if (anotherComplexCondition) {
    return BLOCK_AND_INLINE_ELEMENTS;
  } else if (adNauseam) {
    return FORMATTING_ELEMENTS_AND_IMAGES;
  }
  // NOTE: Missing return at bottom implies return of undefined
}

Since the behavior for undefined and null, 0, NaN, "" and other falsey values is not documented, I recommend either

  • changing the code that fils in blanks:
    options = extend(sanitizeHtml.defaults, options);
    to first remove any properties with falsey, but non-false values.
  • and/or change the falsey checks
    if (options.allowedTags && options.allowedTags.indexOf(name) === -1) {
    to check for false:
    if (options.allowedTags !== false
        && (options.allowedTags || []).indexOf(name) === -1) {
    and similarly for allowedAttributes.
@stale
Copy link

stale bot commented Jul 7, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jul 7, 2020
@abea abea added the v2 label Jul 7, 2020
@stale stale bot removed the stale label Jul 7, 2020
@kedarchandrayan
Copy link
Contributor

kedarchandrayan commented Sep 23, 2022

Hello @boutell,

Should I pick this up? This seems to be an issue as null or undefined are behaving the same as false. As per the documentation, only false value should be respected.

Also, @mikesamuel has given a very good example in which such mistakes can occur, if a function like computeAllowedTags is being used which misses a default return.

Please let me know your opinion. I will raise a PR if you want.

Thanks,
Kedar Chandrayan

@boutell
Copy link
Member

boutell commented Sep 30, 2022

Feel free. Sounds like there's a good reason for a runtime check on this.

@kedarchandrayan
Copy link
Contributor

Hello @boutell,

I have raised the PR as per the discussion. Also added new test cases for covering the expected behavior. Please let me know your comments.

Thanks,
Kedar Chandrayan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants