like_escape() is Deprecated in WordPress 4.0

@miqrogroove has written a blog post on his personal blogblog (versus network, site) explaining why like_escape() has been deprecated in WordPress 4.0. It has been reposted below.

PluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party authors and website developers who work with WordPress database queries should notice an important change coming in WordPress 4.0.

The function like_escape() is no longer used in WordPress coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. code. It is still available as a deprecated function, so it still works in any existing plugins that rely on it. However, a new and different function is available that should be used in all new code.

Deprecated means that anyone using code that calls like_escape() with WP_DEBUG enabled will see an error message. If WP_DEBUG_LOG is also enabled, the error message will appear in the /wp-content/debug.log file.

Let’s look at an example of core code where I removed like_escape() and implemented the new function $wpdb->esc_like().

3.9 Old Style

$search_orderby_s = like_escape( esc_sql( $q['s'] ) );
$search_orderby .= "WHEN $wpdb->posts.post_title LIKE '%{$search_orderby_s}%' THEN 1 ";

What did this do? It was an old snippet from /wp-includes/query.php that set up a search for post titles. The input $q['s'] was escaped using two functions before it was added to the post_title LIKE expression. Now let’s see how I replaced that snippet in the next version.

4.0 New Style

$like = '%' . $wpdb->esc_like( $q['s'] ) . '%';
$search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 1 ", $like );

There are two important differences to notice.

  • I changed the like_escape() call to $wpdb->esc_like().
  • I changed the esc_sql() call to $wpdb->prepare().

The second change is important because esc_sql() is not secure if it is called before, or inside, the call to the new function $wpdb->esc_like(). By relying on the preferred style of the function prepare(), I can easily see that each instance of $wpdb->esc_like() will run first instead of last.

4.0 Alternative Style

Here is something that still works, but I avoided using it. Notice the old query is unchanged. It is critically important to call the two escaping functions in the correct order when using $wpdb->esc_like().

$search_orderby_s = esc_sql( $wpdb->esc_like( $q['s'] ) ); // This is the correct order.
$search_orderby .= "WHEN $wpdb->posts.post_title LIKE '%{$search_orderby_s}%' THEN 1 ";

How Should I Get My Code Ready for 4.0?

The nice thing about deprecated functions is that you can still use them and they don’t change. Your existing code should work fine.

When you write new code, remember that using $wpdb->esc_like() is not compatible with WordPress 3.9. This should be avoided if you need compatibility with old versions. When you are ready to adopt 4.0 as your minimum version, consider using the new function.

If you have a specific need for the new function in old versions of WordPress, I suggest copying the new function into your plugin under a different name. This would be the simplest solution, but rarely necessary.

Why Did like_escape() Change to $wpdb->esc_like()?

There were several problems with the old function that could not be fixed.

  • Documentation said the function’s output was safe to use in SQL queries. That was not correct.
  • The function’s output was not fully compatible with LIKE expressions in MySQLMySQL MySQL is a relational database management system. A database is a structured collection of data where content, configuration and other options are stored. https://www.mysql.com/..
  • The function had been used many different ways in core code, some of which were incompatible with the desired output.
  • Changing the old function instead of creating a new one would have caused many security problems in plugins.
  • The function was related to $wpdb because of its MySQL syntax, which does not work on other databases.

Is There a Security Problem with like_escape()?

The old function like_escape() was not intended to be used in any security sensitive context. There are no security problems when it is used correctly.

With that said, I am concerned that plugin authors frequently confused the old function like_escape() with esc_sql(), which was used for security. The documentation for like_escape() was misleading and very confusing about this point.

Just remember, like_escape() does not provide any security for your database!

So What Does $wpdb->esc_like() Do Anyway?

Whenever user input or other raw data are copied into a WordPress query, the data must be escaped using $wpdb->prepare() or esc_sql(). This prevents certain characters, such as quotes, from getting confused with SQL commands.

In a LIKE expression, there are additional special characters that are used as wildcards to search for partial matches in the database. Those wildcard characters have to be escaped from the user input so that they are not confused with the wildcards added by the programmer.

Before adding user input to this type of search query, $wpdb->esc_like() should be called for compatibility, and then $wpdb->prepare() must be called for security, in that order.

How to Use $wpdb in Functions

It is very rare to use $wpdb->esc_like() without also running a query. But just in case you want to …

function my_search( $input ) {
    global $wpdb;
    $escaped = $wpdb->esc_like( $input );
    ...
}

… remember to reference $wpdb as a global variable.

#4-0, #database, #dev-notes, #query, #security

Announcing a secure SWFUpload fork

The WordPress security team has officially forked the long-abandoned SWFUpload project and is strongly encouraging all web developers who use SWFUpload to update.

We strongly suggest you do not use SWFUpload. But if you must, use this fork. You can find it on GitHubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ at github.com/wordpress/secure-swfupload.

WordPress does not use SWFUpload, but we continue to include it in WordPress coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. for plugins that have yet to be updated to use Plupload, our upload library of choice. Plupload is written and actively maintained by Moxiecode, the developers of TinyMCE.

We do not condone the use of abandonware. We only wish to make the web a better place by ensuring that developers have access to a secure version of SWFUpload, when the only alternative may be to use insecure code.

