51
Secure Coding with WordPress Mark Jaquith “JAKE-with” @markjaquith m@rkj.me markjaquith.com

WordPress Security - WordCamp Phoenix

Embed Size (px)

Citation preview

Page 1: WordPress Security - WordCamp Phoenix

Secure Coding with WordPress

Mark Jaquith“JAKE-with”

@[email protected]

Page 2: WordPress Security - WordCamp Phoenix

The state of WordPress plugin

security is...

Page 3: WordPress Security - WordCamp Phoenix
Page 4: WordPress Security - WordCamp Phoenix

Problem #1

Lack of awareness

Page 5: WordPress Security - WordCamp Phoenix

Problem #2

Apathy

Page 6: WordPress Security - WordCamp Phoenix

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:

Page 7: WordPress Security - WordCamp Phoenix

Attack #1

SQL Injection

Page 8: WordPress Security - WordCamp Phoenix

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

Page 9: WordPress Security - WordCamp Phoenix
Page 10: WordPress Security - WordCamp Phoenix

$wpdb->update()

Page 11: WordPress Security - WordCamp Phoenix

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

Page 12: WordPress Security - WordCamp Phoenix

$sets = array( 'post_title' => $newtitle, 'post_content' => $newcontent);

$wheres = array( 'post_type' => 'post', 'post_name' => $my_name);

$wpdb->update( $wpdb->posts, $sets, $wheres );

Page 13: WordPress Security - WordCamp Phoenix

$wpdb->insert( $table, $data )

Page 14: WordPress Security - WordCamp Phoenix

$wpdb->prepare()

Page 15: WordPress Security - WordCamp Phoenix

$wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_name = %s OR ID = %d", $some_name, $some_id);

Page 16: WordPress Security - WordCamp Phoenix

• 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

Page 17: WordPress Security - WordCamp Phoenix

Rule #1

Escape Late

Page 18: WordPress Security - WordCamp Phoenix

Attack #2

XSS(Cross-Site Scripting)

Page 19: WordPress Security - WordCamp Phoenix

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

Page 20: WordPress Security - WordCamp Phoenix

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

Page 21: WordPress Security - WordCamp Phoenix

Rule #2

Anything that isn’t hardcoded

is suspect

Page 22: WordPress Security - WordCamp Phoenix

Rule #2 (revised)

Everythingis suspect

Page 23: WordPress Security - WordCamp Phoenix

Easy as...

Page 24: WordPress Security - WordCamp Phoenix

esc_html()

Page 25: WordPress Security - WordCamp Phoenix

<h1><?php echo esc_html( $title ); ?></h1>

Page 26: WordPress Security - WordCamp Phoenix

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

Page 27: WordPress Security - WordCamp Phoenix

esc_attr()

Page 28: WordPress Security - WordCamp Phoenix

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

Page 29: WordPress Security - WordCamp Phoenix

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

Page 30: WordPress Security - WordCamp Phoenix

esc_url()

Page 31: WordPress Security - WordCamp Phoenix

esc_url_raw()

Page 32: WordPress Security - WordCamp Phoenix

esc_js()

Page 33: WordPress Security - WordCamp Phoenix

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

Page 34: WordPress Security - WordCamp Phoenix

esc_textarea()

Page 35: WordPress Security - WordCamp Phoenix

wp_filter_kses()

Page 36: WordPress Security - WordCamp Phoenix

Attack #3

CSRFCross-site Request Forgery

Page 37: WordPress Security - WordCamp Phoenix

Authorizationvs.

Intention

Page 38: WordPress Security - WordCamp Phoenix

Noncesaction-, object-, & user-specific

time-limited secret keys

Page 39: WordPress Security - WordCamp Phoenix

Specific to •WordPress user

•Action attempted

•Object of attempted action

•Time window

Page 40: WordPress Security - WordCamp Phoenix

wp_nonce_field( 'plugin-action_object' )

Page 41: WordPress Security - WordCamp Phoenix

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

Page 42: WordPress Security - WordCamp Phoenix

check_admin_referer( 'plugin-action_object' );

Page 43: WordPress Security - WordCamp Phoenix

Still need to use current_user_can()

Page 44: WordPress Security - WordCamp Phoenix

CSRF for Ajax/XHR

Page 45: WordPress Security - WordCamp Phoenix

// 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' );

Page 46: WordPress Security - WordCamp Phoenix

Stupid shit I see all the time

Page 47: WordPress Security - WordCamp Phoenix

eval()

Page 48: WordPress Security - WordCamp Phoenix

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

Page 49: WordPress Security - WordCamp Phoenix

<a href="<?php echo $home; ?>" title="<?php echo $title; ?>"><?php echo $text; ?></a><script>var foo = '<?php echo $var; ?>';</script>

Page 50: WordPress Security - WordCamp Phoenix

<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>

Page 51: WordPress Security - WordCamp Phoenix

Thanks!

Mark Jaquith“JAKE-with”

@[email protected]