Home Forums Bug Reports Field saving does not respect unfiltered_html capability


Field saving does not respect unfiltered_html capability

  • Users assigned roles without the unfiltered_html capability are able to save html markup in ACF fields. This opens up a site to XSS vulnerabilities by allowing any user to paste in potentially malicious code, rather than requiring users with the expressed capability only.

    Steps to Reproduce:
    1. Create an ACF text/textarea/wysiwyg field on a page.
    2. Create a new user with role Author. Authors by default do not have the unfiltered_html capability.
    3. Create a new page as the new user, with <script>alert('This should not happen!');</script> as the ACF field content.
    4. View the page, the script runs.

    Expected Behavior: For users without the unfiltered_html capability, script tags should be stripped out and the field content should display as alert('This should not happen!').

    Proposed resolution: ACF fields should check if the user has the unfiltered_html capability on save, and if not, run field content through wp_filter_post_kses().

    • Elliot

    • December 6, 2018 at 6:00 pm

    Hi @benabaird

    Thanks for the bug report and sorry for my delayed reply.
    This is a good idea and will be easy to implement.

    Please edit the file โ€œincludes/form.phpโ€ and find the line ~160:

    // action
    do_action('acf/save_post', $post_id);

    Then change it to this:

    // Filter $_POST data for users without the 'unfiltered_html' capability.
    if( !current_user_can('unfiltered_html') ) {
    	$_POST['acf'] = wp_kses_post_deep( $_POST['acf'] );
    // action
    do_action('acf/save_post', $post_id);

    We have tested this and can confirm it works correctly for author users who don’t have the ‘unfiltered_html’ capability:

    Let me know your thoughts on the fix and I’ll aim to release a patch shortly.


  • @elliot Sound update for most all use cases โ€“ but, would you consider adding a filter on this so we can choose fields to bypass kses? or is there some other way currently?

    Use Case: We use a text area field on the page editor for “custom scripts”, which only outputs to logged out users. For now, we have rolled back this release until we come up with a work around.


    • Elliot

    • December 18, 2018 at 10:21 am

    Hi @chriscarr

    Thanks for the comment. I’m happy to add this in.
    For naming, maybe something like ‘acf/allow_unfiltered_html’?
    You could hook into this and override the boolean value.

  • Yeah, that would definitely allow us to bypass the check and keep up to date ๐Ÿ‘

    Honestly I had not really looked at the implementation when I suggested this, and was thinking this was being run later โ€“ per value rather than on the entire $_POST['acf'].

    I suppose for our use case we would then want to add our own conditional KSES implementation later in the save_post process, like in acf/pre_update_value.

    (Just droppin these notes in case someone else is in the same situation someday)


    • Elliot

    • January 9, 2019 at 4:56 pm

    Hi @chriscarr

    Just wanted to let you know I’ve added in a new filter for v5.7.10 called “acf/allow_unfiltered_html”.

    You can hook into this and return true/false to allow/prevent unfiltered HTML.

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.

We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.