CSRF • Cross-Site Request Forgery attacks involve malicious websites attempting to forge legitimate requests, often from a different site. • Can your code tell the difference between •
CSRF • How do we know the submission is legitimate? • We check for something that only we can provide — a nonce. • NONCE: Number used ONCE. • Nonces in WordPress are valid for 12–24 hours, and are generated from: • the current 12 hour tick, • the action name, • the current user’s ID, • their session token. • It also leverages the unique generated strings in wp-config.php for security. [ 15 ]
• The rotating nonce cannot be anticipated. • • ALSO: Nonces are for intent, not for authentication! They are for validating that the user intended to do an action. Always also check against user caps. [ 16 ]
XSS • Cross-Site Scripting means — in short — that some villain can sneak malicious javascript code into your site, and trick you into running the script. • Anything* you can do, it can do too! • * (nearly) [ 17 ]
XSS • It does a lot more than cause alerts. • It can load up admin pages, extract nonces, and spoof form submissions. • It can use the Plugin and Theme Editor in the admin to write nasty PHP code to your server. • It can change your password without your knowledge. • It can create a new Administrator account for itself. • It can install new plugins and themes. • It can inject malware links and embeds into your posts. [ 21 ]
XSS • Cross-Site Scripting isn’t all-powerful. • Anything that you need to re-authenticate for, it can’t spoof. #31779-core • Anything the currently logged in user can’t do, XSS can’t either. • This is why folks recommend creating yourself an Author or Editor account for every day use, and not doing everything as Administrator. • Rule of : If a sitting at your can do it, so can XSS. ! [ 22 ]
SQLi • So what can SQL Injection do? • DROP (delete) all of the tables in your database. • INSERT new users, posts, etc. • DELETE users, posts, meta. • UPDATE (change) user info, passwords, roles. • Getting access to an Administrator user (either by creating a new one or changing the password of an existing) is normally game over. [ 24 ]
SQLi • ! This code is a simplified version of real code that was once in use by a popular plugin (that shall remain nameless). It is insecure. Do not use it. • $orderby = 'post_title'; $order = 'ASC'; if ( ! empty( $_GET['orderby'] ) { $orderby = esc_sql( sanitize_text_field( $_GET['orderby'] ) ); } if ( ! empty( $_GET['order'] ) ) { $order = esc_sql( strtoupper( sanitize_text_field( $_GET['order'] ) ) ); } $wpdb->get_col( "SELECT `ID` FROM {$wpdb->posts} ORDER BY {$orderby} {$order} LIMIT 10" ); • We’re fetching posts and letting the user change the sorting. • Fairly harmless? #nopenopenope [ 25 ]
SQLi • But what do the functions do? –sanitize_text_field(): Checks for invalid UTF-8, Convert single < characters to entity, strip all tags, remove line breaks, tabs and extra white space, strip octets. • Not really useful (or relevant) to us here. –esc_sql(): Prepares a string for use as an SQL query. This function is a glorified addslashes() that works with arrays. • esc_sql() is also deprecated in favor of using $wpdb->prepare(). It will escape single quotes in values, but as ORDER and ORDERBY aren’t escaped in the query, in this case it’s useless. [ 26 ]
SQLi • The `$wpdb->prepare()` method will take your data, escape it, and then pop them into your query. • $wpdb->prepare( "SELECT * FROM `table` WHERE `str` = %s AND `num` = %d;”, "Sonny's", 3 ); • Becomes… • SELECT * FROM `table` WHERE `str` = 'Sonny\'s' AND `num` = 3; • But you can’t use prepare with order / orderby arguments as they’re not quoted in the query. [ 28 ]
Few ways to avoid this • Developers – There are not many use-cases to write your own SQL code – Use WordPress’ Classes, Objects and Queries • Eg. Use WP_Query instead of writing your own SQL line • Users – Ask your developers to use native WordPress functions [ 29 ]
Take-away • Developers – Don’t trust user input • Users – Ask developers if they have taken appropriate CSRF, XSS, SQLi preventions – Like asking your local butcher if the meat has been through AVA checks [ 30 ]
Sanitisation • Sanitise Early – Because variables can be passed around at any time, sanitise early so you know it’s clean, because other functions that make use of your variable may not have cleaning lines • Understand your content – What content do you want? • Functions – intval() – sanitize_text_field() – https://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data [ 39 ]
Escaping • Escape late – Variable can be used to output to different context – Different context requires different code • Understand the context – What is it going to be used for? • Functions – esc_url – esc_html – https://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Da ta [ 40 ]