0

I have a validation function that uses wp_kses, and it works as expected to remove code from the input if it is relatively simple code HOWEVER using kses is also removing semicolons from inline styles. (in <h1 style="color: red;">the name</h1>, the semicolon after the word 'red' is removed)

Documentation makes no mention of this behavior, is it a bug? My actual code using kses is below. Can anyone tell me how to change my code so that kses does not remove the semicolon?

function sanitize_name($valid, $value, $field, $input) {

    if( $valid !== true ) {
        return $valid;
    }

    $allowed = array( 
        'h1' => array(
            'style' => array(),
        ),
        'h2' => array(),
        'h3' => array(),
        'h4' => array(),
        'h5' => array(),
        'h6' => array(),
        'p' => array(),
        'br' => array(),
        'strong' => array(),
        'b' => array(),
        'em' => array(),
        'ul' => array(),
        'li' => array(),
        'ol' => array(),
        'div' => array(),
        'span' => array(),
        'pre' => array(),
        'button' => array(),
        'svg' => array(),
        'blockquote' => array(),
        'a' => array(),
        'i' => array(),
        'sup' => array(),
        'sub' => array()
    );

    $value2 = wp_kses( $value, $allowed );

    
    if ( strcmp( stripslashes( $value ), $value2) !== 0 ) {
        return 'Please remove the disallowed HTML from this field to submit.<br />
        Entered:' . stripslashes($value) . '<br />
        Cleaned:<br />' . $value2;
    }

    return $valid;
}
9
  • Semi-colons are not required after a single declaration.
    – vancoder
    Commented Nov 1, 2022 at 15:55
  • @vancoder I believe that is true, however as you can see, my next step is a strcmp which gives a false negative because of the missing semicolon. Do you know of a way around that?
    – ubsd
    Commented Nov 1, 2022 at 16:11
  • are you sure the problem isn't the missing opening quote on the style attribute? I don't think this is a kses problem, this is a HTML mistake
    – Tom J Nowell
    Commented Nov 1, 2022 at 16:24
  • Also, you shouldn't be mixing validation and sanitation in the same function, right now there's a problem that the check doesn't escape or sanitise its own outputs to make sure the error message is safe to display, and there's no way for the code that calls this function to know if sanitising worked or failed because you can't validate without also sanitising. It also means late escaping is impossible because unsafe HTML is being returned. There should be a separate validate_name
    – Tom J Nowell
    Commented Nov 1, 2022 at 16:27
  • @TomJNowell The test input is <h1 style="color: red;">Photo Challenge 1</h1> and the output is <h1 style="color: red">Photo Challenge 1</h1> or <h1 style="color: red; text-decoration: underline;">Photo Challenge 1</h1> and <h1 style="color: red;text-decoration: underline">Photo Challenge 1</h1> so there is no HTML mistake that I see. The last style attribute doesnt have the semicolon on both... Is that a bug with wp_kses?
    – ubsd
    Commented Nov 1, 2022 at 16:44

1 Answer 1

0

There are no signs that this was accidental or a bug, and has been in core for many years. This is because of this set of lines at the end of the main loop of safecss_filter_attr:

            // Only add the CSS part if it passes the regex check.
            if ( $allow_css ) {
                if ( '' !== $css ) {
                    $css .= ';';
                }

                $css .= $css_item;
            }

The root of the question is a broken assumption that wp_kses modifies the original HTML string, which is not the case.

Instead, wp_kses uses regular expressions to break apart your HTML into arrays which are then further subdivided by more regular expressions. It's these arrays that are then going to be processed to remove attributes and tags etc. Then these are reassembled to create a brand new HTML string.

2
  • I am trying to show an alert when code was removed and disallow the field to be submitted hence the strcmp(), however I am getting a false negative and the strings are different whether kses removed code or not. Clearly the strcmp is not allowing this to happen, so how can I achieve that?
    – ubsd
    Commented Nov 1, 2022 at 18:48
  • interesting, you should ask a new question about that, if I left an answer for that question here it would be incredibly confusing to anybody who came here since that's not what your original question was asking. Also you're falling into the X Y problem trap, except it looks more like an X Y Z problem here, you should ask how to solve your problem, not how to fix your solution, in this case there's multiple layers as your check + alert combination is also a solution to an unnamed problem. Would it not be easier to add a HTML class? Inline styling is an anti-pattern
    – Tom J Nowell
    Commented Nov 2, 2022 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.