Make WordPress Plugins

Recent Updates Page 2 Toggle Comment Threads | Keyboard Shortcuts

  • Ipstenu (Mika Epstein) 2:14 am on December 22, 2013 Permalink |

    Notice: SVN will reject PHP with errors 

    When you commit PHP files, the repository will no longer let you commit them if they have PHP syntax errors. Such an error would make the plugin fail when it tried to load the file anyway, so think of this as a ‘for your own protection’ kind of thing.

    So if you get a kick-back error like this:

    Error: Commit failed (details follow):
    Error: Commit blocked by pre-commit hook (exit code 1) with output:
    Error: PHP Parse error: syntax error, unexpected end of file in - on line 1234
    Error: ***********************************
    Error: PHP error in: really-cool/tags/1.0/really-cool.php:
    Error: Errors parsing really-cool/tags/1.0/really-cool.php
    Error: ***********************************
    Error: This error was generated by a custom hook script on the Subversion server.
    Error: Please contact your server administrator for help with resolving this issue.

    you need to fix the syntax errors in the file before uploading.

    • J.D. Grimes 2:09 pm on December 22, 2013 Permalink | Log in to Reply

      That’s great! I’ve seen this happen occasionally, and its no fun for the developer or the plugin users.

    • Andrew Nacin 8:18 pm on December 22, 2013 Permalink | Log in to Reply

      Please note: This currently does a PHP 5.4 syntax check. Please be careful if you are using 5.3 or 5.4-specific language features, like namespaces, closures, short array or ternary syntaxes, etc. These will break sites running PHP 5.2 (which is a majority of sites).

      This has actually been enabled for many months.

      • Rafael Ehlers 10:36 am on December 23, 2013 Permalink | Log in to Reply

        Hi @nacin can you elaborate on “ternary syntaxes” that you’ve mentioned ?!

        • Samuel Wood (Otto) 2:47 pm on December 23, 2013 Permalink | Log in to Reply

          A ternary operator in PHP looks like this:

          ( expression1 ) ? expression2 : expression3

          If the expression1 evaluates to true, then the result is expression2. If not, then the result is expression3. A simple example:

          $variable = ( $a > $b ) ? ‘A is greater than B’ : ‘A is not greater than B';

          Obviously the expressions can be more complex than this.

          Now, as of PHP 5.3, there is a shorthand ternary operation that works like this:

          ( expression1 ) ?: expression3

          This basically evaluates expression1, and if it’s equivalent to true, then the value of expression1 is returned. If not, then expression3 is returned. This is useful in either/or cases.

          Say you have a function returns a string or false. You want to replace the false case with some other string, like “fake”. This will do it:

          $var = ( getString() ) ?: ‘fake';

          However, the ?: shorthand is PHP 5.3 only. In 5.2 it will cause a syntax error. You could do the same thing in 5.2 code without the shorthand:

          $var = ( getString() ) ? getString() : ‘fake';

          Or if you needed to not call getString twice, by using a separate call:

          $var = getString();
          $var = ( $var ) ? $var : ‘fake';

          If you’re using 5.3-only code of any sort, make sure that your plugin checks for 5.2 cases (still more than half of all installs) and fails gracefully. Or just write 5.2 compliant syntax. There’s nothing in 5.3 and up that’s actually required for most cases.

      • Barry 4:27 am on December 27, 2013 Permalink | Log in to Reply

        This has actually been enabled for many months.

        It was actually broken (disabled) until ~11 days ago

    • elitetreecare 4:13 pm on January 1, 2014 Permalink | Log in to Reply

      Thanks for the info Samuel

    • Zane Matthew 3:09 pm on September 8, 2014 Permalink | Log in to Reply

      Would love to see this also support “warnings” and “notices” 😄

  • Jon Cave 12:56 pm on November 24, 2013 Permalink |

    How to fix the intentionally vulnerable plugin 

    If you have not reviewed the intentionally vulnerable plugin, then I suggest you do so before reading on.

    The intentionally vulnerable plugin demonstrates a range of security vulnerabilities that are commonly seen in WordPress plugins. In this post I aim to go through each vulnerability giving a little background on why it is dangerous and how it should be fixed.

    SQL injection

    This is a rather famous vulnerability that can be exploited by an attacker to modify database queries. This can allow the attacker to read sensitive information from the database, modify data stored in the database, and possibly even execute commands on database server, among other things. The basic idea is that if untrusted user input is included directly in a query then maliciously formatted input can be used to alter the query’s syntax.

    The first SQL injection vulnerability is caused by the incorrect usage of the wpdb::prepare() method on line 42:

    $wpdb->query( $wpdb->prepare( "INSERT INTO login_audit (login, pass, ip, time) VALUES ('$login', '$pass', '$ip', '$time')" ) );

    When using the prepare() method placeholders, such as %s and %d, should be used in the query string which is the first argument of the method — the method is not magic, it cannot parse the query to determine what was user input! The variables are then passed in as separate arguments so that they can be escaped properly before being included in the query. This rather common error has been made more obvious since the release of WordPress 3.5 which required more than one argument to be passed to the method.

    The correct usage, and the fix, is:

    $wpdb->query( $wpdb->prepare( "INSERT INTO login_audit (login, pass, ip, time) VALUES (%s, %s, %s, %s)", $login, $pass, $ip, $time ) );

    The other two SQL injection vulnerabilities, on lines 102 and 127, are caused by incorrectly escaping user input that is not used in a quoted context of an SQL query. The esc_sql() function can only be safely used to escape input that will be used within quotes. However, the two queries are using input as a numeric argument that is not enclosed within quotes:

    $log = $wpdb->get_row( "SELECT * FROM login_audit WHERE ID = " . esc_sql( $id ), ARRAY_A );
    // ... and ...
    $wpdb->query( "DELETE FROM login_audit WHERE ID = " . esc_sql( $_POST['id'] ) );

    To fix this you should use the prepare() method with a %d placeholder:

    $log = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM login_audit WHERE ID = %d", $id ), ARRAY_A );
    // ... and ...
    $wpdb->query( $wpdb->prepare( "DELETE FROM login_audit WHERE ID = %d", $_POST['id'] ) );

    It is also possible to sanitize numeric input by casting to int or using the absint() method.

    Cross-site scripting

    Cross-site scripting (XSS) is one of the most prevalent security vulnerabilities in web applications. XSS is also commonly found in WordPress plugins, so it features heavily in the intentionally vulnerable plugin. XSS is often classed as either “persistent” or “reflected”. An XSS vulnerability is persistent if the unsafe user input is stored in the database, and then output to other users in future requests. It is known as reflected if the unsafe user input is output immediately in response to a request containing the dangerous input. To exploit a reflected XSS vulnerability the attacker would have to convince a victim to click on their specially crafted link that triggers a malicious script. However, a persistent XSS vulnerability will allow the attacker to input their malicious script themselves and then wait for unsuspecting users to visit or click on benign looking links.

    There are two instances of persistent XSS in the intentionally vulnerable plugin, in dvp_view_all_logs() and dvp_view_log(). Both of these functions output data straight from the database without escaping it. All of this data originated from the user in dvp_log_failed_login(). For example, an attacker could purposefully fail a login attempt using a password of <script>alert(1)</script>. The fix for this would be to use an appropriate escaping function, such as esc_html() or esc_attr() when outputting data from the database. Data can also be sanitized when being stored in the database using KSES, or strip_tags() when no HTML is expected, in addition to escaping on output.

    There are also multiple examples of reflected XSS. On lines 104 and 115, the $id variable, which was originally $_GET['id'], is output without any escaping. Line 104 should be fixed with esc_html(), and line 115 should be fixed with esc_attr(). Another problem is the use of $_SERVER['PHP_SELF'] on line 116 to get the current URL. This is an extremely common problem that allows XSS since an attacker can control its value and include malicious HTML that will break out of the attribute and execute a script. This should be fixed by using a WordPress function, such as menu_page_url(), to get the correct URL.

    Cross-site request forgery

    Another extremely common vulnerability in web applications is the failure to prevent cross-site request forgeries (CSRF). This type of attack exploits a request handler that checks authorisation, but not intention. A malicious website is able to send a request to another site that the user is authenticated to. The vulnerable target site will accept this request since it is sent with valid authentication cookies. However, the user did not intend for the action to be performed. WordPress plugins can defend against this type of attack by using nonces. These are action dependent random strings that cannot be predicted by an attacker, but can be verified by WordPress. So, if a request does not include a valid nonce then it is rejected.

    The intentionally vulnerable plugin looks as if it makes use of nonces to defend against CSRF, but the author has made a couple of mistakes that leave it exploitable. Firstly, the use of nonce generation and verification functions without passing the $action parameter is insecure. Lines 114 and 123 should be edited to add the use of an action. Note that this mistake would be caught when developing with WP_DEBUG enabled as this use of check_admin_referer() raises a notice.

    The second mistake is more subtle. On line 137 the following check is made:

    if (isset($_REQUEST['nonce']) && ! wp_verify_nonce($_REQUEST['nonce'], 'dvp_settings'))
        // ... failed nonce check

    The problem with this check is that it requires the nonce request parameter to be set to ever evaluate to true. This means that an attacker can simply omit this parameter to bypass the nonce verification. This type of logic error means that it is highly recommended that you use check_admin_referer() instead of wp_verify_nonce() directly.

    Missing capabilities checks

    The lack of capabilities checks in the log deletion handler allows for a privilege escalation attack. Any logged in user is able to delete rows from the login_audit table since there are no privilege checks. Note that unauthenticated users cannot exploit this because the handler is not hooked into a _nopriv admin-post.php action. However, this is still a serious security failure. So, always remember to use the appropriate current_user_can() capabilities checks on your admin pages and privileged request handlers.

    Failure to exit after a redirect

    When a script redirects the user to another page execution will actually continue on the server side until it exits. This means that it is almost always desirable to make a call to exit or die() when making a redirect. The failure to do this on line 140 means that the capabilities check and CSRF defence (even if it didn’t have a logic error) are rendered useless as a forged request or request made by a low privilege user will actually cause the settings to be updated even though the conditional triggered a redirect. (Note that using check_admin_referer() would have also nullified the problem for a forged request since it calls die() on failure.) The other locations where redirects are used are not vulnerable in the same way because they are called at the end of script execution, but it would be good practice to add exits there as well.

    This vulnerability is exacerbated by the fact that the plugin has a ridiculous update loop that would allow a successful attacker to update any option in the database. Instead a plugin should know which options it is in charge of and only modify those whitelisted options.

    Open redirect

    On a redirect related note, there is an open redirect vulnerability in the deletion handler on line 130. In this plugin the intention is to return the user to the list of failed login attempts, so wp_safe_redirect() should have been used instead of plain old wp_redirect(). However, in this situation it would be even better to redirect to a hardcoded URL using menu_page_url() or admin_url() and then remove the ability to specify the redirect through the request parameters.

    IP forgery

    The dvp_get_ip() function can be tricked into logging an incorrect IP address since the X-Forwarded-For header is user controllable. This is bad news for a variety of reasons. For security logging purposes it degrades the utility of the audit trail as an attacker pretends to be coming from a legitimate address. If it were used for securing access then it is trivially by-passable. In the case of this plugin this can also lead to SQL injection and persistent XSS.


    There are many things that plugin authors can do wrong! The number one rule to remember is that the user is not to be trusted. Always validate and escape anything that could be controlled by a user.

    I hope that participants found this to be a useful exercise and that this review post has helped your understanding of plugin security.

    • Jon Cave 12:57 pm on November 24, 2013 Permalink | Log in to Reply

      I’m sorry that this took so long to be published. It has been sitting as a draft for many months because I forgot I hadn’t pushed the button!

    • Brian Hogg 1:13 pm on November 24, 2013 Permalink | Log in to Reply

      No worries, thanks for posting and for creating the original exercise!

    • Andrey "Rarst" Savchenko 3:22 pm on November 24, 2013 Permalink | Log in to Reply

      Why not dedicated methods for INSERT and DELETE queries?

      Will you be replying to fixes submitted? I vaguely remember considerably butchering it, so I am curious if I got the issues *and* hadn’t created any new horrible holes in my solution. :)

    • Gregory Karpinsky 3:48 pm on November 26, 2013 Permalink | Log in to Reply

      Those who come to WordPress from plain (or semi-plain) PHP, probably know well the escaping, etc.
      But for the “WP-born” developers this article is a gem!
      Thank you!

    • lorax 6:57 pm on November 27, 2013 Permalink | Log in to Reply

      Very helpful for me as I write plugins for our own use.. Thanks.

    • muddg 5:26 am on April 17, 2014 Permalink | Log in to Reply

      I am so thrilled to find this very useful information. I’ve been grappling with a security issue and have been trying to find this type of information so that I can check plugins that we’ve come to rely on. Even plugins we’ve paid for seem to be a problem. Thank you for this great resource!

    • Ploufside 2:33 pm on May 14, 2014 Permalink | Log in to Reply

      Now the question is : how to detect an intentionally vulnerable plugin 😄 Is there another way that checking plugin author trust ? Very useful anyway thanks a lot dude !

  • Ipstenu (Mika Epstein) 3:12 pm on September 12, 2013 Permalink |
    Tags: 3.6.1, ajax, error   

    The Order of Things 

    Since WP 3.6.1, you may get odd errors like “Call to undefined function wp_validate_redirect()” errors in WP Admin where AJAX is used. The error is due to plugins that call wp_get_referer() on init.

    While this will be patched more in 3.6.2, today’s quick lesson in ‘Making your plugins better’ is this simple note:

    Doing anything before plugins_loaded or init is a bad idea.

    If you find an affected plugin, please feel free to report it here: https://core.trac.wordpress.org/ticket/25294

    • takien 3:24 pm on September 12, 2013 Permalink | Log in to Reply

      Thanks for this info bro

    • Mike Schinkel 4:10 pm on September 12, 2013 Permalink | Log in to Reply

      In general @nacin‘s advice that the only thing a plugin should be doing on inclusion is add_action() and add_filter() is extremely good advice, but I’m concerned it might be taken too literally.

      There are other things that can and should be done when loading files and I’d hate for people who review code for best practices for corporations but who are not really experienced with WordPress to add that literally to the list of required best practices without including some caveats.

      Here are some caveats I would add to @nacin‘s advice as being okay to do on plugin inclusion:

      • Capturing __FILE__ or __DIR__ into a static variable of a class for later use.
      • Calling spl_autoload_register().
      • Pre-parsing of environment variables such as $_SERVER['REQUEST_URI'] into static variables of classes.
      • Defining architectural relationships between classes in a plugin that are beyond what PHP provides at the language level, i.e. defining one class as a mixin to another and storing that information in static variables of a class.
      • Possibly other things that are pure PHP/environment and/or that do not have an dependencies on the functions or classes in WordPress, depending on use-case, of course.
    • Andrey "Rarst" Savchenko 6:54 pm on September 12, 2013 Permalink | Log in to Reply

      > The error is due to plugins that call wp_get_referer() on init.

      You probably meant on load rather than init?

    • Knut Sparhell 5:05 pm on September 14, 2013 Permalink | Log in to Reply

      Maybe more precise: Calling any WordPress functions, except add_action() and add_filter(), on plugin inclusion is a bad idea.

      • brasofilo 5:08 am on October 17, 2013 Permalink | Log in to Reply

        Knut, just to clarify my ignorance, what do you guys refer as “plugin inclusion”? I suppose it’s an activated plugin start up…. Normally, if it’s the case, I call

        if( is_admin() )
            add_action( 'plugins_loaded', 'start_everything' );

        I also suppose is_admin() is not a bad idea, is it?

  • Ipstenu (Mika Epstein) 9:04 pm on June 21, 2013 Permalink |
    Tags: , swfupload   

    Secure SWFUpload 

    Do you use SWFUpload? Have you been getting a lot of emails from us telling you it’s not secure? We have a solution. Or rather, WordPress has one.


    The WordPress security team has officially forked the long-abandoned SWFUpload project and is strongly encouraging all web developers who use SWFUpload to update.

    We strongly suggest you do not use SWFUpload. But if you must, use this fork.

    Read More at Make/Core

  • Ipstenu (Mika Epstein) 10:18 pm on May 1, 2013 Permalink |
    Tags: ,   

    Font Awesome is permitted in the Plugin Repository 

    This took longer than we would have liked to say, but there were communication issues on multiple fronts.

    You can use the Font Awesome font files and CSS in your code, per the current Font Awesome License:

    As far as crediting is concerned, we feel attribution is always good. You should always put that in your source code, but your readme is optional. Credit links must be opt-in if they show on the front facing part of your site (this includes the login page), but that’s nothing new.

    So with that said, we’re going through the plugins that had been closed for Font Awesome usage and opening them. If we missed yours, please email us at plugins at wordpress.org, with a link to the plugin (like https://wordpress.org/extend/plugins/font-awesome/ which is open) and we’ll check right away.

  • Andrew Nacin 7:48 pm on April 23, 2013 Permalink  

    Plugins SVN Repository DNS Change Today 

    In a short while (next 30 minutes or so), plugins.svn.wordpress.org will undergo a DNS change as part of a datacenter migration. The TTLs are low, so this should only take a few minutes.

    Nothing will go down, but the SVN repository will become temporarily read-only. If you try to commit code during this time, you’ll receive an maintenance message pointing you here. Plugin pages and downloads will not be affected.

    Also, the associated Trac at plugins.trac.wordpress.org will be taken offline (for up to an hour) while it is migrated and re-synced.

    • Sam 8:15 pm on April 23, 2013 Permalink

      ok good luck andrew ^-^

    • Andrew Nacin 8:17 pm on April 23, 2013 Permalink

      Plugins SVN is online again. If your commits are not working, flush your DNS cache. Here’s the proper IP address for plugins.svn.wordpress.org:

      $ dig plugins.svn.wordpress.org +short

      Trac remains down while it re-syncs.

    • Andrew Nacin 8:37 pm on April 23, 2013 Permalink

      Everything is back online.

    • jquindlen 11:54 pm on April 23, 2013 Permalink

      If you don’t know how to flush your DNS on Windows, open up cmd and type:
      ipconfig /flushdns

    • jquindlen 11:55 pm on April 23, 2013 Permalink

      To flush your DNS on Windows, open a command prompt (run > cmd) and type: ipconfig /flushdns

    • JAkzam 7:11 pm on May 15, 2013 Permalink

      Hey could someone maybe help me out…I’m a long time WP Developer, but just release our first public Plugin that has been accepted and approved for the WP directory and the SVN.

      I received the email to wait about an hour (it’s been many) and login with this account information.

      But I think I may have screwed up, as I think I have a previous registration on the SVN Repository using this same username. When I log in to the already created account, it says I am not involved in any projects, but the link to the SVN Repository shows my files…

      So what do ya think…should I just be a little more patient?



      p.s. Sorry if this isn’t a good place to ask this question. But I’m a quick learner.

      • Ipstenu (Mika Epstein) 6:41 pm on May 23, 2013 Permalink

        Email plugins AT wordpress.org if you need help with this. Also re-read the email we sent, especially the part where it says to use the WordPress.org login ID and password to get into SVN. 😉

    • Shrinivas 11:02 am on July 28, 2013 Permalink

      My second plugin got approved by WordPress, and I also got SVN repository URL. I checkout out the plugin with Tortoise SVN, copied my plugin files to trunk folder, but when I am trying to commit it, I am getting the following error.

      Commit failed (details follow):
      At least one property change failed; repository is unchanged
      Server sent unexpected return value (400 Bad Request) in response to PROPPATCH
      request for ‘/!svn/txn/747084-g5of’

      am I doing it right? How to solve this issue?

      Here is the my question in support forum https://wordpress.org/support/topic/commit-failed-while-uploading-my-plugin-to-repository?replies=1

  • Ipstenu (Mika Epstein) 6:45 pm on April 22, 2013 Permalink |  

    Plugins to embed audio/video or use HTML, please read 

    If you have a plugin with the sole purpose of embedding video into WP posts, or one that makes HTML5 work in WP, you need to know that there is HTML5 support for Audio and Video coming in WordPress 3.6, so please test ASAP.

    Read Audio/Video Support in Core

  • Samuel Wood (Otto) 4:14 pm on April 16, 2013 Permalink |
    Tags: author, google, markup, schema   

    Be the Author… 

    So, I’ve had this working for a while, but not a lot of people noticed, so I figured I’d spell it out explicitly.

    WordPress.org plugin pages have special magic Google markup. This is what allows many of the Google tricks we do for plugin pages to work. If you’ve ever searched for one of our plugins on Google, you may have noticed that it says it’s “free” as well as showed the rating as stars and such. This is all using Google’s Rich Snippets functionality with markup from the schema.org specifications.

    One of the magic tricks we do is to point to your WordPress.org Profiles page as the “author” of the plugin. It’s your plugin, after all, and you deserve the credit. But promoting the authorship is only half the picture, it helps if Google also knows who you are as an author. Then they can do something clever too:


    This is a sample entry for one of my plugins from the Rich Snippets Testing tool. The photo and authorship info may not show up on every search result that gets my plugin up on Google’s search results, but it certainly doesn’t hurt. But to get this information to be capable of showing, Google needs to connect your profile and user information on WordPress.org with a profile and user information from Google+. To do this, there’s two steps:

    Step 1: Edit your WordPress.org profile to include a link to your Google+ account. You can do this yourself, and you can see how I did it on my Profiles page. I included this link in my “About Me” section: https://plus.google.com/100201852715113506716?rel=author

    Note that the ?rel=author bit is important, that’s what tells Google that you are the author here and links your G+ account to this page.

    Step 2: Tell Google that you contribute to WordPress.org. To do this, go to your Google+ Profile. In the “Links” section you will find a “Contributor To” area. You need to add two links to this area:

    • The first link will be a link to your own profile page, on http://profiles.wordpress.org. This completes the connection and tells Google that you and the profile are the same person. Because your plugin page automatically links to your profile with the author information, making this connection creates an indirect authorship connection to all your plugins.
    • The second link you need to make is a link to http://wordpress.org itself. This is because Google wants there to be an explicit connection on the same domain name (not a subdomain), and so this link is required. And hey, you’re contributing to WordPress.org every time you update your plugin or theme, so well done there! :)

    After doing both these steps, you can try your plugin’s URL in the Rich Snippets tool yourself, and voila, you’ll see the magic. Note that you may not see it in the actual Google search results for weeks, and it may never appear. Google shows snippets like these on terms of their own choosing. All you’re doing here is to give them the data that lets their engine do the magic, if it can.

    • Gabriel Reguly 4:24 pm on April 16, 2013 Permalink | Log in to Reply

      Wonderful Otto! Thanks for sharing this.

    • Charleston Software Associates 4:28 pm on April 16, 2013 Permalink | Log in to Reply

      Coolness! Thanks for the step-by-step guide, Otto. Works great!

    • myatu 5:39 pm on April 16, 2013 Permalink | Log in to Reply

      I didn’t even know you could use HTML in the “About Me” section. Learn something new everyday! :)

    • Peter 6:14 pm on April 16, 2013 Permalink | Log in to Reply

      +1 for Otto!

    • Chuck Reynolds 6:26 pm on April 16, 2013 Permalink | Log in to Reply

      never had my about section filled out. html ftw. thx – good setup.

    • realloc 7:50 pm on April 16, 2013 Permalink | Log in to Reply

      +1 Excellent!!

    • Syed Balkhi 8:43 pm on April 16, 2013 Permalink | Log in to Reply

      Sweet. I just added authorship on my profile :)

    • Crunchify 8:52 pm on April 16, 2013 Permalink | Log in to Reply

      Great Tips. I’ve just updated my profiles..

    • Andrey "Rarst" Savchenko 9:13 pm on April 16, 2013 Permalink | Log in to Reply

      Had you considered implementing `link rel=”author” url=”[g+ profile]”` in plugin pages header? It will simplify setup and won’t need that “indirect” connection through profile page.

      • Samuel Wood (Otto) 9:17 pm on April 16, 2013 Permalink | Log in to Reply

        That would require us to set up a special field somewhere for a G+ account, and if that social-network, then why not add others too, and yadda-yadda..

        This was a freebie, basically. I didn’t have to make any code changes to do it. We’ve had rel=author in there pointing to profiles forever, and the schema.org markup has been there for at least a year or more.

        I just noticed that I seemed to have been the only one to have done this already when I was looking through some search results today, so I felt like a post to show people how was in order. I did fiddle with the markup a bit today for other reasons, but not for this post.

    • Marcel Brinkkemper 9:14 pm on April 16, 2013 Permalink | Log in to Reply

      This is great stuff. +1 for @rarst suggestion

    • Jon Brown 1:32 am on April 17, 2013 Permalink | Log in to Reply

      This is fantastic Otto, Thanks for the detailed write up. Would have taken way longer than I have patience to figure it all out on my own.

    • takien 2:45 am on April 17, 2013 Permalink | Log in to Reply

      Done, thank you :)

    • toddhalfpenny 9:35 am on April 17, 2013 Permalink | Log in to Reply

      Absolutely brilliant… lovely work… thanks.

    • Eric Amundson 2:26 pm on April 17, 2013 Permalink | Log in to Reply

      Thanks for the write-up, Otto.

      Looks like the WP.org plugin repo alphabetizes plugin contributors, correct?

      In trying to connect my profile, I found that the Rich Snippet Testing Tool, I get an error saying:

      “Note: The testing tool currently only checks the first rel=author link listed on a webpage for a link to a Google+ profile”

      Issue is that a former contributor has a name that starts earlier in the alphabet, so it’s always finding his author link first, but since he’s not linking to Google +, his avatar isn’t showing in results.

      Any ideas on how to force Google to see the profile of the correct user?

      • Samuel Wood (Otto) 2:36 pm on April 17, 2013 Permalink | Log in to Reply

        I don’t think it is sorted, actually. I think it shows up in the order in the Contributors line in the readme.txt file. But if you have an example I can see, I can track the code down.

        • Aaron D. Campbell 8:10 pm on April 17, 2013 Permalink | Log in to Reply

          Google “WordPress Twitter Widget” and you’ll see Sara’s pretty face, and she’s the last contrib in the list. However, check the Rich Snippet Tool and it shows me. I’m the first contrib in the list. I’d prefer it to show Range, but that one’s in the middle.

          I’m not certain this is the pattern, but that seems to be what’s happening now. I’ll try to tweak the contrib list on a few plugins and see what happens.

          • Samuel Wood (Otto) 8:17 pm on April 17, 2013 Permalink | Log in to Reply

            The readme.txt for that plugin has the people in the same order as the author listing on the sidebar does:


            I have no idea how/why Google shows faces or chooses between them. The rich snippets tool says first one wins, but this is neither the first nor the last time that Google has given me false or contradictory information.

            • Aaron D. Campbell 8:22 pm on April 17, 2013 Permalink

              Yeah, the rich snippets tool says the first wins (and displays the first person), but actual Google searches seem to be showing the last. Since you’re right about the order of contribs matching the readme, I’m going to try reording some to see what happens.

            • Aaron D. Campbell 6:33 pm on April 18, 2013 Permalink

              I gave it a little over 24 hours after the change, and as best as I can tell, Google just likes Sara better. She seems to be listed no matter the order. It may still be cached, but either way it’s still really cool.


            • Samuel Wood (Otto) 6:37 pm on April 18, 2013 Permalink

              24 hours isn’t enough time. Those things likely won’t alter for weeks or more. I know WordPress.org is well-indexed by Google, but seriously, their snippets logic is confounding sometimes. Best to just set it the way you want and let it do its own thing. You can’t force it.

              Mine didn’t start showing up until I changed my G+ pic to be a “recognizable headshot”. Guess they don’t like my scuba avatar. It’s a shame too, I like the blue one.

            • Samuel Wood (Otto) 6:20 pm on April 20, 2013 Permalink

              After screwing around with this for a while, and reading up on the topic, Google seems to get very, very confused with multiple rel=authors. So I just now changed it to only have one rel=author on the plugin page, and that will be the first person listed.

              Hopefully, this should eliminate the ambiguity and cause more predictable results.

    • Brad Dalton 8:56 pm on April 17, 2013 Permalink | Log in to Reply

      Been using this link on my profile for a while already but didn’t add the ?rel=author to the end of the Google url which does make a difference.

    • Mert Yazicioglu 9:31 am on April 20, 2013 Permalink | Log in to Reply

      Before doing this, my plugin WordPress Move was the second result in Google when you searched for “wordpress move”. Now, however, it’s on the third page.

      Not sure if it’s a coincidence.

  • Ipstenu (Mika Epstein) 1:51 am on April 11, 2013 Permalink |
    Tags: , api   

    Google Maps JavaScript v2 API To Be Removed 

    If you’re using the Google Maps JavaScript API v2 (and 78 of you are), your plugins will break on May 19th. This means we’ll not be accepting any plugins that use the old code (and probably will close your plugins that do if you don’t fix ’em).

    From Google, Google Maps JavaScript v2 (Deprecated)

    The Google Maps JavaScript API Version 2 has been officially deprecated as of May 19, 2010. The V2 API will continue to work until May 19, 2013. We encourage you to migrate your code to version 3 of the Maps JavaScript API.

    The Google Maps API lets you embed Google Maps in your own web pages with JavaScript. The API provides a number of utilities for manipulating maps (just like on the http://maps.google.com web page) and adding content to the map through a variety of services, allowing you to create robust maps applications on your website.

    The Maps API is a free service, available for any web site that is free to consumers. Please see the terms of use for more information.

    To use the Maps API on an intranet or in a non-publicly accessible application, please check out Google Maps API for Business.

    So please update your plugins.

    (Props to Kailey Lampert for this post)

  • Jon Cave 7:38 pm on April 9, 2013 Permalink |

    Review an intentionally vulnerable plugin 

    Imagine that another plugin author has asked you to look at a plugin that is currently in development to check for security flaws and help them fix any that are present. Would you know what to look for and how to fix the problems? Well, a fun challenge has arrived that will test, and hopefully improve, your knowledge in this crucial area of plugin development. I have developed a small, bug ridden plugin that requires a rigorous security review and suggestions for fixes.

    The code is available from https://gist.github.com/joncave/5348689.

    This is an incomplete plugin that aims to log any failed login attempts. Unfortunately, it actually harms the security of a site rather than enhancing it. All of the interesting parts are in vulnerable.php, so you should focus your review there. Please remember not to run this plugin on any server that is accessible to the internet!

    If you spot a vulnerability whilst reviewing the code then make a note of the problem, where it’s located and what the problem is. Then come up with a patch that would solve the problem. It might also be beneficial to create a request that would demonstrate the vulnerability which can then be used to test your fix. I hope that this process will help you understand more about vulnerabilities, what sorts of things to look for when reviewing your own code, how to go about coding securely, and how to fix any problems in your own plugins if a flaw is found.

    If you would like individual feedback on your finding and solutions, and to provide me with some information on which bugs people found and fixed, you can submit them via this survey. Please refrain from posting any spoilers in the comments for now.

    In a week or so I will write another post detailing each of the vulnerabilities present in the code and how to fix them.

    Bonus challenge: with access to a subscriber level account can you find any ways of extracting the data from an option named secret_option?

compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc