mganss / HtmlSanitizer

Cleans HTML to avoid XSS attacks
MIT License
1.55k stars 199 forks source link

How to keep whole SVG tag #287

Closed RaptorCZ closed 1 year ago

RaptorCZ commented 3 years ago

I'm using SVG icons in application, but sanitizer removes it. Tried to allow svg tag, but it is not working. All svg nested tags are removed.

sanitizer.AllowedTags.Add("svg")

How to solve it?

SVG example:

<svg viewBox="0 0 136 200" xmlns="http://www.w3.org/2000/svg" class="dashboard-icon">
    <path d="M90.98 167.85c-.2.57-.44 1.16-.72 1.78-.28.62-.6 1.22-.96 1.78-.35.57-.76 1.09-1.22 1.57-.431.457-.93.845-1.48 1.15-.35.14-.66.26-.94.36-.28.1-.58.15-.89.15-.34 0-.58-.14-.72-.42-.14-.28-.22-.61-.25-.98-.02-.37-.01-.72.03-1.06.04-.34.08-.57.11-.68.13-.54.35-1.17.66-1.89.31-.72.68-1.4 1.12-2.04.44-.64.92-1.18 1.42-1.61.51-.44 1.04-.66 1.61-.66.71 0 1.31.18 1.82.55.5.37.65.96.45 1.78l-.04.22zm-6.39 9.94c.17 0 .33.01.48.02.15.01.3.02.44.02.51 0 1.05-.15 1.62-.45.57-.3 1.13-.66 1.69-1.08.56-.42 1.08-.88 1.57-1.36.49-.48.89-.91 1.21-1.28.63-.71 1.2-1.44 1.71-2.19s.89-1.57 1.14-2.44l.2-.81c.08-.31.14-.62.19-.91.05-.3.03-.59-.04-.87-.08-.34-.17-.69-.25-1.06-.08-.37-.24-.68-.49-.94-.29-.31-.62-.57-1-.76-.38-.2-.76-.38-1.16-.55-.4-.17-.79-.34-1.17-.51-.38-.17-.74-.38-1.07-.64-.21-.17-.45-.25-.7-.25-.62 0-1.28.2-1.97.59-.69.4-1.34.86-1.94 1.38-.6.52-1.12 1.06-1.57 1.61-.45.55-.75.98-.92 1.3-.35.74-.74 1.54-1.17 2.4-.43.86-.72 1.61-.87 2.23-.32 1.27-.33 2.35-.04 3.23.29.88.84 1.59 1.64 2.12.36.25.7.52 1.01.78.31.27.71.4 1.19.4h.27v.02zm-7.97-22.9c-.11.43-.21.86-.3 1.3-.09.44-.2.87-.3 1.3-.16.65-.28 1.15-.35 1.51-.07.35-.17.79-.3 1.29-.06.26-.18.56-.33.91-.16.35-.47.53-.92.53-.42.2-.79.34-1.13.42-.33.08-.65.16-.97.21-.31.06-.63.11-.96.17-.33.06-.69.16-1.09.3-.26.48-.43.88-.51 1.19.14.23.36.52.67.89.31.37.74.55 1.31.55.45 0 .87-.08 1.25-.26.38-.17.84-.3 1.37-.38.03.11.04.22.03.32-.01.1-.03.21-.06.32-.32 1.39-.63 2.77-.95 4.14-.31 1.37-.6 2.75-.86 4.14-.11.57-.21 1.19-.28 1.87-.07.68-.08 1.22-.04 1.61.13.4.32.73.58 1 .26.27.59.4.98.4.06 0 .23-.03.53-.09.33-.08.65-.24.97-.47.31-.23.53-.58.65-1.06.08-.34.12-.71.11-1.1-.01-.4-.01-.79 0-1.19.09-1.27.22-2.6.38-3.97s.4-2.7.71-3.97c.05-.2.1-.39.16-.57.06-.18.11-.36.15-.53.04-.17.08-.34.11-.51.03-.17.07-.35.12-.55.08-.34.27-.62.55-.85.28-.23.6-.41.94-.55.35-.14.71-.26 1.09-.36.38-.1.71-.2.99-.32.3-.09.61-.16.93-.23.32-.07.61-.16.9-.28.28-.11.54-.28.76-.49.22-.21.38-.5.47-.87.08-.31.08-.62.02-.93-.06-.31-.29-.47-.69-.47-.74 0-1.41.12-2.02.36-.61.24-1.29.36-2.02.36-.23 0-.34-.07-.33-.21.01-.14.03-.3.07-.47.09-.37.19-.72.29-1.06.1-.34.19-.66.26-.98.11-.45.23-.9.36-1.34.12-.44.24-.88.35-1.34.11-.43.2-.86.28-1.3.08-.44.2-.95.34-1.55.08-.31.13-.63.15-.96.02-.32-.01-.62-.1-.87a1.329 1.329 0 00-.52-.64c-.26-.17-.62-.26-1.11-.26-.23 0-.42.04-.58.11-.16.07-.37.16-.62.28-.18.4-.32.76-.4 1.1l-1.09 4.4zm-23.4 12.24l-.3 1.19c-.1.4-.23.79-.38 1.19-.42 1.7-.73 3.13-.92 4.29-.19 1.16-.24 2.11-.16 2.85.08.74.33 1.27.75 1.59.41.32 1.03.49 1.85.49.76 0 1.55-.28 2.35-.83.8-.55 1.55-1.2 2.25-1.95s1.33-1.52 1.91-2.32c.58-.79 1.04-1.43 1.39-1.91l.26-.34c-.08.68-.15 1.34-.19 1.98-.05.64-.01 1.22.1 1.74s.31.97.6 1.34c.29.37.73.62 1.32.76.21-.06.42-.1.63-.13.21-.03.4-.08.59-.15.19-.07.36-.18.53-.34.17-.15.31-.38.44-.66-.05-.25-.12-.47-.22-.66-.1-.18-.2-.38-.32-.57-.28-.6-.39-1.38-.33-2.36s.26-2.15.6-3.5c.17-.68.42-1.49.76-2.44.33-.95.71-2.26 1.13-3.93-.08-.23-.25-.45-.51-.68-.25-.23-.5-.34-.72-.34-.03 0-.06-.01-.08-.02-.03-.01-.05-.02-.08-.02-.71 0-1.24.1-1.58.3-.35.2-.6.45-.76.74-.16.3-.28.63-.35 1-.08.37-.22.74-.42 1.1-.5.88-1.12 1.88-1.86 3.02-.74 1.13-1.5 2.21-2.29 3.23s-1.55 1.89-2.29 2.61c-.73.72-1.33 1.11-1.8 1.17.09-.59.24-1.46.44-2.61s.47-2.4.81-3.76c.1-.4.24-.82.42-1.27.18-.45.38-1.09.58-1.91.12-.48.27-.9.44-1.25.17-.35.32-.76.43-1.21.13-.54.01-.95-.37-1.23s-.79-.45-1.23-.51c-.15.03-.28.06-.38.09-.11.03-.21.06-.3.08-.18.06-.35.12-.49.19-.15.07-.24.13-.28.19-.4.68-.71 1.37-.94 2.08-.23.71-.44 1.44-.64 2.21l-.39 1.47zm-12.45.38c1.2-2.32 2.52-4.67 3.97-7.05 0 .57-.01 1.13-.02 1.7-.01.57-.02 1.13-.02 1.7-.01.62-.05 1.23-.11 1.8-.06.58-.13 1.15-.22 1.72-1.93 0-3.13.04-3.6.13m-9.83 12.32c-.09.57.3.99 1.17 1.27.1.06.2.08.3.08h.28c.42 0 .75-.17.98-.51.71-1.05 1.57-2.62 2.58-4.72.455-.958.925-1.908 1.41-2.85.4-.76.73-1.37.99-1.83.76-.54 1.71-.88 2.85-1.02l2.95-.26c.21 1.44.22 3.24.06 5.4-.13 1.98.47 3.1 1.8 3.36.2 0 .57-.2 1.12-.6.59-.43.95-.92 1.09-1.49.08-.31.09-.71.04-1.19a97.536 97.536 0 01-.4-7.41c-.06-2.73-.02-5.77.1-9.11.08-.57.16-1.15.22-1.74.06-.6.12-1.18.18-1.74.11-1.36-.14-2.38-.77-3.06-.25-.26-.57-.38-.97-.38-.54 0-.94.2-1.21.6-.59.91-1.25 1.99-1.98 3.25-.72 1.26-1.54 2.74-2.44 4.44-2.07 3.88-3.53 6.51-4.39 7.9-.11.2-.41.35-.92.47-.5.09-.83.21-.99.38-.14.11-.23.25-.28.42-.04.17.1.41.42.72.3.28.42.54.36.76-.32.93-1.16 2.44-2.52 4.5-1.01 1.53-1.64 2.85-1.92 3.95l-.11.41z" fill="#25aec2" fill-rule="nonzero"/>
    <path d="M.11 77.93V75.1c0-.47.59-.84 1.32-.84h77.41c.73 0 1.32.38 1.32.84v2.83c0 .47-.59.84-1.32.84H1.42c-.72 0-1.31-.38-1.31-.84zm135.27 9.38l-.46 2.91c-.08.48-.79.83-1.6.78L90.3 88.69l-.41-.02-40.5-2.18-.33 2 40.57 2.18.31.02 44.66 2.4-1.23 7.87c-.68 4.35-5.48 5.55-5.48 5.55l-13.12 15.79s-6.81.54-14.65.67c-7.17.12-14.13-.28-15.34-.35-1.22-.06-8.19-.41-15.2-1.29-7.67-.97-14.2-2.23-14.2-2.23l-3.57-7.57c-4.64.13-10.98.3-11.67.3-1.09.01-7.32.03-13.67-.46-6.94-.53-12.91-1.41-12.91-1.41L4.09 94.03S0 92.62 0 88.38v-7.66h80.25v2.76l10.36.56 43.44 2.34c.8.03 1.4.46 1.33.93zM11.5 90.2c2.69 0 4.88-1.4 4.88-3.13s-2.19-3.13-4.88-3.13c-2.7 0-4.88 1.4-4.88 3.13-.01 1.73 2.18 3.13 4.88 3.13zm108.72 11.93c3.01.16 5.68-1.14 5.96-2.92.28-1.77-1.94-3.34-4.95-3.5-3.01-.16-5.68 1.14-5.96 2.92-.27 1.77 1.94 3.34 4.95 3.5zm-26.39 4.96l3.98 2.46 2-2.33c-2.19-.04-4.2-.08-5.98-.13zm-21.8-1.5c-8.38-.87-16.27-2.54-16.27-2.54l5.4 13.03s7.22 1.43 12.47 1.92c4.54.42 10.16.76 11.59.84.84.04 6.98.35 11.91.42 5.31.08 12.86-.56 12.86-.56l9.37-12.23s-8.28.81-16.79.77c-.48 0-.93-.01-1.4-.01l-.53 3.37 10.83-2.11-5.02 3.32 5.81 1.21-9.11.13 4.09 3.2-7.15-2.18-3.67 4.29-.79-4.53-9.34 2.19 6.54-3.54-6.16-2.13 6.19-1.23-1.82-2.2c-1.73-.06-2.99-.11-3.59-.14 0 0-.09-.01-.21-.01-.12-.01-.2-.01-.2-.01-1.62-.12-7.81-.52-15.01-1.27zm-15.77-6.9c3.01.16 5.68-1.14 5.96-2.92.51-3.21-2.16-3.35-4.95-3.5-3.01-.16-5.68 1.14-5.96 2.91-.27 1.78 1.94 3.35 4.95 3.51zm-8.88 3.49s-4.1-1.63-3.67-5.74c-1.52.01-2.22.02-3.4.03h-.37c-1.43-.01-6.99-.08-13.49-.42-7.56-.4-14.8-1.61-14.8-1.61l6.61 12.3s6.61 1.01 11.34 1.21c4.09.17 9.13.2 10.41.21.72 0 5.8-.02 10.09-.19l-2.72-5.79z" fill="url(#_Linear1)" fill-rule="nonzero" transform="translate(0 20)"/>
    <path d="M3.62 87.78c0 1.01.84 1.83 1.87 1.83h7.67c1.03 0 1.87-.82 1.87-1.83V80.7H3.62v7.08zm84.65-7.5l.31-.03 44.66-4.1-1.23-13.44c-.68-7.43-5.48-9.49-5.48-9.49l-13.12-26.98s-6.81-.93-14.65-1.15c-7.17-.21-14.13.47-15.34.6-1.2.1-8.02.68-14.94 2.15l-2.13-5.01c-1.11-.24-6.54-1.39-12.66-2.12-6.29-.75-12.46-.72-13.62-.71-1.18-.01-7.35-.04-13.63.7-6.11.72-11.52 1.87-12.65 2.12L4.36 47.27l-.14.07c-.16.08-3.87 2.15-3.87 8.32v11.38h42.14c-.18 1.11-.25 2.38-.12 3.83H1.36c-.5 0-.9.39-.9.88v4.35c0 .49.4.88.9.88h41.57c.4 4.38.68 7.39.68 7.39l44.66-4.09zm-32.34-2.74c-3.01.28-5.68-1.96-5.96-4.99-.28-3.02 1.94-5.7 4.95-5.98 3.01-.28 5.68 1.96 5.96 4.98.27 3.03-1.94 5.71-4.95 5.99zm36.56-25.32l3.98-4.2 2 3.99c-2.2.05-4.21.12-5.98.21zm32.34 13.45c.28 3.03-1.94 5.71-4.95 5.99-3.01.27-5.68-1.96-5.96-4.99-.28-3.02 1.94-5.71 4.95-5.98 3.001-.268 5.691 1.98 5.96 4.98zM83.88 32.15c.84-.07 6.98-.6 11.91-.73 5.31-.13 12.86.97 12.86.97l9.37 20.9s-8.28-1.38-16.79-1.31c-.48 0-.93.02-1.4.02l-.53-5.77 10.83 3.62-5.02-5.69 5.81-2.07-9.11-.21 4.09-5.47-7.15 3.72-3.67-7.34-.79 7.75-9.34-3.75 6.54 6.05-6.16 3.64 6.19 2.11-1.82 3.76c-1.73.1-2.99.2-3.59.24 0 0-.08.01-.21.02-.12.01-.2.02-.2.02-1.6.16-7.79.85-14.99 2.13-8.38 1.49-16.27 4.35-16.27 4.35l5.41-22.25s7.22-2.45 12.47-3.29c4.5-.72 10.13-1.28 11.56-1.42zM11.43 62.08c-2.46 0-4.47-1.97-4.47-4.39s2-4.4 4.47-4.4c2.47 0 4.47 1.97 4.47 4.4 0 2.42-2.01 4.39-4.47 4.39zm28.81-18.45h-.36c-1.53.02-7.01.12-13.46.65-7.44.61-14.66 2.45-14.73 2.47l-.75.19 6.94-19.87.22-.05c.07-.02 6.7-1.56 11.4-1.87 4.04-.27 9.01-.31 10.44-.32 1.03 0 6.34.04 10.66.32 4.7.31 11.34 1.86 11.41 1.87l.23.05.64 2.07c-5.13 1.31-8.87 2.55-8.87 2.55L50.6 44.06c-5.26-.34-9.46-.42-10.36-.43zm7.45 54.84l.04 2.11c0 1.42 1.15 2.57 2.56 2.57l8.61.02c1.41 0 2.56-1.15 2.55-2.57l-.05-3.39-13.71 1.26zm69.01 2.23c0 1.42 1.15 2.58 2.56 2.58l8.61.02c1.41 0 2.56-1.15 2.55-2.57l.03-9.86-13.78 1.26.03 8.57zm16.87-19.66c-.08-.82-.79-1.41-1.6-1.34l-43.02 3.95-.41.04-43.02 3.95c-.81.07-1.41.79-1.33 1.61l.46 4.97c.07.81.79 1.41 1.6 1.34l43.02-3.95 43.44-3.99c.81-.07 1.41-.8 1.33-1.61l-.47-4.97z" fill-rule="nonzero"/>
    <defs>
        <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="rotate(90 -3.3 71) scale(48.7)">
            <stop offset="0" stop-opacity=".1"/>
            <stop offset="1" stop-opacity="0"/>
        </linearGradient>
    </defs>
