secure coding with wordpress (barcamp orlando 2009)
DESCRIPTION
Slightly modified version of my Secure Coding with WordPress presentation for BarCamp Orlando 2009.TRANSCRIPT
Secure Coding with WordPress
Mark Jaquithmarkjaquith.com
coveredwebservices.com
XSSCSRFSQL injection
privilege escalation
shell execution
Plugin security is hit-or-miss
Mostly miss
SQL Injection
<?php$wpdb->query( "UPDATE $wpdb->posts SET post_title = '$newtitle' WHERE ID = $my_id" );?>
<?php$newtitle = $wpdb->escape( $newtitle );$my_id = absint( $my_id );
$wpdb->query( "UPDATE $wpdb->posts SET post_title = '$newtitle' WHERE ID = $my_id" );?>
$wpdb->update()
<?php$wpdb->update( $wpdb->posts, array( 'post_title' => $newtitle ), array( 'ID' => $my_id ) );?>
$wpdb->insert()
<?php$wpdb->insert( $wpdb->posts, array( 'post_title' => $newtitle ) );?>
<?php$wpdb->update( $wpdb->posts, array( 'post_title' => $newtitle, 'post_content' => $newcontent ), array( 'ID' => $my_id, 'post_title' => $old_title ) );?>
<?php$post_title = 'New Title';$wheres['ID'] = 123;$wheres['post_title'] = 'Old Title';$wpdb->update( $wpdb->posts, compact( 'post_title' ), $wheres );?>
$wpdb->prepare()
<?php$title = 'Post Title';$ID = 123;$content = $wpdb->get_var( $wpdb->prepare( "SELECT post_content FROM $wpdb->posts WHERE post_title = %s AND ID = %d", $title, $ID ) );?>
•Uses sprintf() formatting
•%s for strings
•%d for integers
•You should not quote or escape
Escapelate
XSS
<h1><?php echo $title;?></h1>
<?php $title = '<script> pwnage(); </script>'?><h1><?php echo $title;?></h1>
Anything that isn’t hardcoded
is suspect
Better:Everything is suspect
wp_specialchars()
<?php $title = '<script> pwnage(); </script>'?><h1><?php echo wp_specialchars( $title );?></h1>
<?php$title = '" onmouseover="pwnd();';?><a href="#wordcamp" title="<?php echo wp_specialchars( $title );?>">Link Text</a>
attribute_escape()
<?php$title = '" onmouseover="pwnd();';?><a href="#wordcamp" title="<?php echo attribute_escape( $title );?>">Link Text</a>
<?php $url = 'javascript:pwnage();';?><a href="<?php echo attribute_escape( $url );?>">Link Text</a>
clean_url()
<?php $url = 'javascript:pwnage();';?><a href="<?php echo clean_url( $url );?>">Link Text</a>
sanitize_url(), sister of clean_url()
js_escape()
CSRF
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()
<form action="process.php" method="post"><?php wp_nonce_field('plugin-action_object');?>
...</form>
check_admin_referer( )
<?php// before output goes to browsercheck_admin_referer('plugin- action_object');?>
Still need to use current_user_can()
AJAXCSRF
• wp_create_nonce( 'your_action' );
• &_ajax_nonce=YOUR_NONCE
• check_ajax_referer( 'your_action' );
Privilege Escalation
current_user_can()
Set your salts!http://api.wordpress.org/secret-key/1.1/
Stupid shit I see all the time
exec()
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>">
Thank you!