54
Writing Secure Plugins Mark Jaquith @markjaquith markjaquith.com coveredwebservices.com Saturday, November 14, 2009

Writing Secure Plugins — WordCamp New York 2009

Embed Size (px)

DESCRIPTION

How to write secure plugins, from my presentation at WordCamp New York 2009.

Citation preview

Page 1: Writing Secure Plugins — WordCamp New York 2009

Writing Secure Plugins

Mark Jaquith

@markjaquithmarkjaquith.com

coveredwebservices.com

Saturday, November 14, 2009

Page 2: Writing Secure Plugins — WordCamp New York 2009

XSSCSRFSQL injection

privilege escalation

shell execution

Saturday, November 14, 2009

Page 3: Writing Secure Plugins — WordCamp New York 2009

Plugin security is hit-or-miss

Saturday, November 14, 2009

Page 4: Writing Secure Plugins — WordCamp New York 2009

Mostly miss

Saturday, November 14, 2009

Page 5: Writing Secure Plugins — WordCamp New York 2009

SQL Injection

Saturday, November 14, 2009

Page 6: Writing Secure Plugins — WordCamp New York 2009

<?php$wpdb->query( "UPDATE $wpdb->posts SET post_title = '$newtitle' WHERE ID = $my_id" );?>

Saturday, November 14, 2009

Page 7: Writing Secure Plugins — WordCamp New York 2009

<?php$newtitle = esc_sql( $newtitle );$my_id = absint( $my_id );

$wpdb->query( "UPDATE $wpdb->posts SET post_title = '$newtitle' WHERE ID = $my_id" );?>

Saturday, November 14, 2009

Page 8: Writing Secure Plugins — WordCamp New York 2009

$wpdb->update()

Saturday, November 14, 2009

Page 9: Writing Secure Plugins — WordCamp New York 2009

<?php$wpdb->update( $wpdb->posts, array( 'post_title' => $newtitle ), array( 'ID' => $my_id ) );?>

Saturday, November 14, 2009

Page 10: Writing Secure Plugins — WordCamp New York 2009

$wpdb->insert()

Saturday, November 14, 2009

Page 11: Writing Secure Plugins — WordCamp New York 2009

<?php$wpdb->insert( $wpdb->posts, array( 'post_title' => $newtitle ) );?>

Saturday, November 14, 2009

Page 12: Writing Secure Plugins — WordCamp New York 2009

<?php$wpdb->update( $wpdb->posts, array( 'post_title' => $newtitle, 'post_content' => $newcontent ), array( 'ID' => $my_id, 'post_title' => $old_title ) );?>

Saturday, November 14, 2009

Page 13: Writing Secure Plugins — WordCamp New York 2009

<?php$post_title = 'New Title';$wheres['ID'] = 123;$wheres['post_title'] = 'Old Title';$wpdb->update( $wpdb->posts, compact( 'post_title' ), $wheres );?>

Saturday, November 14, 2009

Page 14: Writing Secure Plugins — WordCamp New York 2009

$wpdb->prepare()

Saturday, November 14, 2009

Page 15: Writing Secure Plugins — WordCamp New York 2009

<?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 ) );?>

Saturday, November 14, 2009

Page 16: Writing Secure Plugins — WordCamp New York 2009

•Uses sprintf() formatting

•%s for strings

•%d for integers

•You should not quote or escape

Saturday, November 14, 2009

Page 17: Writing Secure Plugins — WordCamp New York 2009

Escapelate

Saturday, November 14, 2009

Page 18: Writing Secure Plugins — WordCamp New York 2009

XSSSaturday, November 14, 2009

Page 19: Writing Secure Plugins — WordCamp New York 2009

<h1><?php echo $title;?></h1>

Saturday, November 14, 2009

Page 20: Writing Secure Plugins — WordCamp New York 2009

<?php $title = '<script> pwnage(); </script>'?>

<h1><?php echo $title;?></h1>

Saturday, November 14, 2009

Page 21: Writing Secure Plugins — WordCamp New York 2009

Anything that isn’t hardcoded

is suspect

Saturday, November 14, 2009

Page 22: Writing Secure Plugins — WordCamp New York 2009

Better:Everything is suspect

Saturday, November 14, 2009

Page 23: Writing Secure Plugins — WordCamp New York 2009

Saturday, November 14, 2009

Page 24: Writing Secure Plugins — WordCamp New York 2009

esc_html()

Saturday, November 14, 2009

Page 25: Writing Secure Plugins — WordCamp New York 2009

<?php $title = '<script> pwnage(); </script>'?><h1><?php echo esc_html( $title );?></h1>

Saturday, November 14, 2009

Page 26: Writing Secure Plugins — WordCamp New York 2009

