The WordPress Coding Standards sniffs treat do_shortcode()
as an “autoescaped function”. This appears to have been discussed in 2015 in these GitHub issues:
https://github.com/WordPress/WordPress-Coding-Standards/issues/167
https://github.com/WordPress/WordPress-Coding-Standards/issues/428
The explanation used when it was added to the list was:
I discussed this with VIP support (#44195). David, after conferring
with another team member, said that it’s unnecessary, as we do the
escaping where the HTML is emitted (in the shortcode’s code).
But I’m not sure I agree with the reasoning. If you used it like this:
<?php echo do_shortcode( '[liveperson]' ); ?>
Where the shortcode is hard-coded, it makes sense, because the only thing to escape is the output of the shortcode, which should be escaped by the shortcode callback.
However, in your situation, you are using do_shortcode()
to allow execution of shortcodes within user-supplied text, from a custom field. That text does need to be escaped, but do_shortcode()
does not do any actual escaping.
So the safe way to handle fields like this would be to put the text through wp_kses()
or wp_kses_post()
, to remove disallowed tags, and then put it through do_shortcode()
so that the shortcodes can be executed without being escaped again.
$text = get_field( 'field_name' );
echo do_shortcode( wp_kses_post( $text ) );
It won’t make any difference to what the code sniffer does/does not report, but at least the user supplied text is sanitised.
One limitation is that it won’t work if you use esc_html()
, because that will interfere with shortcode attributes. This sanitisation also won’t prevent users entering unbalanced tags that could affect the layout, which is one thing escaping normally helps with. To address that issue you could add force_balance_tags()
:
$text = get_field( 'field_name' );
echo do_shortcode( force_balance_tags( wp_kses_post( $text ) ) );