Secure Coding With Wordpress (BarCamp Orlando 2009)

3,157 views
3,046 views

Published on

Slightly modified version of my Secure Coding with WordPress presentation for BarCamp Orlando 2009.

Published in: Technology, Business
1 Comment
7 Likes
Statistics
Notes
No Downloads
Views
Total views
3,157
On SlideShare
0
From Embeds
0
Number of Embeds
207
Actions
Shares
0
Downloads
52
Comments
1
Likes
7
Embeds 0
No embeds

No notes for slide

Secure Coding With Wordpress (BarCamp Orlando 2009)

  1. 1. Secure Coding with WordPress Mark Jaquith markjaquith.com coveredwebservices.com
  2. 2. XSS privilege shell execution escalation CSRF SQL injection
  3. 3. Plugin security is hit-or-miss
  4. 4. Mostly miss
  5. 5. SQL Injection
  6. 6. <?php $wpdb->query( quot;UPDATE $wpdb->posts SET post_title = '$newtitle' WHERE ID = $my_idquot; ); ?>
  7. 7. <?php $newtitle = $wpdb->escape( $newtitle ); $my_id = absint( $my_id ); $wpdb->query( quot;UPDATE $wpdb->posts SET post_title = '$newtitle' WHERE ID = $my_idquot; ); ?>
  8. 8. $wpdb->update()
  9. 9. <?php $wpdb->update( $wpdb->posts, array( 'post_title' => $newtitle ), array( 'ID' => $my_id ) ); ?>
  10. 10. $wpdb->insert()
  11. 11. <?php $wpdb->insert( $wpdb->posts, array( 'post_title' => $newtitle ) ); ?>
  12. 12. <?php $wpdb->update( $wpdb->posts, array( 'post_title' => $newtitle, 'post_content' => $newcontent ), array( 'ID' => $my_id, 'post_title' => $old_title ) ); ?>
  13. 13. <?php $post_title = 'New Title'; $wheres['ID'] = 123; $wheres['post_title'] = 'Old Title'; $wpdb->update( $wpdb->posts, compact( 'post_title' ), $wheres ); ?>
  14. 14. $wpdb->prepare()
  15. 15. <?php $title = 'Post Title'; $ID = 123; $content = $wpdb->get_var( $wpdb->prepare( quot;SELECT post_content FROM $wpdb->posts WHERE post_title = %s AND ID = %dquot;, $title, $ID ) ); ?>
  16. 16. •Uses sprintf() formatting •%s for strings •%d for integers •You should not quote or escape
  17. 17. Escape late
  18. 18. XSS
  19. 19. <h1> <?php echo $title; ?> </h1>
  20. 20. <?php $title = '<script> pwnage(); </script>' ?> <h1> <?php echo $title; ?> </h1>
  21. 21. Anything that isn’t hardcoded is suspect
  22. 22. Better: Everything is suspect
  23. 23. wp_specialchars()
  24. 24. <?php $title = '<script> pwnage(); </script>' ?> <h1> <?php echo wp_specialchars( $title ); ?> </h1>
  25. 25. <?php $title = 'quot; onmouseover=quot;pwnd();'; ?> <a href=quot;#wordcampquot; title=quot; <?php echo wp_specialchars( $title ); ?> quot;> Link Text </a>
  26. 26. attribute_escape()
  27. 27. <?php $title = 'quot; onmouseover=quot;pwnd();'; ?> <a href=quot;#wordcampquot; title=quot; <?php echo attribute_escape( $title ); ?> quot;> Link Text </a>
  28. 28. <?php $url = 'javascript:pwnage();'; ?> <a href=quot; <?php echo attribute_escape( $url ); ?> quot;> Link Text </a>
  29. 29. clean_url()
  30. 30. <?php $url = 'javascript:pwnage();'; ?> <a href=quot; <?php echo clean_url( $url ); ?> quot;> Link Text </a>
  31. 31. sanitize_url(), sister of clean_url()
  32. 32. js_escape()
  33. 33. CSRF
  34. 34. Authorization vs. Intention
  35. 35. Nonces action-, object-, user-specific time limited secret keys
  36. 36. Specific to •WordPress user •Action attempted •Object of attempted action •Time window
  37. 37. wp_nonce_field()
  38. 38. <form action=quot;process.phpquot; method=quot;postquot;> <?php wp_nonce_field('plugin-action_object'); ?> ... </form>
  39. 39. check_admin_referer( )
  40. 40. <?php // before output goes to browser check_admin_referer('plugin- action_object'); ?>
  41. 41. Still need to use current_user_can()
  42. 42. AJAX CSRF
  43. 43. • wp_create_nonce( 'your_action' ); • &_ajax_nonce=YOUR_NONCE • check_ajax_referer( 'your_action' );
  44. 44. Privilege Escalation
  45. 45. current_user_can()
  46. 46. Set your salts! http://api.wordpress.org/secret-key/1.1/
  47. 47. Stupid shit I see all the time
  48. 48. exec()
  49. 49. <form action=quot;<?php echo $_SERVER['REQUEST_URI']; ?>quot;>
  50. 50. Thank you!

×