SlideShare a Scribd company logo
WRITING SECURE WORDPRESS CODE
BY	
  BRAD	
  WILLIAMS	
  
Brad Williams
@williamsba
h-p://www.slideshare.net/williamsba/wri>ng-­‐secure-­‐wordpress-­‐code-­‐wordcamp-­‐nyc-­‐2014	
  
WHO IS BRAD?
Brad Williams
@williamsba
Brad	
  Williams	
  
	
  
CO-HOST DRADCAST
Brad Williams
@williamsba
TODAY’S TOPICS
Brad Williams
@williamsba
	
  
• Cover	
  the	
  big	
  three	
  exploits	
  
•  SQL	
  Injec>on	
  -­‐	
  SQLi	
  
•  Cross-­‐Site	
  Scrip>ng	
  -­‐	
  XSS	
  
•  Cross-­‐Site	
  Request	
  Forgery	
  –	
  CSRF	
  
• Hack	
  Examples	
  
• Data	
  Valida>on	
  and	
  Sani>za>on	
  
• Resources	
  
TRUST NO ONE
Brad Williams
@williamsba
Golden	
  Rule	
  of	
  Code	
  
Trust	
  No	
  One	
  
TRUST NO ONE
Brad Williams
@williamsba
Consider	
  all	
  data	
  invalid	
  
unless	
  it	
  can	
  be	
  proven	
  valid	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
SQL	
  Injec>on	
  (SQLi)	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
SQL	
  injec*on	
  is	
  a	
  code	
  injec>on	
  technique	
  
in	
  which	
  malicious	
  SQL	
  statements	
  are	
  
inserted	
  into	
  an	
  entry	
  field	
  for	
  execu>on	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
SQL	
  Injec>on	
  Example	
  
	
  global $wpdb;
$ID = $_GET['ID'];
$sql = "SELECT post_title FROM $wpdb->posts WHERE ID = '$ID';";
SELECT	
  post_>tle	
  FROM	
  wp_posts	
  WHERE	
  ID	
  =	
  '5';	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
SQL	
  Injec>on	
  Example	
  
	
  
SELECT	
  post_>tle	
  FROM	
  wp_posts	
  WHERE	
  ID	
  =	
  '';	
  	
  
SELECT	
  *	
  FROM	
  wp_users	
  WHERE	
  1	
  =	
  '1';	
  
global $wpdb;
$ID = "'; SELECT * FROM wp_users WHERE 1 = '1";
$sql = "SELECT post_title FROM $wpdb->posts WHERE ID = '$ID';";
SQL INJECTION - SQLI
Brad Williams
@williamsba
h-p://www.sitepoint.com/forums/showthread.php?83772-­‐web-­‐site-­‐hacked	
  
My	
  Introduc>on	
  to	
  SQLi	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
h-p://www.sitepoint.com/forums/showthread.php?83772-­‐web-­‐site-­‐hacked	
  
My	
  Introduc>on	
  to	
  SQLi	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
WordPress	
  Database	
  Class	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
$wpdb->insert()
SQL INJECTION - SQLI
Brad Williams
@williamsba
$wpdb->insert(
$wpdb->postmeta,
array(
'post_id' => '5',
'meta_key' => '_custom_meta_key',
'meta_value' => 'true'
),
array(
'%d',
'%s',
'%s'
)
);
$wpdb->insert()
$wpdb->insert( $table, $data, $format )
Example:	
  
%s	
  handles	
  strings	
  	
  
%d	
  handles	
  integers	
  
%f	
  handles	
  floats	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
$wpdb->update()
SQL INJECTION - SQLI
Brad Williams
@williamsba
$wpdb->update(
$wpdb->postmeta',
array(
'meta_value' => 'false'
),
array(
'post_id' => 5,
'meta_key' => '_custom_meta_key'
),
array(
'%s'
),
array(
'%d',
'%s'
)
);
$wpdb->update()
$wpdb->update( $table, $data, $where, $format, $where_format )
Example:	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
$wpdb->delete()
SQL INJECTION - SQLI
Brad Williams
@williamsba
$wpdb->delete(
$wpdb->posts,
array( 'ID' => 5 ),
array( '%d' )
);
$wpdb->delete()
$wpdb->delete( $table, $where, $where_format )
Example:	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
$wpdb->prepare()
SQL INJECTION - SQLI
Brad Williams
@williamsba
•  Handles	
  strings	
  (%s)	
  and	
  
integers	
  (%d)	
  
•  Does	
  the	
  escaping	
  for	
  you	
  
•  No	
  need	
  to	
  quote	
  %s	
  
$wpdb->prepare( " SELECT post_title FROM $wpdb->posts WHERE ID = %d ", $ID );
$wpdb->prepare()
SQL INJECTION - SQLI
Brad Williams
@williamsba
•  Handles	
  strings	
  (%s)	
  and	
  
