Q:

From a security standpoint, should bloginfo() or get_bloginfo() be escaped?

I've been reviewing a lot of information about WP theme and plugin security and understand the concept that you should escape attributes and HTML values in themes and plugins. I've seen bloginfo() and echo get_bloginfo() used both standard and inside an esc_html() or esc_attr() function. 
Genesis and _s, Automattic's base theme both escape these values but WP's own codex theme standards guide does not say anything about escaping these values. I've looked into the WP code (wp-includes/option.php) and it seems like that there's a little sanitization of values passed from get_option() but it also looks like there's a filter that a plugin could overwrite for certain values. 
It's this fact that leads me toward thinking that it should be escaped. Can anyone enlighten me on this?

A:

We have to look a bit deeper here to get an answer to your question.
So, bloginfo is a simple wrapper around get_bloginfo.
<?php
function bloginfo( $show='' ) {
    echo get_bloginfo( $show, 'display' );
}

Notice the second argument display. Let's see what that does.
<?php
function get_bloginfo( $show = '', $filter = 'raw' ) {

    // snip snip, $output is fetched somewhere in here

    if ( 'display' == $filter ) {
        if ( $url )
            $output = apply_filters('bloginfo_url', $output, $show);
        else
            $output = apply_filters('bloginfo', $output, $show);
    }

    return $output;
}

If the filter is set to display the output of get_bloginfo is run through a filter.
Rather than hardcode something like a call to esc_html in a function, WP uses it's own hook system to do things.  The place to find that where that happens is in wp-includes/default-filters.php.  A quick search for bloginfo in that file reveals...
<?php
// Format strings for display.
foreach ( array( 'comment_author', 'term_name', 'link_name', 'link_description', 'link_notes', 'bloginfo', 'wp_title', 'widget_title' ) as $filter ) {
    add_filter( $filter, 'wptexturize'   );
    add_filter( $filter, 'convert_chars' );
    add_filter( $filter, 'esc_html'      );
}

bloginfo is hidden in the foreach array. As you can see, the output of bloginfo gets escaped with esc_html.
In other words, this:
<?php
bloginfo('name');

Is equivalent to this:
<?php
echo esc_html(get_bloginfo('name'));

Or this:
<?php
echo get_bloginfo('name', 'display');

So, no, the output of bloginfo does not need to be escaped.  Neither does the output of get_bloginfo as long as the second argument is set to display.
The caveat, however, is that anyone can remove the esc_html filter from bloginfo.  So it's likely safer just to escape the output. And, of course, if you're using the output of bloginfo for anything other than HTML display (eg. in the alt attribute of an image), you should run it through esc_attr.