<?php$title = '" onmouseover="pwnd();';?><a href="#wordcamp" title="<?php echo $title;?>">Link Text</a>

Saturday, November 14, 2009

Page 27: Writing Secure Plugins — WordCamp New York 2009

esc_attr()

Saturday, November 14, 2009

Page 28: Writing Secure Plugins — WordCamp New York 2009

<?php$title = '" onmouseover="pwnd();';?><a href="#wordcamp" title="<?php echo esc_attr( $title );?>">Link Text</a>

Saturday, November 14, 2009

Page 29: Writing Secure Plugins — WordCamp New York 2009

<?php $url = 'javascript:pwnage();';?><a href="<?php echo esc_attr( $url );?>">Link Text</a>

WRONG

Saturday, November 14, 2009

Page 30: Writing Secure Plugins — WordCamp New York 2009

esc_url()

Saturday, November 14, 2009

Page 31: Writing Secure Plugins — WordCamp New York 2009

<?php $url = 'javascript:pwnage();';?><a href="<?php echo esc_url( $url );?>">Link Text</a>

Saturday, November 14, 2009

Page 32: Writing Secure Plugins — WordCamp New York 2009

esc_url_raw(), sister of esc_url()

Saturday, November 14, 2009

Page 33: Writing Secure Plugins — WordCamp New York 2009

esc_ js()

Saturday, November 14, 2009

Page 34: Writing Secure Plugins — WordCamp New York 2009

<script>var foo = '<?php echo esc_js( $bar ); ?>';</script>

Saturday, November 14, 2009

Page 35: Writing Secure Plugins — WordCamp New York 2009

CSRFSaturday, November 14, 2009

Page 36: Writing Secure Plugins — WordCamp New York 2009

Authorizationvs.

IntentionSaturday, November 14, 2009

Page 37: Writing Secure Plugins — WordCamp New York 2009

Noncesaction-, object-,

user-specific time limited secret keys

Saturday, November 14, 2009

Page 38: Writing Secure Plugins — WordCamp New York 2009

Specific to •WordPress user

•Action attempted

•Object of attempted action

•Time window

Saturday, November 14, 2009

Page 39: Writing Secure Plugins — WordCamp New York 2009

wp_nonce_field()

Saturday, November 14, 2009

Page 40: Writing Secure Plugins — WordCamp New York 2009

<form action="process.php" method="post"><?php wp_nonce_field('plugin-action_object');?>

...</form>

Saturday, November 14, 2009

Page 41: Writing Secure Plugins — WordCamp New York 2009

check_admin_referer( )

Saturday, November 14, 2009

Page 42: Writing Secure Plugins — WordCamp New York 2009

<?php// before output goes to browsercheck_admin_referer('plugin- action_object');?>

Saturday, November 14, 2009

Page 43: Writing Secure Plugins — WordCamp New York 2009

Still need to use current_user_can()

Saturday, November 14, 2009

Page 44: Writing Secure Plugins — WordCamp New York 2009

AJAXCSRF

Saturday, November 14, 2009

Page 45: Writing Secure Plugins — WordCamp New York 2009

• wp_create_nonce( 'your_action' );

• &_ajax_nonce=YOUR_NONCE

• check_ajax_referer( 'your_action' );

Saturday, November 14, 2009

Page 46: Writing Secure Plugins — WordCamp New York 2009

Privilege Escalation

Saturday, November 14, 2009

Page 47: Writing Secure Plugins — WordCamp New York 2009

current_user_can()

Saturday, November 14, 2009

Page 48: Writing Secure Plugins — WordCamp New York 2009

Set your salts!http://api.wordpress.org/secret-key/1.1/

Saturday, November 14, 2009

Page 49: Writing Secure Plugins — WordCamp New York 2009

Stupid shit I see all the time

Saturday, November 14, 2009

Page 50: Writing Secure Plugins — WordCamp New York 2009

exec()

Saturday, November 14, 2009

Page 51: Writing Secure Plugins — WordCamp New York 2009

<form action="<?php echo $_SERVER['REQUEST_URI']; ?>">

Saturday, November 14, 2009

Page 52: Writing Secure Plugins — WordCamp New York 2009

<a href="<?php echo $url; ?>" title="<?php echo $title; ?>"><?php echo $text; ?></a>

<script>var foo = '<?php echo $js; ?>';</script>

Saturday, November 14, 2009

Page 53: Writing Secure Plugins — WordCamp New York 2009

<a href="<?php echo esc_url( $url ); ?>" title="<?php echo esc_attr( $title ); ?>"><?php echo esc_html( $text ); ?></a>

<script>var foo = '<?php echo esc_js( $js ); ?>';</script>

Saturday, November 14, 2009

Page 54: Writing Secure Plugins — WordCamp New York 2009

Discussion

Saturday, November 14, 2009