Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Code with Care : Write Secure Themes and Plugins

Code with Care : Write Secure Themes and Plugins

Write secure WordPress themes and plugins. Presentation from WordCamp St. Louis 2014.

Rachel Baker

March 01, 2014
Tweet

More Decks by Rachel Baker

Other Decks in Technology

Transcript

  1. XSS (Cross-Site Scripting) Cross-Site Scripting (XSS) attacks are a type

    of injection problem, in which malicious scripts are injected into the otherwise benign and trusted web sites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. Source: https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
  2. CSRF (Cross-Site Request Forgery) CSRF is an attack which forces

    an end user to execute unwanted actions on a web application in which he/she is currently authenticated. With a little help of social engineering (like sending a link via email/ chat), an attacker may trick the users of a web application into executing actions of the attacker's choosing. Source: https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
  3. Step 1: Filter Input
 Step 2: Escape Output
 Step 3:

    Verify Data Source
 
 Step 4: Profit
  4. Filter Input •Distrust data from any source (even yourself). •Understand

    the context of the data being input. •Validate your expectations, never assume. •Correct any formatting issues that may exist. •Process input filters before saving to the database. How?
  5. Location Name Input // sanitize the location name input to

    only allow a text string ! // and strip HTML tags.! $safe_name = sanitize_text_field( $_POST['_wcstl_name'] );
 update_post_meta( $post_id, '_wcstl_name', $safe_name );!
  6. Location Email Input // filter then sanitize the email address

    input.! if ( is_email( $_POST['_wcstl_email'] ) ) {! ! $safe_email = sanitize_email( $_POST['_wcstl_email'] );
 ! update_post_meta( $post_id, '_wcstl_email', $safe_email );! }
  7. Location Phone 
 Number Input // correct phone number input

    to remove any non-numerical characters.! $format_phone_input = preg_replace( "/\D+/","", $_POST['_wcstl_phone'] );! // filter any added numbers from the input.! if ( strlen( $format_phone_input ) > 10 ) {! ! $format_phone_input = substr( $format_phone_input, 0, 10 );! }! // sanitize phone number input.! $safe_phone = sanitize_text_field( $format_phone_input );
 update_post_meta( $post_id, '_wcstl_phone', $safe_phone );!
  8. Location Address Input ! // sanitize the address text input

    based on $allowed_tags.! ! $safe_address = wp_filter_kses( $_POST['_wcstl_address'] );! ! ! ! update_post_meta( $post_id, '_wcstl_address', $safe_address );!
  9. Location Description Input ! // sanitize the description HTML input

    based on post content HTML filter.! ! $safe_description = wp_filter_post_kses( $_POST['_wcstl_description'] );! ! ! ! update_post_meta( $post_id, '_wcstl_description', $safe_description );!
  10. Location Map URL ! // filter any html tags then

    santize the url input.! ! $filter_map_url = wp_strip_all_tags( $_POST['_wcstl_map_url'] );! ! $safe_map_url = esc_url_raw( $filter_map_url );! ! ! ! update_post_meta( $post_id, '_wcstl_map_url', $safe_map_url );!
  11. •Distrust data from any source (even yourself). •Understand the context

    of the data being displayed. •Correct any formatting issues that may exist. •Encode data before display. How? Escape Output
  12. Decode Encoding From < > ( ) # & "


    
 &lt;script&gt; <
 >
 (
 )
 #
 & "
 
 <script> To
  13. Display Location Name <h5>Name:</h5>
 <?php! ! $name = get_post_meta( get_the_ID(),

    '_wcstl_name', true );
 ! echo esc_attr( $name );! ?>! <h5>Name:</h5>! Washington University in St. Louis!
  14. Display Location Email <h5>Email:</h5>
 <?php! ! $email= get_post_meta( get_the_ID(), '_wcstl_email',

    true );! ! $email = antispambot( $email );
 ! echo esc_html( $email );! ?>! <h5>Email:</h5>! &#115;tl&#111;uis&#064;w&#111;&#114; &#100;ca&#109;p&#046;or&#103;!
  15. Display Location Phone Number <h5>Phone:</h5>
 <?php ! ! $phone =

    get_post_meta( get_the_ID(), '_wcstl_phone', true );! 
 ! echo esc_attr( $phone);! ?>! <h5>Phone:</h5>! 8006380700!
  16. Display Location 
 Address <h5>Address:</h5>
 <?php! ! $address = get_post_meta(

    get_the_ID(), '_wcstl_address', true );! ! $address = wptexturize( $address );! ! $address = convert_chars( $address );
 ! echo wpautop( $address );! ?>! <p>One Brookings Drive<br />! St. Louis, MO 63130</p>!
  17. Display Location Description <h5>Description:</h5>
 <?php! ! $description = get_post_meta( get_the_ID(),

    '_wcstl_description', true );
 ! $description = wptexturize( $description );! ! $description = convert_chars( $description );
 ! echo wpautop( $description );! ?>! <div class="wcstl-example">! ! <p>WordCamp St. Louis 2014 will be hosted on the beautiful Danforth Campus of Washington University in the Laboratory Sciences Building (map).</p>! </div>!
  18. Display Location 
 Map URL <h5>Map:</h5>
 <?php! ! $map_url =

    get_post_meta( get_the_ID(), '_wcstl_map_url', true );
 ! echo esc_url( $map_url); ! ?>! <h5>Map:</h5>! https://www.google.com/maps/place/1+Brookings+Dr/ @38.652088,-90.3077647,16z/data=!4m2!3m1! 1s0x87d8cab20b777057:0xf54f7dc56315b57!
  19. Display Location Meta Boxes Source: https://github.com/rachelbaker/wcstl-demo/blob/ master/wcstl2014-secured.php#L37 function wcstl_display_location_meta_boxes( $post

    ) {! ! // Get all location meta values for the current post.! ! $name_value! ! = get_post_meta( $post->ID, '_wcstl_name', true );! ! $email_value! ! = get_post_meta( $post->ID, '_wcstl_email', true );! ! $phone_value! ! = get_post_meta( $post->ID, '_wcstl_phone', true );! ! $address_value! ! = get_post_meta( $post->ID, '_wcstl_address', true );! ! $description_value! = get_post_meta( $post->ID, '_wcstl_description', true );! ! $map_url_value! ! = get_post_meta( $post->ID, '_wcstl_map_url', true );! ! ! // encode text to display in rich text editor.! ! $address_value! ! = wp_richedit_pre( $address_value );! ! $description_value! = wp_richedit_pre( $description_value );! ! ! // display hidden nonce field for CSRF protection.! ! wp_nonce_field( 'wcstl_location_save_meta','wcstl_meta_nonce' );! ! ! // output Location Information meta form fields on "Edit Post" screen.! ! $location_meta_fields = '<p><label for="_wcstl_name">Location Name (text string only)</label></p>! ! ! <input type="text" size="80" id="_wcstl_name" name="_wcstl_name" value="' . esc_attr( $name_value ) . '" /><p>! ! ! <label for="_wcstl_email">Email Address (valid email address only)</label></p>! ! ! <input type="text" size="20" id="_wcstl_email" name="_wcstl_email" value="' . esc_attr( $email_value ) . '" />! ! ! <p><label for="_wcstl_phone">Phone Number (10 digit phone number only)</label></p>! ! ! <input type="text" size="10" id="_wcstl_phone" name="_wcstl_phone" value="' . esc_attr( $phone_value ) . '" />! ! ! <p><label for="_wcstl_address">Address (Basic HTML Allowed)</label></p>! ! ! <textarea style="width:90%; height:60px;" cols="40" id="_wcstl_address" name="_wcstl_address">' . esc_html( $address_value ) . '</textarea>! ! ! <p><label for="_wcstl_description">Description (Advanced HTML allowed)</label></p>! ! ! <textarea style="width:90%; height:160px;" cols="40" id="_wcstl_description" name="_wcstl_description">' . esc_html( $description_value ) . '</ textarea>! ! ! <p><label for="_wcstl_map_url">Map URL (url only)</label></p>! ! ! <input size="80" id="_wcstl_map_url" name="_wcstl_map_url" value="' . esc_url( $map_url_value ) . '" />';! ! ! echo $location_meta_fields;! }!
  20. Verify Data Source •Create a nonce field or value anytime

    data will be processed from a form, AJAX request, or URL. •Check the referring source of a processing request. •Confirm the presence and validity of a nonce before processing data from a form, AJAX request, or URL. How?
  21. Create Nonce Field Source: https://github.com/rachelbaker/wcstl-demo/blob/ master/wcstl2014-secured.php#L51 // display hidden nonce

    field for CSRF protection.! wp_nonce_field( 'wcstl_location_save_meta','wcstl_meta_nonce' );!
  22. Verify Referrer and Nonce Value Source: https://github.com/rachelbaker/wcstl-demo/blob/ master/wcstl2014-secured.php#L84 // return

    early if nonce doesn't match.! if ( ! check_admin_referer( 'wcstl_location_save_meta', 'wcstl_meta_nonce' ) ) {! ! 
 ! return $post_id;! }!
  23. Unsure of What to Do? Do as WP Core does!

    https://core.trac.wordpress.org/browser/ tags/3.8.1/src/wp-includes/default- filters.php ! https://core.trac.wordpress.org/browser/ tags/3.8.1/src/wp-includes/ formatting.php
 
 https://core.trac.wordpress.org/browser/ tags/3.8.1/src/wp-includes/kses.php
  24. http://codex.wordpress.org/ Validating_Sanitizing_and_Escaping_User_Data
 
 http://codex.wordpress.org/Data_Validation ! https://codex.wordpress.org/WordPress_Nonces ! http://www.cgisecurity.com/xss-faq.html
 
 https://core.trac.wordpress.org/browser/tags/3.8.1/src/wp-

    includes/formatting.php#L0
 https://www.owasp.org/index.php/ Testing_for_Reflected_Cross_site_scripting_(OWASP-DV-001)
 http://ottopress.com/2010/wp-quickie-kses/ 
 https://codex.wordpress.org/Class_Reference/ wpdb#Protect_Queries_Against_SQL_Injection_Attacks Resources
  25. Questions? Go Cubs Rachel Baker @rachelbaker https://github.com/rachelbaker/ wcstl-demo Demo Code

    Slide Deck https://speakerdeck.com/ rachelbaker/code-with-care-write- secure-themes-and-plugins