apostrophecms / sanitize-html

Clean up user-submitted HTML, preserving whitelisted elements and whitelisted attributes on a per-element basis. Built on htmlparser2 for speed and tolerance
MIT License
3.68k stars 349 forks source link

allowedStyles does not work #622

Open david-siqi-liu opened 1 year ago

david-siqi-liu commented 1 year ago

PLEASE NOTE: make sure the bug exists in the latest patch level of the project. For instance, if you are running a 2.x version of Apostrophe, you should use the latest in that major version to confirm the bug.

To Reproduce

Step by step instructions to reproduce the behavior:

input = '<p style="color: rgb(241, 196, 15);">Color</p>';

input = sanitizeHtml(input, {
  allowedTags: ['p'],
  allowedAttributes: {
    'p': ["style"],
  },
  allowedStyles: {
    '*': {
      // Match HEX and RGB
      'color': [/^#(0x)?[0-9a-f]+$/i, /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/],
      'text-align': [/^left$/, /^right$/, /^center$/],
      // Match any number with px, em, or %
      'font-size': [/^\d+(?:px|em|%)$/]
    },
    'p': {
      'font-size': [/^\d+rem$/]
    }
  }
});
return input;

Expected behavior

'<p style="color: rgb(241, 196, 15);">Color</p>'

Describe the bug

'<p>Color</p>'

Details

Version of Node.js: 16

Server Operating System: MacOS

Additional context: "sanitize-html": "^2.10.0",

Screenshots

BoDonkey commented 1 year ago

Hi @david-siqi-liu, I can't reproduce this bug when I add your ruleset into the package tests. I ran this with Node 16.20.0 and 'sanitize-html' at 2.10.0. Maybe you have other sanitize settings that are interfering?

it('should allow RGB styles', function () {
    assert.equal(
      sanitizeHtml('<p style="color: rgb(241, 196, 15);">Color</p>', {
        allowedTags: ['p'],
        allowedAttributes: {
          p: ['style']
        },
        allowedStyles: {
          '*': {
            // Match HEX and RGB
            color: [/^#(0x)?[0-9a-f]+$/i, /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/],
            'text-align': [/^left$/, /^right$/, /^center$/],
            // Match any number with px, em, or %
            'font-size': [/^\d+(?:px|em|%)$/]
          },
          p: {
            'font-size': [/^\d+rem$/]
          }
        }
      }),
      '<p style="color:rgb(241, 196, 15)">Color</p>'
    );
  });
MarcGooris commented 10 months ago

I am having the same issue with the same ruleset using version: "sanitize-html": "2.10.0".

Input:

<p style="text-align: center;">text align center</p>

Output:

<p>text align center</p>

Solution is to replace the wildcard/asterisk of allowedStyles with the specified element or an empty string like so:

allowedStyles: {
            '': { 
                // Match HEX and RGB
                color: [
                    /^#(0x)?[0-9a-f]+$/i,
                    /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/,
                ],
                'text-align:': [/^left$/, /^right$/, /^center$/],
                // Match any number with px, em, or %
                'font-size': [/^\d+(?:px|em|%)$/],
                'width': [/^\d+(?:px|em|%)$/],
            },`

Also make sure the style properties for each elements are included in your allowedAttributes.

aviyi commented 7 months ago

It's also happen to me .

aviyi commented 6 months ago

@david-siqi-liu do you have a fix?