to forge legitimate requests, often from a different site. • Can your code tell the difference between • <form action="process.php"> <input type="hidden" name="action" value="delete" /> <input type="hidden" name="id" value="42" /> <input type="submit" /> </form> • and • <img src="//target.io/admin/process.php?action=delete&id=42" /> [ 14 ]
• 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 ]
→ <input type="hidden" name="_nonce" value="JD7ANaoKG" /> <input type="hidden" name="action" value="delete" /> <input type="hidden" name="id" value="42" /> <input type="submit" /> </form> • The rotating nonce cannot be anticipated. • <img src="//target.io/admin/process.php?action=delete&id=42&_nonce=…………?" /> • 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 ]
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 ]
Again, if we try … • /page?id=X"><script>alert('XSS');</script><" • This time, it becomes … • <div id="X"><script>alert('XSS&# 039;);</script><""> [ 20 ]
• 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 ]
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 ]
(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 ]
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 ]
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 ]
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 ]
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 ]
– 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 ]
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 ]
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 ]