[wp-hackers] wp_specialchars() vs attribute_escape() ( now esc_attr() ) and quote entity-encoding

Mark Jaquith markjaquith at gmail.com
Sat May 9 08:36:21 GMT 2009

WordPress 2.8 is getting a shortening, consolidation, and
"i18n-chaining" upgrade for its security escaping functions.

Here are some old/new pairs:

echo attribute_escape( __('Translated String') );
esc_attr_e(' Translated String' );

attribute_escape( __('Translated String' ) );
esc_attr__( 'Translated String' );

attribute_escape( $user_string );
esc_attr( $user_string );

js_escape( "dynamic $js" );
esc_js( "dynamic $js" );

The naming convention is esc_FORMAT[optional i18n suffix](). It's
shorter, predictable, and it cuts down on parenthesis nesting! Next on
my list was one-parameter wp_specialchars(), which will become
esc_html(), esc_html_e() and esc_html__().

It occurred to me that a lot of people do this:

<input value="<?php echo wp_specialchars( $xss ); ?>" />

Which is WRONG (and unfortunately common in plugins) and an XSS
exploit opportunity. See, attribute_escape() (now esc_attr())
additionally entity-encodes quotes, to prevent XSS attacks from
"breaking out" of the attribute. That's the only real difference
between attribute_escape( $xss ) and wp_specialchars( $xss ). While it
is dangerous to use wp_specialchars( $xss ) instead of
attribute_escape( $xss ), the opposite is not true. There is no harm,
that I can think of, in entity-encoding quotes in an HTML context.

Can you think of any? If not, this presents us with an opportunity to
make esc_html() and esc_attr() functionally equivalent and to have
wp_specialchars( $xss ) calls go through esc_html(), which would
encode quotes, and thus anyone who used the above code would get a
free security upgrade to their plugin/theme. Can you think of any
reason this wouldn't work? C'mon, go ahead and rain on my parade.


Backward compat with the old functions is maintained. As for my
proposed handling of esc_html() and wp_specialchars(), calls to
wp_specialchars() with default values for the rarely-used additional
params would be honored, like before. It's only single-parameter calls
to wp_specialchars() that would get the esc_html()/quote-encoding

Mark Jaquith
• http://markjaquith.com/http://coveredwebservices.com/

More information about the wp-hackers mailing list