</svg>
mganss commented 3 years ago

You'll have to use events:

sanitizer.RemovingTag += (s, e) => e.Cancel = e.Tag is AngleSharp.Svg.Dom.SvgElement;
sanitizer.RemovingAttribute += (s, e) => e.Cancel = e.Tag is AngleSharp.Svg.Dom.SvgElement;
RaptorCZ commented 3 years ago

ok and any way to keep svg and prevent <svg/onload=alert()> xss?

mganss commented 3 years ago

If you want to keep the event-based approach allowing all SVG elements and their attributes, you'll have to implement your own logic. Something like this:

sanitizer.RemovingAttribute += (s, e) => e.Cancel = e.Tag is AngleSharp.Svg.Dom.SvgElement
    && !e.Attribute.Name.StartsWith("on");

Another option that aligns better with the original design of the sanitizer is to add all the elements and attributes you actually want to allow to AllowedTags and AllowedAttributes.

Do you really want to allow user contributed SVG?

RaptorCZ commented 3 years ago

Well, this is not exactly about SVG itself. I need to sanitize html parts in CMS that can contain SVG sprites. And also I need sanitize inputs to prevent user enter some types of XSS strings. Img onLoad and SVG onLoad is just an example.

mganss commented 3 years ago

So users should be allowed to enter SVG?

RaptorCZ commented 3 years ago

User can enter any text to form inputs, but some are rendered back as html. So I need to strip XSS attempts. Pentesters are using OWASP samples and <svg/onload is almost the same as any script tag. Text from all inputs and other sources should be sanitized with one helper function. Some texts are external and can contain SVG parts, mostly icons, with user entered texts.

So for now I just need to strip onload attributes from and <svg/onload=""> strings and keep svg. It is not possible to have mutiple sanitize functions with strip all svg and keep safe parts of svg.

mganss commented 3 years ago

If user entered SVG is really a possible source of XSS then it's probably best to compile a list of elements and attributes you want to allow and add these to AllowedTags and AllowedAttributes.