This is a fork of SWFUpload 2.2.0.1 and includes cross-site scripting fixes that have been reported by Szymon Gruszecki (CVE-2013-2205 and CVE-2012-2399), and Neal Poole and Nathan Partlan (CVE-2012-3414). It also includes fixes from Yelp’s engineering team for CVE-2012-2399.

WordPress 3.5.2, released moments ago, includes fixes for CVE-2013-2205 and CVE-2012-2399. WordPress 3.3.2 (2012-04-20) included a fix for CVE-2012-3414 and an incomplete fix for CVE-2012-2399.

If you think you have found a vulnerability in this fork of SWFUpload, we appreciate your help in disclosing it to us responsibly. Please email reports of security vulnerabilities to swfupload-security AT wordpress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/. These reports will be reviewed by the WordPress security team and by security researchers contributing to this project, including Neal and Szymon.

#security, #swfupload

The published exploit for WordPress 3.0.4 isn’t accurate

We were informed yesterday of a published vulnerability for WordPress 3.0.4, “Stored XSS (via Editor role)”.

This is an invalidinvalid A resolution on the bug tracker (and generally common in software development, sometimes also notabug) that indicates the ticket is not a bug, is a support request, or is generally invalid. report. (Edit: The exploit has been delisted by the database.)

The dead giveaway was the title: “via Editor role.” In WordPress, users with the role of Editor or Administrator have the ability to post unfiltered HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers.. It has always been like this.

From the Security FAQ on the Codex:

Users with Administrator or Editor privileges are allowed to publish unfiltered HTML in post titles and content. WordPress is, after all, a publishing tool, and people need to be able to include whatever markup they need to communicate. Users with lesser privileges are not allowed to post unfiltered content.

We also issue a warning for security researchers, which wasn’t followed here:

If you are running security tests against WordPress, use a lesser privileged user so that all content is filtered.

How to change this behavior

In multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site, only super administrators can publish unfiltered HTML. All other users are considered untrusted in this case, as they can be administrators for their own sites. (There is a pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party to restore unfiltered HTML to editors and regular administrators in this case, if you trust those users: Unfiltered MU.)

There’s a constant you can use to disallow unfiltered HTML for everyone, including administrators and super administrators. To disallow unfiltered HTML for all users, you can add this to wp-config.php:

define( 'DISALLOW_UNFILTERED_HTML', true );

Filtered HTML for Editors

To deny unfiltered HTML for Editors, try the Filtered HTML for Editors plugin, which I put together today. The description and FAQ go into much of what was covered here.

How to report security vulnerabilities

Standard practice when finding a security vulnerability is to privately notify the vendor and give them an opportunity to respond and prepare a fix for public release. It’s the concept of responsible disclosure. We’ll always credit responsible disclosure in the release announcement as the person requests, such as with a link to your blogblog (versus network, site).

For WordPress, suspected vulnerabilities can be privately emailed to our security team at security@wordpress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/.

Unfortunately, not everyone follows responsible disclosure. In the case of 3.0.4, an exploit published regarding 3.0.3 forced our hand to release the fix we had been privately testing (thanks to responsible disclosure). This can sometimes force our hand in very bad ways — the fixes included in 3.0.4 were very complicated and involved more than a hundred hours of work from more than a dozen individuals. Had we rushed a release due to a public announcement, we might have missed something.

Not following responsible disclosure also prevents us from responding to invalid reports. Unfiltered HTML results in false reports every so often. The fact that this was published as an exploit, without any confirmation or notification, only contributes to FUD and perception issues.

The status of WordPress 3.0.4

This all said, there are currently no known vulnerabilities for WordPress 3.0.4. I’ll go knock on wood now.

#security

Deprecated clean_url() in favor of esc_u…

Deprecated clean_url() in favor of esc_url(), and deprecated sanitize_url() in favor of esc_url_raw().

#api, #escaping, #esc_url_raw, #security

Deprecated wp_specialchars() in favor of…

Deprecated wp_specialchars() in favor of esc_html() (also: esc_html__() and esc_html_e()). Using wp_specialchars() with more than one param works for backwards compat. Also, esc_html() (or wp_specialchars() with one param) escapes quotes, just like esc_attr(). This buys security for pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party authors who were mistakenly using a one-param wp_specialchars() call in an HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. attribute. See this wp-hackers message for more detail.

#api, #escaping, #security

Standardizing and shortening the WP secu…

Standardizing and shortening the WP security escaping functions.

attribute_escape() is now esc_attr()

Additionally, you can do attribute escaping and translationtranslation The process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. in one go. Just add the translation function to the end. Like so:

  • esc_attr__() — translate and return, attribute-escaped.
  • esc_attr_e() — translate and echo, attribute-escaped.

Will be following up with esc_html (with __() and _e() variants), esc_url(), maybe some more. Will be nice, short, predictable, and allow you do translate/escape in one go without a lot of nested parenthesis.

#api, #escaping, #security

The auth cookies are now HTTPonly in tru …

The auth cookies are now HTTPonly in trunktrunk A directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running "trunk", then you are on the latest revision..

#security

Need a secret key for your wp-config.php …

Need a secret key for your wp-config.php? Get one here

#security