The document discusses various techniques for writing secure WordPress code. It covers the top exploits of SQL injection, cross-site scripting (XSS), and cross-site request forgery (CSRF). It provides examples of how these exploits can occur and recommendations for data validation, sanitization, and escaping user input to prevent exploits. These include using functions like $wpdb->prepare(), esc_html(), sanitize_text_field(), and others to properly handle and escape data when outputting or storing it.
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
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
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()
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
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
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
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'] )
);
?>
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
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