WP Engine

Solutions
AgencyEnterpriseSmall & Medium BusinessMarketer
How WP Engine supports marketers.Benefits for marketers.Features that help you innovate.
Developer
How WP Engine supports developers.Benefits for developers.Features that help you move faster.
Explore Our Platform
Insights
Thought LeadershipTopics

Read articles, trends, and insights on these topics from leaders in marketing and technology.

Creative AgilityEnterprise PerformanceActionable IntelligenceEcosystem Integration
Resources

Access ebooks, whitepapers, webinars, and other knowledge from our ecosystem of digital experts.
Visit Resource Center.

Delivering a Slam Dunk Experience on WordPressEbook: The Ultimate Guide to WordPress Plugins15 Common WordPress Mistakes Agencies and their Clients Make
Case Studies
About
Our CompanyOur PlatformLatest News

Access the latest news from inside WP Engine.
Visit the Newsroom.

WP Engine Secures Strategic Growth Investment From Silver LakeWP Engine Unveils First WordPress Digital ExperienceWP Engine Expands Global Presence with New Office in Brisbane
Media Center

Get announcements and resources about WP Engine.

Press Releases
Careers at WP Engine
Pricing
Sales Questions?

Contact Sales

Discover why organizations of all types and sizes choose WP Engine — and how it can benefit you.

Chat

1

I'm available right now to answer any of your questions!

Reply

Call

+1-512-201-4819

Contact

Send a message

Compare Plans
Need Support?
Support DocumentationBilling HelpSupport

We offer support 24 hours a day, 7 days a week, 365 days a year. Log in to get expert one-on-one help.

Log in for support

Sales Questions

Contact Sales

Discover why organizations of all types and sizes choose WP Engine — and how it can benefit you.

Chat

1

I'm available right now to answer any of your questions!

Reply

Call

+1-512-201-4819

Contact

Send a message

Sign in
Sign in
Search

Search

Compare Plans
Call Sales +1-512-201-4819
Menu
AgencyEnterpriseSmall & Medium BusinessMarketers
How WP Engine supports marketers.Benefits for marketersFeatures that help you innovate.
Developers
How WP Engine supports developers.Benefits for developers.Features that help you move faster.
Our PlatformPricingResource CenterOur CompanySolution CenterThought LeadershipDocumentationCareers

Brad WIlliams on Secure WordPress Development

Brad Williams 5.10.2013

Brad WilliamsThis guest post is a technical  by Brad Williams, a leading WordPress developer and security expert, as well as a co-founder of WebDevStudios, one of the top WordPress agencies. He is the author of Professional WordPress, and also co-hosts the DradCast.

One of the most important steps when writing code, regardless of what platform the code will run on, is making sure it is secure from hacks and exploits. Running a plugin with a security hole could open up the entire WordPress website to malicious hackers. WordPress features some built-in security tools that you should always take advantage of when creating custom plugins and themes in WordPress to verify your code is as secure as it can be.

Trust No One

The golden rule when writing code is to trust no one. That is, consider all data invalid unless it can be proven valid. Any data that can be manipulated by a third party should be validated and sanitized prior to processing that data. Forgetting this simple rule could end in disaster for anyone running your code.

Data Validation and Sanitization

Any and all data that comes from somewhere external to your code, like user input, needs to be scrubbed to verify it’s free from illegal characters and potentially unsafe data. WordPress contains a set of escaping functions that you can use to verify that your data is escaped properly when displaying it to the screen.

  • esc_html() – Used for escaping data that contains HTML. The function encodes special characters in their HTML entities, making it safe to display on the page.
    Example: <?php echo esc_html( $text ); ?>
  • esc_attr() – Used for escaping HTML attributes. This function should be used whenever you need to display data inside an HTML element
    Example: <input type="text" name="name" value="<?php echo esc_attr( $text ); ?>" />
  • esc_textarea() – Used for escaping HTML <textarea> values. This function should be used to encode text for use in a <textarea> form element.
    Example: <textarea name="bio"><?php echo esc_textarea( $bio); ?></textarea>
  • esc_url() – Used for validating and sanitizing URLs. This function should be used to scrub the URL for illegal characters and encodes HTML entities. Also see esc_url_raw(), which uses esc_url(), but does not replace entities for display.
    Example: <a href="<?php echo esc_url( $url); ?>">Link</a>
  • esc_js() – Used to escape text strings in JavaScript.
    Example: <script>var bwar='<?php echo esc_js( $text ); ?>';</script>

