Download - WordPress Security - WordCamp Phoenix
Secure Coding with WordPress
Mark Jaquith“JAKE-with”
The state of WordPress plugin
security is...
Problem #1
Lack of awareness
Problem #2
Apathy
Goals1. How to thwart the three most common attacks
2. Two useful principles
3. Common mistakes to avoid
I want you to learn the following:
Attack #1
SQL Injection
$wpdb->query( "UPDATE $wpdb->posts SET post_title = '$newtitle' WHERE ID = $my_id");
$wpdb->update()
$wpdb->update( $wpdb->posts, array( 'post_title' => $newtitle ), array( 'ID' => $my_id ));
$sets = array( 'post_title' => $newtitle, 'post_content' => $newcontent);
$wheres = array( 'post_type' => 'post', 'post_name' => $my_name);
$wpdb->update( $wpdb->posts, $sets, $wheres );
$wpdb->insert( $table, $data )
$wpdb->prepare()
$wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_name = %s OR ID = %d", $some_name, $some_id);
• Powered by sprintf(), but only %s and %d are supported right now
• Do not quote %s — use %s, NOT '%s'
• Does the escaping for you
Rule #1
Escape Late
Attack #2
XSS(Cross-Site Scripting)
<h1><?php echo $title ?><h1>
$title = '<script>pwnage();</script>';
Rule #2
Anything that isn’t hardcoded
is suspect
Rule #2 (revised)
Everythingis suspect
Easy as...
esc_html()
<h1><?php echo esc_html( $title ); ?></h1>
<?php $title = '" onmouseover="pwnd();'; ?><a href="#wordcamp" title="<?php echo $title; ?>">Link Text</a>
esc_attr()
<?php $title = '" onmouseover="pwnd();'; ?><a href="#wordcamp" title="<?php echo esc_attr( $title ); ?>">Link Text</a>
<?php $url = 'javascript:pwnd()'; ?><a href="<?php echo $url; ?>">Link Text</a>
esc_url()
esc_url_raw()
esc_js()
<script>var foo = '<?php echo esc_js( $unsafe ); ?>';</script>
esc_textarea()
wp_filter_kses()
Attack #3
CSRFCross-site Request Forgery
Authorizationvs.
Intention
Noncesaction-, object-, & user-specific
time-limited secret keys
Specific to •WordPress user
•Action attempted
•Object of attempted action
•Time window
wp_nonce_field( 'plugin-action_object' )
<form action="process.php" method="post"><?phpwp_nonce_field('plugin-action_object');?>...</form>
check_admin_referer( 'plugin-action_object' );
Still need to use current_user_can()
CSRF for Ajax/XHR
// 1. On the front end$nonce = wp_create_nonce( 'your_action' );
// 2. add &_ajax_nonce=$nonce to your// post/get vars
// 3. On the backendcheck_ajax_referer( 'your_action' );
Stupid shit I see all the time
eval()
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>">
<a href="<?php echo $home; ?>" title="<?php echo $title; ?>"><?php echo $text; ?></a><script>var foo = '<?php echo $var; ?>';</script>
<a href="<?php echo esc_url( $home ); ?>" title="<?php echo esc_attr( $title ); ?>"><?php echo esc_html( $text ); ?></a><script>var foo = '<?php echo esc_js( $var ); ?>';</script>
Thanks!
Mark Jaquith“JAKE-with”