integers	
  (%d)	
  
•  Does	
  the	
  escaping	
  for	
  you	
  
•  No	
  need	
  to	
  quote	
  %s	
  
$wpdb->prepare( " DELETE FROM $wpdb->postmeta
WHERE post_id = %d AND meta_key = %s ", 420, 'Europe' );
$wpdb->prepare()
SQL INJECTION - SQLI
Brad Williams
@williamsba
$wpdb-­‐>prepare()	
  only	
  prepares	
  the	
  query,	
  it	
  does	
  not	
  execute	
  it.	
  
$wpdb->query(
$wpdb->prepare( " DELETE FROM $wpdb->postmeta
WHERE post_id = %d AND meta_key = %s ", 420, 'Europe' )
);
$wpdb->prepare()
echo $wpdb->prepare( " DELETE FROM $wpdb->postmeta
WHERE post_id = %d AND meta_key = %s ", 420, 'Europe' );
To	
  view	
  the	
  fully	
  prepared	
  query	
  simply	
  echo	
  it	
  
SQL INJECTION - SQLI
Brad Williams
@williamsba
h-p://xkcd.com/327/	
  
Don’t	
  be	
  Li-le	
  Bobby	
  Tables	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
Cross-­‐Site	
  Scrip>ng	
  	
  
(XSS)	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
	
  
What	
  is	
  Cross-­‐Site	
  Scrip>ng?	
  
	
  
A-acker	
  injects	
  client-­‐side	
  scripts	
  into	
  your	
  web	
  pages	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
Escaping	
  
To	
  escape	
  is	
  to	
  take	
  the	
  data	
  you	
  may	
  
already	
  have	
  and	
  help	
  secure	
  it	
  prior	
  to	
  
rendering	
  it	
  for	
  the	
  end	
  user	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
1.  esc_	
  is	
  the	
  prefix	
  for	
  all	
  escaping	
  func>ons	
  
2.  a-r	
  is	
  the	
  context	
  being	
  escaped	
  
3.  _e	
  is	
  the	
  op>onal	
  transla>on	
  suffix	
  
Props	
  to	
  Mark	
  Jaquith!	
  
Escaping	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
<h1><?php echo $title; ?></h1>
BAD	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
<?php
$title = "<script>alert('YO!');</script>";
?>
<h1><?php echo $title; ?></h1>
BAD	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
<?php
$title = "<script>alert('Hello Europe!');</script>";
?>
<h1><?php echo esc_html( $title ); ?></h1>
View	
  Source:	
  
<h1>&lt;script&gt;alert(&#039;Hello Europe!&#039;);&lt;/script&gt;</h1>
GOOD	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
<input type="text" name="name"
value="<?php echo esc_attr( $text ); ?>" />
esc_attr()
Used	
  whenever	
  you	
  need	
  to	
  display	
  data	
  inside	
  an	
  HTML	
  element	
  
h-p://codex.wordpress.org/Func>on_Reference/esc_a-r	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
<textarea name="bio">
<?php echo esc_textarea( $bio); ?>
</textarea>
esc_textarea()
Used	
  to	
  encode	
  text	
  for	
  use	
  in	
  a	
  <textarea>	
  form	
  element	
  
h-p://codex.wordpress.org/Func>on_Reference/esc_textarea	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
<a href="<?php echo esc_url( $url); ?>">Link</a>
esc_url()
	
  Used	
  for	
  valida>ng	
  and	
  sani>zing	
  URLs	
  
h-p://codex.wordpress.org/Func>on_Reference/esc_url	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
<?php
$url = 'http://wordpress.org';
$response = wp_remote_get( esc_url_raw( $url ) );
?>
esc_url_raw()
	
  Used	
  for	
  escaping	
  a	
  URL	
  for	
  database	
  queries,	
  redirects,	
  and	
  HTTP	
  requests	
  
Similar	
  to	
  esc_url(),	
  but	
  does	
  not	
  replace	
  en>>es	
  for	
  display	
  
h-p://codex.wordpress.org/Func>on_Reference/esc_url_raw	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
<script>
var bwar='<?php echo esc_js( $text ); ?>';
</script>
esc_js()
	
  Used	
  to	
  escape	
  text	
  strings	
  in	
  JavaScript	
  
h-p://codex.wordpress.org/Func>on_Reference/esc_js	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
Integers	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
$ID = absint( $_GET['ID'] );
absint()
Coverts	
  a	
  value	
  to	
  a	
  non-­‐nega>ve	
  integer	
  
h-p://codex.wordpress.org/Func>on_Reference/absint	
  
<input type="text" name="number_posts" value="<?php echo absint( $number ); ?>" />
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
$ID = intval( $_GET['ID'] );
intval()
Returns	
  the	
  integer	
  value.	
  	
  Works	
  with	
  nega>ve	
  values	
  
h-p://php.net/manual/en/func>on.intval.php	
  
<input type="text" name="number_posts" value="<?php echo intval( $number ); ?>" />
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
Sani>zing	
  
To	
  sani>ze	
  is	
  to	
  take	
  the	
  data	
  and	
  clean	
  
to	
  make	
  safe	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
<?php
update_post_meta(
420,
'_post_meta_key',
$_POST['new_meta_value']
);
?>
BAD	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
sanitize_text_field()
Sani>ze	
  a	
  string	
  
h-p://codex.wordpress.org/Func>on_Reference/sani>ze_text_field	
  
<?php
update_post_meta(
34,
'_post_meta_key',
sanitize_text_field( $_POST['new_meta_value'] )
);
?>
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
sanitize_email()
Strip	
  out	
  all	
  characters	
  not	
  allowed	
  in	
  an	
  email	
  address	
  
h-p://codex.wordpress.org/Func>on_Reference/sani>ze_email	
  
<?php
update_post_meta(
34,
'_email_address',
sanitize_email( $_POST['email'] )
);
?>
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
sanitize_user()
Sani>ze	
  username	
  stripping	
  out	
  unsafe	
  characters	
  
h-p://codex.wordpress.org/Func>on_Reference/sani>ze_user	
  
<?php
update_post_meta(
34,
'_custom_username',
sanitize_user( $_POST['username'] )
);
?>
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
wp_kses()
Filters	
  content	
  and	
  keeps	
  only	
  allowable	
  HTML	
  elements.	
  
h-p://codex.wordpress.org/Func>on_Reference/wp_kses	
  
<a	
  href="#">link</a>.	
  This	
  is	
  bold	
  and	
  <strong>strong</strong>	
  
CROSS-SITE SCRIPTING - XSS
Brad Williams
@williamsba
wp_kses_post()
Filters	
  post	
  content	
  and	
  keeps	
  only	
  allowable	
  HTML	
  elements.	
  
h-p://codex.wordpress.org/Func>on_Reference/wp_kses_post	
  
HTML	
  tags	
  allowed	
  to	
  be	
  put	
  into	
  Posts	
  by	
  non-­‐admin	
  users	
  
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
Cross-­‐site	
  Request	
  
Forgery	
  
(CSRF)	
  
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
Exploit	
  of	
  a	
  website	
  whereby	
  unauthorized	
  commands	
  
are	
  transmi-ed	
  from	
  a	
  user	
  that	
  the	
  website	
  trusts.	
  
Cross-­‐site	
  Request	
  
Forgery	
  
(CSRF)	
  
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
Nonces	
  
Ac>on,	
  object,	
  &	
  user	
  specific	
  >me-­‐
limited	
  secret	
  keys	
  
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
<?php
if ( isset( $_POST['email'] ) ) {
//process form data
}
?>
<form method="post">
<input type="text" name="email /><br />
<input type="submit" name="submit" value="Submit" />
</form>
Example	
  
There	
  is	
  no	
  way	
  to	
  know	
  where	
  $_POST[‘email’]	
  is	
  being	
  posted	
  from	
  
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
<form method="post">
<?php wp_nonce_field( 'bw_process_email_action', 'bw_newsletter' ); ?>
<input type="text" name="email" /><br />
<input type="submit" name="submit" value="Submit" />
</form>
wp_nonce_field()
<form method="post">
<input type="hidden" id="bw_newsletter" name="bw_newsletter" value="287de957e8" />
<input type="hidden" name="_wp_http_referer" value="/x/sample-page/" />
<input type="text" name="email" /><br />
<input type="submit" name="submit" value="Submit" />
</form>
View	
  Source:	
  
Form	
  Code:	
  
h-p://codex.wordpress.org/Func>on_Reference/wp_nonce_field	
  
wp_nonce_field( $action, $name, $referer, $echo );
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
if ( isset( $_POST['email'] ) ) {
check_admin_referer( 'bw_process_email_action', 'bw_newsletter' );
//process form data
}
check_admin_referer()
Processing	
  Code:	
  
check_admin_referer( $action, $query_arg );
h-p://codex.wordpress.org/Func>on_Reference/check_admin_referer	
  
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
<?php
if ( isset( $_POST['email'] ) ) {
check_admin_referer( 'bw_process_email_action', 'bw_newsletter' );
//process form data
}
?>
<form method="post">
<?php wp_nonce_field( 'bw_process_email_action', 'bw_newsletter' ); ?>
<input type="text" name="email" /><br />
<input type="submit" name="submit" value="Submit" />
</form>
Fixed	
  Example	
  
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
$url = 'http://example.com/wp-admin/?ID=5';
$url = wp_nonce_url( $url, 'bw_process_email_action', 'bw_newsletter' );
wp_nonce_url()
http://example.com/wp-admin/?ID=5&bw_newsletter=287de957e8
New	
  URL:	
  
URL	
  Code:	
  
h-p://codex.wordpress.org/Func>on_Reference/wp_nonce_url	
  
wp_nonce_url( $actionurl, $action, $name );
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
if ( isset( $_GET[ID'] ) ) {
check_admin_referer( 'bw_process_email_action', 'bw_newsletter' );
//process data
}
wp_nonce_url()
Processing	
  Code:	
  
h-p://codex.wordpress.org/Func>on_Reference/check_admin_referer	
  
CROSS-SITE REQUEST FORGERY - CSRF
Brad Williams
@williamsba
Nonces	
  
Specific	
  to	
  
• WordPress	
  User	
  
• Ac>on	
  A-empted	
  
• Object	
  of	
  a-empted	
  ac>on	
  
• Time	
  Window	
  
RESOURCES
Brad Williams
@williamsba
•  Security	
  Ar>cles	
  
•  h-p://codex.wordpress.org/Data_Valida>on	
  
•  h-p://codex.wordpress.org/Valida>ng_Sani>zing_and_Escaping_User_Data	
  
•  h-p://wp.tutsplus.com/tutorials/7-­‐simple-­‐rules-­‐wordpress-­‐plugin-­‐development-­‐best-­‐
prac>ces/	
  
•  h-p://wpengine.com/2013/05/brad-­‐williams-­‐on-­‐secure-­‐wordpress-­‐development/	
  
•  h-p://codex.wordpress.org/WordPress_Nonces	
  
•  Security	
  Presenta>ons	
  
•  h-p://wordpress.tv/2013/08/09/mike-­‐adams-­‐three-­‐security-­‐issues-­‐you-­‐thought-­‐youd-­‐fixed/	
  
•  h-p://wordpress.tv/2013/09/26/brennen-­‐byrne-­‐employing-­‐best-­‐security-­‐prac>ces-­‐for-­‐
wordpress-­‐sites-­‐3/	
  
•  h-p://wordpress.tv/2011/01/29/mark-­‐jaquith-­‐theme-­‐plugin-­‐security/	
  
	
  
DRADCAST PLUG
Brad Williams
@williamsba
Listen	
  to	
  the	
  DradCast	
  WordPress	
  Podcast	
  
	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  LIVE	
  every	
  Wednesday	
  @	
  8pm	
  EDT	
  
	
  
DradCast.com	
  
CONTACT BRAD
Brad Williams
@williamsba
Brad	
  Williams	
  
brad@webdevstudios.com	
  
	
  
Blog:	
  	
  strangework.com	
  
Twi-er:	
  @williamsba	
  
	
  
	
  
h-p://bit.ly/prowp2	
  

More Related Content

PDF
Sass maps, my precious! 2.0
PDF
You're Doing it Wrong - WordCamp Atlanta
PPT
PHPUG Presentation
PPTX
Site optimization
PDF
ARIA Gone Wild
PDF
Game Development Using HTML 5
PDF
Fisl 11 - Dicas de Desenvolvimento Web com Ruby
TXT
Posts ‹ teslaecoenergy — word press php
Sass maps, my precious! 2.0
You're Doing it Wrong - WordCamp Atlanta
PHPUG Presentation
Site optimization
ARIA Gone Wild
Game Development Using HTML 5
Fisl 11 - Dicas de Desenvolvimento Web com Ruby
Posts ‹ teslaecoenergy — word press php

Similar to Writing Secure WordPress Code WordCamp NYC 2014 (20)

PDF
Writing Secure WordPress Code
PDF
Writing Secure Code for WordPress
PDF
Secure WordPress Development Practices
PDF
Securing WordPress
PDF
2 Roads to Redemption - Thoughts on XSS and SQLIA
PDF
WordCamp Milwaukee 2012 - Aaron Saray - Secure Wordpress Coding
PDF
WordPress Plugin & Theme Security - WordCamp Melbourne - February 2011
PDF
Web Security - OWASP - SQL injection & Cross Site Scripting XSS
PPT
Php Security By Mugdha And Anish
PDF
2 Roads to Redemption - Thoughts on XSS and SQLIA
PDF
Intro to Php Security
PPTX
Owasp Top 10 A1: Injection
PDF
null Bangalore meet - Php Security
PPTX
Deep understanding on Cross-Site Scripting and SQL Injection
PPSX
Web Security
PDF
OWASP Top 10 - DrupalCon Amsterdam 2019
PDF
Sql Injection and XSS
PPTX
Secure Programming In Php
PPS
Hacking - Web based attacks
Writing Secure WordPress Code
Writing Secure Code for WordPress
Secure WordPress Development Practices
Securing WordPress
2 Roads to Redemption - Thoughts on XSS and SQLIA
WordCamp Milwaukee 2012 - Aaron Saray - Secure Wordpress Coding
WordPress Plugin & Theme Security - WordCamp Melbourne - February 2011
Web Security - OWASP - SQL injection & Cross Site Scripting XSS
Php Security By Mugdha And Anish
2 Roads to Redemption - Thoughts on XSS and SQLIA
Intro to Php Security
Owasp Top 10 A1: Injection
null Bangalore meet - Php Security
Deep understanding on Cross-Site Scripting and SQL Injection
Web Security
OWASP Top 10 - DrupalCon Amsterdam 2019
Sql Injection and XSS
Secure Programming In Php
Hacking - Web based attacks

More from Brad Williams (20)

PDF
From Freelance to Agency: Hiring Employee Number One - WordCamp London 2015
PDF
Hiring Employee Number One: From Freelancer to Agency
PDF
How to Make a Native Mobile App with WordPress
PDF
WordPress Security WordCamp OC 2013
PDF
Using WordPress as an Application Framework
PDF
Top Ten WordPress Security Tips for 2012
PDF
WordPress Security from WordCamp NYC 2012
PPT
WordPress Multisite
PDF
WordPress for Beginners
PDF
Creating Your First WordPress Plugin
PDF
Surviving the Zombie Apocalypse using Custom Post Types and Taxonomies
PDF
Intro to WordPress Plugin Development
PDF
Spooky WordPress: Disturbingly Brilliant Uses of WP
PDF
WordCamp Mid-Atlantic WordPress Security
PPT
Now That's What I Call WordPress Security 2010
PPT
Custom Post Types and Taxonomies in WordPress
PPT
Top 20 WordPress Plugins You've Never Heard Of
PPT
WordPress Security - WordCamp Boston 2010
PPT
WordPress Security - WordCamp NYC 2009
PPT
Website Design Dos and Don’ts for a Successful Online Presence
From Freelance to Agency: Hiring Employee Number One - WordCamp London 2015
Hiring Employee Number One: From Freelancer to Agency
How to Make a Native Mobile App with WordPress
WordPress Security WordCamp OC 2013
Using WordPress as an Application Framework
Top Ten WordPress Security Tips for 2012
WordPress Security from WordCamp NYC 2012
WordPress Multisite
WordPress for Beginners
Creating Your First WordPress Plugin
Surviving the Zombie Apocalypse using Custom Post Types and Taxonomies
Intro to WordPress Plugin Development
Spooky WordPress: Disturbingly Brilliant Uses of WP
WordCamp Mid-Atlantic WordPress Security
Now That's What I Call WordPress Security 2010
Custom Post Types and Taxonomies in WordPress
Top 20 WordPress Plugins You've Never Heard Of
WordPress Security - WordCamp Boston 2010
WordPress Security - WordCamp NYC 2009
Website Design Dos and Don’ts for a Successful Online Presence

Recently uploaded (20)

PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Electronic commerce courselecture one. Pdf
PDF
Empathic Computing: Creating Shared Understanding
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
Spectroscopy.pptx food analysis technology
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPTX
Big Data Technologies - Introduction.pptx
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
Cloud computing and distributed systems.
PDF
Approach and Philosophy of On baking technology
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Dropbox Q2 2025 Financial Results & Investor Presentation
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Electronic commerce courselecture one. Pdf
Empathic Computing: Creating Shared Understanding
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
MIND Revenue Release Quarter 2 2025 Press Release
Spectroscopy.pptx food analysis technology
Unlocking AI with Model Context Protocol (MCP)
Spectral efficient network and resource selection model in 5G networks
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Big Data Technologies - Introduction.pptx
Network Security Unit 5.pdf for BCA BBA.
Understanding_Digital_Forensics_Presentation.pptx
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
The Rise and Fall of 3GPP – Time for a Sabbatical?
Cloud computing and distributed systems.
Approach and Philosophy of On baking technology
Mobile App Security Testing_ A Comprehensive Guide.pdf
Digital-Transformation-Roadmap-for-Companies.pptx

Writing Secure WordPress Code WordCamp NYC 2014

  • 1. WRITING SECURE WORDPRESS CODE BY  BRAD  WILLIAMS   Brad Williams @williamsba h-p://www.slideshare.net/williamsba/wri>ng-­‐secure-­‐wordpress-­‐code-­‐wordcamp-­‐nyc-­‐2014  
  • 2. WHO IS BRAD? Brad Williams @williamsba Brad  Williams    
  • 4. TODAY’S TOPICS Brad Williams @williamsba   • Cover  the  big  three  exploits   •  SQL  Injec>on  -­‐  SQLi   •  Cross-­‐Site  Scrip>ng  -­‐  XSS   •  Cross-­‐Site  Request  Forgery  –  CSRF   • Hack  Examples   • Data  Valida>on  and  Sani>za>on   • Resources  
  • 5. TRUST NO ONE Brad Williams @williamsba Golden  Rule  of  Code   Trust  No  One  
  • 6. TRUST NO ONE Brad Williams @williamsba Consider  all  data  invalid   unless  it  can  be  proven  valid  
  • 7. SQL INJECTION - SQLI Brad Williams @williamsba SQL  Injec>on  (SQLi)  
  • 8. SQL INJECTION - SQLI Brad Williams @williamsba SQL  injec*on  is  a  code  injec>on  technique   in  which  malicious  SQL  statements  are   inserted  into  an  entry  field  for  execu>on  
  • 9. SQL INJECTION - SQLI Brad Williams @williamsba SQL  Injec>on  Example    global $wpdb; $ID = $_GET['ID']; $sql = "SELECT post_title FROM $wpdb->posts WHERE ID = '$ID';"; SELECT  post_>tle  FROM  wp_posts  WHERE  ID  =  '5';  
  • 10. SQL INJECTION - SQLI Brad Williams @williamsba SQL  Injec>on  Example     SELECT  post_>tle  FROM  wp_posts  WHERE  ID  =  '';     SELECT  *  FROM  wp_users  WHERE  1  =  '1';   global $wpdb; $ID = "'; SELECT * FROM wp_users WHERE 1 = '1"; $sql = "SELECT post_title FROM $wpdb->posts WHERE ID = '$ID';";
  • 11. SQL INJECTION - SQLI Brad Williams @williamsba h-p://www.sitepoint.com/forums/showthread.php?83772-­‐web-­‐site-­‐hacked   My  Introduc>on  to  SQLi  
  • 12. SQL INJECTION - SQLI Brad Williams @williamsba h-p://www.sitepoint.com/forums/showthread.php?83772-­‐web-­‐site-­‐hacked   My  Introduc>on  to  SQLi  
  • 13. SQL INJECTION - SQLI Brad Williams @williamsba WordPress  Database  Class  
  • 14. SQL INJECTION - SQLI Brad Williams @williamsba $wpdb->insert()
  • 15. SQL INJECTION - SQLI Brad Williams @williamsba $wpdb->insert( $wpdb->postmeta, array( 'post_id' => '5', 'meta_key' => '_custom_meta_key', 'meta_value' => 'true' ), array( '%d', '%s', '%s' ) ); $wpdb->insert() $wpdb->insert( $table, $data, $format ) Example:   %s  handles  strings     %d  handles  integers   %f  handles  floats  
  • 16. SQL INJECTION - SQLI Brad Williams @williamsba $wpdb->update()
  • 17. SQL INJECTION - SQLI Brad Williams @williamsba $wpdb->update( $wpdb->postmeta', array( 'meta_value' => 'false' ), array( 'post_id' => 5, 'meta_key' => '_custom_meta_key' ), array( '%s' ), array( '%d', '%s' ) ); $wpdb->update() $wpdb->update( $table, $data, $where, $format, $where_format ) Example:  
  • 18. SQL INJECTION - SQLI Brad Williams @williamsba $wpdb->delete()
  • 19. SQL INJECTION - SQLI Brad Williams @williamsba $wpdb->delete( $wpdb->posts, array( 'ID' => 5 ), array( '%d' ) ); $wpdb->delete() $wpdb->delete( $table, $where, $where_format ) Example:  
  • 20. SQL INJECTION - SQLI Brad Williams @williamsba $wpdb->prepare()
  • 21. SQL INJECTION - SQLI Brad Williams @williamsba •  Handles  strings  (%s)  and   integers  (%d)   •  Does  the  escaping  for  you   •  No  need  to  quote  %s   $wpdb->prepare( " SELECT post_title FROM $wpdb->posts WHERE ID = %d ", $ID ); $wpdb->prepare()
  • 22. SQL INJECTION - SQLI Brad Williams @williamsba •  Handles  strings  (%s)  and   integers  (%d)   •  Does  the  escaping  for  you   •  No  need  to  quote  %s   $wpdb->prepare( " DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s ", 420, 'Europe' ); $wpdb->prepare()
  • 23. SQL INJECTION - SQLI Brad Williams @williamsba $wpdb-­‐>prepare()  only  prepares  the  query,  it  does  not  execute  it.   $wpdb->query( $wpdb->prepare( " DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s ", 420, 'Europe' ) ); $wpdb->prepare() echo $wpdb->prepare( " DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s ", 420, 'Europe' ); To  view  the  fully  prepared  query  simply  echo  it  
  • 24. SQL INJECTION - SQLI Brad Williams @williamsba h-p://xkcd.com/327/   Don’t  be  Li-le  Bobby  Tables  
  • 25. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba Cross-­‐Site  Scrip>ng     (XSS)  
  • 26. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba   What  is  Cross-­‐Site  Scrip>ng?     A-acker  injects  client-­‐side  scripts  into  your  web  pages  
  • 27. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba Escaping   To  escape  is  to  take  the  data  you  may   already  have  and  help  secure  it  prior  to   rendering  it  for  the  end  user  
  • 28. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba 1.  esc_  is  the  prefix  for  all  escaping  func>ons   2.  a-r  is  the  context  being  escaped   3.  _e  is  the  op>onal  transla>on  suffix   Props  to  Mark  Jaquith!   Escaping  
  • 29. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba <h1><?php echo $title; ?></h1> BAD  
  • 30. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba <?php $title = "<script>alert('YO!');</script>"; ?> <h1><?php echo $title; ?></h1> BAD  
  • 31. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba <?php $title = "<script>alert('Hello Europe!');</script>"; ?> <h1><?php echo esc_html( $title ); ?></h1> View  Source:   <h1>&lt;script&gt;alert(&#039;Hello Europe!&#039;);&lt;/script&gt;</h1> GOOD  
  • 32. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba <input type="text" name="name" value="<?php echo esc_attr( $text ); ?>" /> esc_attr() Used  whenever  you  need  to  display  data  inside  an  HTML  element   h-p://codex.wordpress.org/Func>on_Reference/esc_a-r  
  • 33. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba <textarea name="bio"> <?php echo esc_textarea( $bio); ?> </textarea> esc_textarea() Used  to  encode  text  for  use  in  a  <textarea>  form  element   h-p://codex.wordpress.org/Func>on_Reference/esc_textarea  
  • 34. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba <a href="<?php echo esc_url( $url); ?>">Link</a> esc_url()  Used  for  valida>ng  and  sani>zing  URLs   h-p://codex.wordpress.org/Func>on_Reference/esc_url  
  • 35. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba <?php $url = 'http://wordpress.org'; $response = wp_remote_get( esc_url_raw( $url ) ); ?> esc_url_raw()  Used  for  escaping  a  URL  for  database  queries,  redirects,  and  HTTP  requests   Similar  to  esc_url(),  but  does  not  replace  en>>es  for  display   h-p://codex.wordpress.org/Func>on_Reference/esc_url_raw  
  • 36. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba <script> var bwar='<?php echo esc_js( $text ); ?>'; </script> esc_js()  Used  to  escape  text  strings  in  JavaScript   h-p://codex.wordpress.org/Func>on_Reference/esc_js  
  • 37. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba Integers  
  • 38. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba $ID = absint( $_GET['ID'] ); absint() Coverts  a  value  to  a  non-­‐nega>ve  integer   h-p://codex.wordpress.org/Func>on_Reference/absint   <input type="text" name="number_posts" value="<?php echo absint( $number ); ?>" />
  • 39. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba $ID = intval( $_GET['ID'] ); intval() Returns  the  integer  value.    Works  with  nega>ve  values   h-p://php.net/manual/en/func>on.intval.php   <input type="text" name="number_posts" value="<?php echo intval( $number ); ?>" />
  • 40. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba Sani>zing   To  sani>ze  is  to  take  the  data  and  clean   to  make  safe  
  • 41. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba <?php update_post_meta( 420, '_post_meta_key', $_POST['new_meta_value'] ); ?> BAD  
  • 42. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba sanitize_text_field() Sani>ze  a  string   h-p://codex.wordpress.org/Func>on_Reference/sani>ze_text_field   <?php update_post_meta( 34, '_post_meta_key', sanitize_text_field( $_POST['new_meta_value'] ) ); ?>
  • 43. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba sanitize_email() Strip  out  all  characters  not  allowed  in  an  email  address   h-p://codex.wordpress.org/Func>on_Reference/sani>ze_email   <?php update_post_meta( 34, '_email_address', sanitize_email( $_POST['email'] ) ); ?>
  • 44. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba sanitize_user() Sani>ze  username  stripping  out  unsafe  characters   h-p://codex.wordpress.org/Func>on_Reference/sani>ze_user   <?php update_post_meta( 34, '_custom_username', sanitize_user( $_POST['username'] ) ); ?>
  • 45. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba wp_kses() Filters  content  and  keeps  only  allowable  HTML  elements.   h-p://codex.wordpress.org/Func>on_Reference/wp_kses   <a  href="#">link</a>.  This  is  bold  and  <strong>strong</strong>  
  • 46. CROSS-SITE SCRIPTING - XSS Brad Williams @williamsba wp_kses_post() Filters  post  content  and  keeps  only  allowable  HTML  elements.   h-p://codex.wordpress.org/Func>on_Reference/wp_kses_post   HTML  tags  allowed  to  be  put  into  Posts  by  non-­‐admin  users  
  • 47. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba Cross-­‐site  Request   Forgery   (CSRF)  
  • 48. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba Exploit  of  a  website  whereby  unauthorized  commands   are  transmi-ed  from  a  user  that  the  website  trusts.   Cross-­‐site  Request   Forgery   (CSRF)  
  • 49. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba Nonces   Ac>on,  object,  &  user  specific  >me-­‐ limited  secret  keys  
  • 50. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba <?php if ( isset( $_POST['email'] ) ) { //process form data } ?> <form method="post"> <input type="text" name="email /><br /> <input type="submit" name="submit" value="Submit" /> </form> Example   There  is  no  way  to  know  where  $_POST[‘email’]  is  being  posted  from  
  • 51. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba <form method="post"> <?php wp_nonce_field( 'bw_process_email_action', 'bw_newsletter' ); ?> <input type="text" name="email" /><br /> <input type="submit" name="submit" value="Submit" /> </form> wp_nonce_field() <form method="post"> <input type="hidden" id="bw_newsletter" name="bw_newsletter" value="287de957e8" /> <input type="hidden" name="_wp_http_referer" value="/x/sample-page/" /> <input type="text" name="email" /><br /> <input type="submit" name="submit" value="Submit" /> </form> View  Source:   Form  Code:   h-p://codex.wordpress.org/Func>on_Reference/wp_nonce_field   wp_nonce_field( $action, $name, $referer, $echo );
  • 52. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba if ( isset( $_POST['email'] ) ) { check_admin_referer( 'bw_process_email_action', 'bw_newsletter' ); //process form data } check_admin_referer() Processing  Code:   check_admin_referer( $action, $query_arg ); h-p://codex.wordpress.org/Func>on_Reference/check_admin_referer  
  • 53. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba <?php if ( isset( $_POST['email'] ) ) { check_admin_referer( 'bw_process_email_action', 'bw_newsletter' ); //process form data } ?> <form method="post"> <?php wp_nonce_field( 'bw_process_email_action', 'bw_newsletter' ); ?> <input type="text" name="email" /><br /> <input type="submit" name="submit" value="Submit" /> </form> Fixed  Example  
  • 54. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba $url = 'http://example.com/wp-admin/?ID=5'; $url = wp_nonce_url( $url, 'bw_process_email_action', 'bw_newsletter' ); wp_nonce_url() http://example.com/wp-admin/?ID=5&bw_newsletter=287de957e8 New  URL:   URL  Code:   h-p://codex.wordpress.org/Func>on_Reference/wp_nonce_url   wp_nonce_url( $actionurl, $action, $name );
  • 55. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba if ( isset( $_GET[ID'] ) ) { check_admin_referer( 'bw_process_email_action', 'bw_newsletter' ); //process data } wp_nonce_url() Processing  Code:   h-p://codex.wordpress.org/Func>on_Reference/check_admin_referer  
  • 56. CROSS-SITE REQUEST FORGERY - CSRF Brad Williams @williamsba Nonces   Specific  to   • WordPress  User   • Ac>on  A-empted   • Object  of  a-empted  ac>on   • Time  Window  
  • 57. RESOURCES Brad Williams @williamsba •  Security  Ar>cles   •  h-p://codex.wordpress.org/Data_Valida>on   •  h-p://codex.wordpress.org/Valida>ng_Sani>zing_and_Escaping_User_Data   •  h-p://wp.tutsplus.com/tutorials/7-­‐simple-­‐rules-­‐wordpress-­‐plugin-­‐development-­‐best-­‐ prac>ces/   •  h-p://wpengine.com/2013/05/brad-­‐williams-­‐on-­‐secure-­‐wordpress-­‐development/   •  h-p://codex.wordpress.org/WordPress_Nonces   •  Security  Presenta>ons   •  h-p://wordpress.tv/2013/08/09/mike-­‐adams-­‐three-­‐security-­‐issues-­‐you-­‐thought-­‐youd-­‐fixed/   •  h-p://wordpress.tv/2013/09/26/brennen-­‐byrne-­‐employing-­‐best-­‐security-­‐prac>ces-­‐for-­‐ wordpress-­‐sites-­‐3/   •  h-p://wordpress.tv/2011/01/29/mark-­‐jaquith-­‐theme-­‐plugin-­‐security/    
  • 58. DRADCAST PLUG Brad Williams @williamsba Listen  to  the  DradCast  WordPress  Podcast                                            LIVE  every  Wednesday  @  8pm  EDT     DradCast.com  
  • 59. CONTACT BRAD Brad Williams @williamsba Brad  Williams   brad@webdevstudios.com     Blog:    strangework.com   Twi-er:  @williamsba       h-p://bit.ly/prowp2