If you are working with integers there are two functions you should be using:

  • intval() – PHP function to verify that the value is an integer. If the variable is a string, and therefore not an integer, it will return a 0.
    Example: <input type="text" name="number_to_display" value="<php echo intval( $number ); ?>" />
  • absint() – WordPress function to verify that the value is a non-negative integer. If the variable is a string, or a negative number, it will return a 0.
    Example: <input type="text" name="number_to_display" value="<php echo absint( $number ); ?>" />

As important as escaping is when displaying data, sanitizing is when saving data. Let’s look at some of the common sanitization functions that WordPress includes.

  • sanitize_text_field() – Used to sanitize standard text data. This function will remove invalid UTF-8 characters, convert single < characters to entity, strip all tags, remove line breaks, tabs and extra white space, and strip octets.
  • sanitize_email() – Used to sanitize an email address. This function will strip out all characters that are not allowed in an email address.
  • wp_kses() – A very powerful function for sanitizing untrusted HTML. This function verifies only defined HTML tags and attributes are allowed and everything else is stripped out.
  • wp_kses_post() – Very similar to wp_kses(), but you do not need to provide an array of allowed HTML tags and attributes. That list is already set based on the allowed HTML tags for regular post content in WordPress.

Let’s look at an example using the wp_kses() WordPress function:

[php]
<?php
$allowed_tags = array(
‘strong’ => array(),
‘a’ => array(
‘href’ => array(),
‘title’ => array()
)
);

$html = ‘<a href=”#” class=”external”>link</a>. This is <b>bold</b> and <strong>strong</strong>’;

echo wp_kses( $html, $allowed_tags );
?>
[/php]

The first step is to define an array of all HTML tags and attributes that are allowed. In the code above you are allowing the <strong> and <a> tags. The <a> tag is allowed to include the href and title attributes. Next, you build an $html variable to run through the wp_kses() function. Let’s look at the output:

[php]
<a href=”#”>link</a>. This is bold and <strong>strong</strong>
[/php]

Notice the <b></b> tags have been completely removed. The function also removed the class attribute from the <a> tag because you didn’t specify that as an allowed attribute. It’s easy to understand how powerful and important the wp_kses() function is in WordPress.

To learn more about escaping and sanitizing in WordPress visit the Data Validation Codex page.

Nonces

Nonces, which stands for number used once, are used in requests (form submissions, ajax requests, saving options) to stop unauthorized access by generating a secret key. This key is generated prior to generating a request, like a form post. The key is then passed in the request to your script and verified to be the same key that was generated. If the key does not match, or does not exist, the entire process will be killed. Let’s look at a basic example:

[html]
<form method=”post”>
<?php wp_nonce_field( ‘williamsba_settings_form_save’, ‘williamsba_nonce_field’ ); ?>
Enter your name: <input type=”text” name=”text” /><br />
<input type=”submit” name=”submit” value=”Save Options” />
</form>
[/html]

As you can see we have a very basic HTML form with a single text field for the user’s name. We are also using the WordPress function wp_nonce_field() to generate a secret key. This key is generated as a hidden form field and passed through the form when it is posted.

Now that you have generated a nonce field in your form, let’s look at the process of verifying the secret key upon form submission:

[php]
function bw_update_options() {

if ( isset( $_POST[‘submit’] ) ) {

//check nonce for security
check_admin_referer( ‘williamsba_settings_form_save’, ‘williamsba_nonce_field’ );

//nonce passed, now do stuff

}
}
[/php]

Verifying that the nonce is valid is as simple as calling the check_admin_referer() function. Simply pass it your unique nonce action and name that you defined earlier. If the secret key does not match WordPress will stop processing the page and issue an error message.

Nonces can also be used on links that perform actions in the form of a querystring. Here’s an example:

[php]
<?php $link = ‘http://example.com/wp-admin/my-url.php?action=delete&ID=15’; ?>
<a href=”<?php echo wp_nonce_url( $link, ‘williamsba_nonce_url_check’ ); ?>”>Delete</a>
[/php]

In this example you’ll use the wp_nonce_url() function to generate a unique secret key in the URL. The function accepts two parameters: the URL to add the nonce to and the unique nonce name you are creating. You can verify the nonce is correct just like you did with your form using the check_admin_referer() function:

[php]
function bw_update_options() {

if ( isset( $_GET[‘action’] ) ) {

//check nonce for security
check_admin_referer( ‘williamsba_nonce_url_check’ );

//do stuff
}
}
[/php]

Understanding how to write solid secure code in WordPress is an absolute necessity in this day and age. One single user-submitted value that is unsanitized could potentially destroy your entire site. Scared? You should be! Now go update your code to be as secure as possible!

More WordPress news from WP Engine

Finely Tuned Consultant – Aaron CampbellOur Message to President Obama: Creating Jobs that are Worth Having

Comments

  1. Paul Graham says

    May 10, 2013 at 2:27 pm

    Awesome article, I’m going to have to put this in my permanent resources and sent to bad plugin writers. These are such simple techniques and luckily most of the popular plugins have implemented these but you still catch a few that haven’t.

    For site owners: REVIEW YOUR PLUGIN CODE, make sure these sorts of things are implemented in plugins you are using.

    Reply
  2. Elliott Richmond says

    May 13, 2013 at 3:54 pm

    Very useful, in fact I was looking up all of this recently across a couple of books and this post hit the spot with everything in one place, as ever Brad just awesome!

    Reply
  3. Matthias Holzmann says

    May 15, 2013 at 6:42 am

    Great article and very usefull. I will try to use these ideas to make my blog safer!

    Reply
  4. dashaluna says

    May 17, 2013 at 10:27 am

    Thank you Brad for the great summary! wp_kses() function sounds very useful, good to learn these things.

    Could anyone recommend a good resource on understanding NONCE better in more detail?

    Many thanks!
    Dasha

    Reply
  5. Tcphost says

    June 2, 2013 at 9:08 pm

    Awesome article, i follow this in my blog and i also obey this.
    thanks

    Reply
  6. wordpress deveoper says

    July 20, 2013 at 11:11 pm

    Some of the plug-ins can be difficult to understand,
    but these are optional and selected by the blogger. 08 AUD per
    month for system backup, daily malware scans and security threat
    fixes. For any business that would like improve its presence on the Internet, choosing the right Content.

    Reply
  7. Thomas Zickell says

    July 26, 2014 at 7:38 am

    Hi Brad,
    very happy to seize and that he shares my view that security is paramount and people who write code need to take that into consideration.

    I consider code security essentially the foundation web development. Your company’s work with WPEngne & Sucuri shows you care I do a lot with FireHost, Sucuri & WP engine I need a full time developer I have my current developer is moving to a job that I am happy he obtained because we are close friends however I will now need to seek out a person is capable and that it is not easy. Any advice would be very welcomed.
    Thomas

    Reply
  8. cmarlochoudhury says

    June 10, 2017 at 7:56 am

    Hi

    Thanks for providing this article with us. Very useful information to give us.

    Regards
    Web Development Company in Chennai

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • Subscribe

    Subscribe to our blog to get great tips for your WordPress site.

  • Favorite Tweets by @wpengine
  • Sign In

    Solutions

    • Agency
    • Enterprise
    • SMB
    • Marketer
    • Developer

    Insights

    • Blog
    • Torque
    • Velocitize

    About

    • Our Company
    • Leadership Team
    • Our Platform
    • Careers
    • Affiliates
    • Contact
    • Legal
    • Newsroom
    • Privacy Policy

    Resources

    • Resource Center
    • Documentation
    • Solution Center
    • Find an Agency

    WP Engine

    504 Lavaca Street, Suite 1000
    Austin, TX 78701

    Sales

    +1-512-201-4819
    [email protected]
    7am–7pm CST

    Billing

    [email protected]

    • Facebook
    • Twitter
    • LinkedIn
    • YouTube
    • Instagram
    • RSS
    © 2013—2025 WPEngine, Inc. All rights reserved.
    WP ENGINE®, VELOCITIZE®, TORQUE®, EVERCACHE®, and the cog logo service marks are owned by WPEngine, Inc.