Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: security

  • I Don’t Understand CloudFlare

    I Don’t Understand CloudFlare

    If you know the answer to all this, I’d love to hear it, because I can’t figure this out. What’s the real point of CloudFlare?

    Fairly recently I was reading Tony Perez’s post about CloudFlare vs Incapsula vs ModSecurity. As regular readers may know, I am frenemies with Mod_Security. I often want to kill it with fire, but I never disable it entirely because it protects my site from hackers. By using Mod_Security I limit my chances of having Bobby Tables kill my site.

    Using Mod_Security gives you some protection from simple SQL injections, but also XSS attacks. You can integrate it with things like Project Honeypot. As they put it:

    ModSecurity™ is an open source, free web application firewall (WAF) Apache module. With over 70% of all attacks now carried out over the web application level, organizations need all the help they can get in making their systems secure. WAFs are deployed to establish an external security layer that increases security, detects and prevents attacks before they reach web applications. It provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring and real-time analysis with little or no changes to existing infrastructure.

    And you know what? It really does all that.

    So what’s CloudFlare? It’s an intermediary between your site and the world which caches your site, compresses data, and gives people the fastest version of your site. In the event your site is down, they’ll serve cached versions. They even give you a pretty picture.

    CloudFlare

    The first time I heard about this, I arched my eyebrows in surprise and confusion. I’m going to make my site faster by putting more layers between the reader and my content? That means instead of just relying on my server and host to be fast, serve compressed pages, keep the lights on, keep a speedy connection to the Intertubes, and do all the things that needs to happen for the magic pipe between my website and you guys, I’m doing all that and trusting someone new to help me do it better. Interesting, Captain. How are they doing this?

    squire3 CloudFlare has a few tricks to do this: CDN (content loads faster if it’s stored local to the people visiting the site), content optimization (minimizes and compresses page content), security (protecting you from DDOS and SQL injection), and analytics.

    Except when I look at that list I think that I already use mod_pagespeed to minimize and compress my content, mod_security to protect me (also Config Server Firewall for the DDoS stuff), and analytics is done by my server or Google. For me, that means the only thing they’re offering that I don’t have is a CDN. I read up on CloudFlare’s CDN, and they tout not having the weight of 15 years legacy crap. That’s a tricky edge to dance on, since they also don’t have the experience of those 15 years, or the network. In fact, looking at their network map, they have nothing in South America. Guess what the number two location is for people visting my sites? Brazil.

    And this, my children, is why you study your stats to understand who is visiting your site, where from, why, and with what browsers. Right away I can see that CloudFlare, while interesting, doesn’t seem to have any benefit for me. If I decide that I want a CDN, it’ll probably cost me around $30 more a month, minimum, for my sites and what they have on them today. Oh but wait, you say, CloudFlare is free?

    Yeaaaah. I don’t trust free services very much. A free app, once I download it and put it on my server, I keep. A free service is hosted on someone else’s server, at their whimsy, and is supported as they see fit. Yes, this means I don’t trust Facebook or Twitter. A free service is interesting only in that it lets me try it before I buy it, and for that, I approve of how CloudFlare does it. But the problem is today I went to a website and saw this:

    cloudflareddos

    What did I do? I didn’t visit this website. They can brag about the whole 30ms response time all they want, but if I went to a website and hit a barrier like that, I stop because it’s getting in the way of my surfing. That was my initial quandary about CloudFlare after all. How can it provide all these awesome things without getting in the way? And it can’t for everyone. At first I thought it was because I was going through bit.ly and it worried I was a spammer (okay, fair enough), so I tried manually, and it was the same problem. I just went to the page normally now, and it’s been well more than “5 seconds” and the site still hasn’t loaded.

    I fundamentally dislike anything that causes my users to do ‘more’ to get to my content. I think that it’s more harmful than a slow site, and it’s more harmful than letting these bad eggs visit my site. The right place to block a naughty person is when they’re doing something naughty. If my IP is a range of DDoS attackers, that’s one thing. You shouldn’t be detecting as the page loads, delaying me almost 30 seconds, and then loading the page. This delay is supposedly for my protection (me the site runner, not the visitor). Okay then, what are they protecting me from?

    Part of CloudFlare’s service is something called a Web Application Firewall (WAF), which is fancy-speak for saying their computer looks at what people are coming to your site to do, what data they’re sending, and tries to figure out if they’re nice visitors (which it should let through) or naughty hackers (which it should block).(From WP Shine Cloudflare: Early Reports Question Effectiveness as Website Security Tool)

    WAF came up before, with Mod_security. And at this moment, I go to a picture. Here’s what Tony parsed from the data:

    Screen Shot 2013-03-20 at 10.10.03 AM

    He asked on Google+ what we took from that article, and my reply was “That the months I spent mastering mod_security was totally worth it.” If you don’t trust Tony’s numbers, you can read the full report on slideshare for yourself. Tony has the same feelings about Captcha as I do, by the way, though less strongly. I despise it more than I hate hotlinkers, and I hate hotlinking. Captchas are the worst barrier between content and consumer that was ever invented. They don’t work, they’re not accessibility friendly, and they are rarely implemented well. Hotlinking may be theft, but Captchas are shouting “No soup for you!”

    Which brings me to my point.

    What is CloudFlare doing? In plain english, can someone explain to me how it would benefit me? Ignoring the CDN aspect, the only WAF part I can see benefiting me is that CloudFlare (and Incapsula for that matter) essentially crowdsource the list of people who are ‘bad’ and shouldn’t access my site. Which is cool, and that I certainly like. It’s sort of like a Project Honeypot for baddies (and by the way, that would be a nice feature). Having the world bring in the list of bad people, as well as their patterns, and sharing that back out is a great way to keep everyone up to date quickly and seamlessly.

    I really just can’t see why I’d ever want to use CloudFlare. It would certainly be a cheap and easy way to put some possible gain on my site, but in the long run I feel that managing these things myself (or hiring someone to do it) would be a better business solution. It saves me from the dread blackbox spam killer, which means I always know what’s going on. Now I know not everyone is capable of handling all this themselves, but from what I’ve seen, most webhosts already have mod_security running. So lets drop the WAF argument from the table, and we come down to the best thing CloudFlare’s doing is acting as a CDN and compressing content. That’s not good enough for me. At that point, you may as well use Google’s PageSpeed Service

    I’m sure there are great reasons for using CloudFlare, but I just can’t see it.

    Quick ETA… Talking to a coworker, it occurred to us that I may just not be their audience. I’m too big already and I took care of most of what they do. I can look at this and think “If I just have a small site and I want to speed it up on a shared server where I have no root nothings” then it looks way more reasonable. But I’m not.

  • Don’t Tread On Me

    Don’t Tread On Me

    Even the non techs have been hearing about Do Not Track lately. The basic idea is that letting advertisers track you is annoying, frustrating, and something a lot of us just don’t want, but moreover, we don’t want random websites doing the same thing! Imagine if you went into Starbucks, and they followed you around to everywhere else you went that day? Starbucks.com could do that, and I personally find it invasive.(I’m not the only one. My friend Remkus goes even further than I do.)

    This is, in part, what that stupid EU law was trying to tackle.

    There are a lot of ways to block that sort of tracking, but the latest way is to use Do Not Track (DNT). Turning on DNT on your browser puts an extra header in your web page requests that says “Don’t track my behavior!” Now, the only real downside is that both your browser and the site you’re on have to agree to these rules for it to work, but with Microsoft in the mix, turning DNT on by default for Windows 8, I think we’re on the right track.
    If you go to IE’s testdrive of DNT you can see the status of your current browser, and all others.

    Interstingly Chrome doesn’t have this yet, and when it does, it will default to track. Safari does that too. It’s weird for me to be saying ‘Microsoft has it right’ but I suspect it comes down to how advertising works. Microsoft really doesn’t need to advertise except to improve their image. Everyone knows Microsoft, and they know Office, IE, and Windows. Apple’s still a small percentage, and Google was a techy thing for so long, I think that’s why their first social network failed. Because Microsoft has such a percentage of non-tech users (i.e. everyone) and because of their bad rep, the best thing they can do to improve everything is start protecting the users more.

    Of course, we all know that being tracked is a function of being online, or even in a store. Physical stores have often watched where people linger to figure out how to better arrange stores, and they ask for your zipcode when you show to understand who buys what. This is all a part of marketing. Of course the problem with online is that the more I search for something, the more I see it in my ads (Google). Why is this a problem? Let’s say I research a MiFi device, find the one I want, and buy it. For the next four months, I got ads for MiFis.

    I should explain, while I have no problem with people tracking me for analytics (I rely on them myself, can’t understand your visitors without data), its what they’re doing with that data that pisses me off. Getting my info to make a better product for me is great. Getting my info to sell to people is not. And that’s why I’m for do-not-track. Or at least ‘Ask to track.’ It goes back to the store. If I go to Office Depot, they ask me for my zipcode or phone, and I can decline. They use that to track me, and if I don’t want them to know that I drove 80 miles to get something, I don’t have to tell them. Online, I should have that same option.

    Sadly, the steam behind Do Not Track is running out. Ten months after everyone agreed this needed to happen, nothing’s happened and that’s problematic. Why did we all go dark over SOPA? Because, at some level, we all believed that the Internet is changing things for the better. And yet, we all promised to have Do Not Track up by the end of 2012, and that sure didn’t happen. Then again, we’re merrily Thelma and Lousie’ing right off a fiscal cliff too, so this really isn’t a surprise.

    I’m actually against ad-blocking software, and yet we’re at the point where I’ve installed it on Chrome, and I’m starting to block people. Oh, I run the other way with this. I only block certain sites (generally I’ve taken to blocking ones that have annoying ‘overlay’ ads) because, again, I get that people need these metrics to make things work, and I too make money off ads.

    In fact, this is yet another reason I use Project Wonderful for my ads. They have a very simple policy:

    Specific tracking of user interactions that don’t involve clicks is not allowed, including view-through tracking, key-modifier tracking, and mouse-location tracking.

    So please, allow ads on my sites. I promise I don’t track you with ads. I do have Google and Jetpack tracking your visits, but that’s just for me to measure how things work on the site, and I will never sell or otherwise use your personal information for my own gain.

  • Scorched Earth Security

    Scorched Earth Security

    This post is dedicated to Matthew Freeman, who donated to help me get to WCSF. I have not forgotten coffee.

    Napoleon’s invasion of Russia
    Napoleon’s invasion of Russia
    There’s been a lot of kerfluffle about hacked systems again, especially that the ‘auto upgrade’ isn’t safe. I want to point out that your automatic upgrade of WP and its plugins is prefectly safe, if your system hasn’t been infected. Once you’ve been infected, however, it’s a whole different ball game. I subscribe to the salt-the-earth philosophy of cleanup, but more on that in a moment.

    Odd as this may sound, I tend not to spend any time determining where the hack was. My feeling is that the longer a hack sits on my live server, the worse off I’ll be. If it starts to happen repeatedly, I may look into it more. But generally speaking, a hacked site boils down to some pretty obvious avenues of attack:

    1. Insecure password on your server
    2. Insecure behaviors
    3. Bad plugins/themes/extensions
    4. An insecure webserver

    You notice that I’m leaving the apps themselves off the list? For the most part, a hugely explioted hack isn’t an app vulnerability. Most well used apps, like Drupal and WordPress, are remarkably well tested when it comes to that, and the developers are quite attentive. The weakest point in the security tripod is going to be the user. When I was exploited, you bet your ass it was 100% on my head, and no one else’s.

    So when I see a web-app get hacked, my first thought is not ‘debug from whence it came’ but ‘get the file off the server — now.’ If you leave the hacked files on the server, the odds of your site going down again and again increases, so the very first thing I do is download everything. Every single file, the database, and everything that sits on that server. I back it all up on a computer, preferably one with a good security/virus scan tool, and then I get started on the real work. I’m going to come back to those files and review them, but that’s later. Right now I need to get what I have clean.

    Make a list of everything on your server. Separate your ‘personal’ files from the application files. For example, in WordPress I would list my themes and plugins as the ‘application’ files, because I can easily download them from the repository. My ‘personal’ files would be the images in /wp-content/uploads and /wp-content/blogs.dir, the .htaccess file and my wp-config.php file.

    scorched earthNow here’s the scary bit. Every file gets deleted off the server. Yes. Every file. When it’s WordPress, I kill it all with fire except those personal files.

    Then I download fresh copies from WordPress.org (and only WordPress.org) but I don’t copy them up. No, instead I change my server password, and my SQL password. If I’m having an extra neurotic day, I may make a new SQL id and use that instead. Regardless, it’s Password Changing Day. If I used that password anywhere else, it gets changed there too.

    Still with my site down, I look over my .htaccess and config files with a fine toothed comb. I know what’s supposed to be there, and I know what’s not. I’ll also scan my personal files (all those image folders) for any .php or .htaccess files in there. See, nothing but files I uploaded are supposed to be in there, so if anything is, it’s bad.(If you use caching plugins, you may have other files in there, but you should already know that. Still, it’s best to turn off any caching you have while you rebuild. Change the cache constant in wp-config to off, and remove the cache folders from wp-content.) If I find anything, I delete it (though I will make a note of the time/date that file was updated, and since I have my backup, I can look at it in depth later). I’m also going to make sure permissions are right. I want things to be secure.

    Finally I upload every new file back up from my fresh copies, and then make sure my site still works. It should.

    It used to be that people told me I was silly for doing this. It was overkill, surely I could just change passwords and remove the infected file. Sure, that might work. The problem is these guys are getting smart. Denis uncovered a pretty cool (if evil) hack, where your updates are compromised, and basically from now on, you’re getting hacked code. With my method, you’d be ‘safe’ from that continuing.

    Of course, you’re not safe from it happening again, as you could be hacked again, and this is where we have to start digging into logs and sorting out what the hack was and how it happened. And that is a different post all together.

    If all of that is too much for you, and it can be, I recommend hiring Sucuri. For $90 a year, they’ll monitor your site for you. If that sounds like a lot, that’s $7.50 a month. You can spare the latte.

    Sucuri Security

  • Art History of Plugins

    Art History of Plugins

    This post is dedicated to Lisa Sabin Wilson, who donated to help me get to WCSF. Lisa is to documentation what I am to the forums, and encourages me to write better (though she probably didn’t know that).

    A Sunday on La Grande Jatte, Georges Seurat, 1884Quite often people suggest that we ‘weigh’ the usefulness of plugins and themes in the WordPress repository differently. Some want to use star ratings, other popularity, and others compatibility of WordPress Versions.

    Invariably, if I get roped into these discussions, I say ‘None of it maters more than the rest.’ And people always argue that their chosen method is the best. No one has ever succeeded in convincing me they’re right and, I’m pretty sure, no one ever will.

    The reason I’m so sure about that is the same reason we don’t just buy cars based on the tire size, or a house based on a bathroom. It’s the reason we research and compare, study and inspect, and ask our friends. It’s because we know to look at the big picture.

    Let’s look at A Sunday Afternoon on the Island of La Grande Jatte. From afar, it’s simple. A painting of people on the island. But if you walk up to the painting (it lives in Chicago, I love visiting it) you’ll see Seurat painted entirely by dots! As you step in and out, the painting changes and your perspective and understanding of the work as a whole changes. You cannot simply say ‘There is blue paint.’ and make your final decision that this painting will look nice against a blue wall. You have to consider how it will look up close, far away, and will it be better to blend or contrast. Seurat liked the contrast, which is why it has a brown border and a white frame.

    The small moments, those dots, make up the whole of the piece and you have to consider everything that went into it, if you want to understand the painting. Anyone can look at if from afar and say ‘Yeah, nice.’ But when you start looking at the work, and the layers of meaning, you see things differently. With art, that’s the point. Sometimes a painting is just a painting, and sometimes a story is just a story, but more often than not, the ‘deeper meaning’ your teachers were after you to get from a story is simple: Look at the whole story. Look at how each character’s actions become a part of the whole.

    This relates, directly, to understanding plugins. At heart the question people are asking is simple: How do I know which plugin is the best to use for this situation?

    You can’t just take one and say ‘This is compatible with 3.4, therefore it is superior!’ I wish you could, my life would be easier. Instead, you must learn how to review plugins critically. Don’t throw your hands in the air, you don’t need to know code to do this. You do need to know what you want, and you need to read and pay attention, but at this point, if you’re still reading this blog post, you know how to do those.

    The secret magic, which I talk about in WordPress Multisite 110 (Chapter 6: Security, Plugins, pg 36), is to review all components of a plugin’s information. You have to look at how all the little dots make up the whole picture — that’s why we talked about Seurat — and use those to understand how likely a plugin is to be safe to use.

    Who wrote it? If I see a plugin written by someone I’m familiar with, I’m more inclined to trust their work. I already know how to get in touch with the developer if something goes wrong, and we have a rapport. Second to that is if they work on WordPress core. If they have commit access, I trust them (even Otto, who’s broken the site before). If they’re a regular contributor, it’s much the same. However this is not ‘common’ information. It’s easy to find, but it’s not something everyone knows off the top of their head. You can quickly search trac for their user name. I find it easier to limit the search by changesets, so here’s a search for wpmuguru’s credits in changesets. Yeah, looks like a trustworthy fellow!

    What does their website look like? In cases where the developer doesn’t have any core contribs, move on to look at their website. Is it the generic version of WordPress with barely any content? Is it a Geocities flashback? You know crappy websites when you see them, and a crappy website for a developer warns me that they don’t use WordPress the way I do. Little to no content implies they’re not writing posts, and if they aren’t writing posts, how do they keep up with the look and feel dynamic of WordPress?

    Is it well documented? Documentation is king. A plugin that is poorly documented, with poor spelling and grammar (regardless of language), and no screenshots makes me Spock the eyebrow. Not every plugin needs a screenshot, but a plugin should have the basic information included on that page. I’ve started copying my readme content into the contextual help in my plugins, for extra documentation levels. The point is, if the documentation is sparse, either the plugin is really simple, or you’re going to have a bad time of it when you have a problem. Developers, document. It will save you a lot of time.

    How often is it updated? This is where we start to get weird. The simpler a plugin, the less it needs to be updated. Impostercide has barely changed since WP 2.5. I do update it about once a year, to change the versions, or add internationalization/help screens, etc. The bones of the code have not changed since 2005, and the original version still works just fine. Not every plugin should be updated every month. Now a more complicated plugin, I’d actually like to see it updated more often, with smaller changes. Don’t change it all at once, after all. Review the Changelog (if they don’t have one, it’s not well documented). See what’s being changed.

    What problems have people had? Recently the Andy/Otto team made it easier to see the forum posts associated with a plugin, which means it’s easier for you to see how active a developer is with support, and how problematic the plugin is. Many of these issues are user-based (i.e. they’re not sure how to use a plugin), but sometimes they’re actually bugs. Check how many problems have people had, and if they are resolved. This example is a great sign:

    Support Example

    Compatibility MatrixWhat’s in the Compatibility Matrix? This is a very complicated thing, but it’s also very telling. Knowing how many people have reported a plugin works or doesn’t work, and getting an average, can help you. Sometimes you have to go back and forth, checking various plugin versions to WordPress releases, to get the whole picture, though, so it can time time to understand what’s going on.

    Requires, Compatible Up To, Last Updated, Downloads, RatingWhat Else? Only now do I take a look at things like downloads, what the author says it’s compatible to, when it was last updated, and what the stars are. Why? Because unless an author has written ‘This plugin will not work on WordPress 3.4!’ in the readme, there’s a darn good chance it’s just fine and they didn’t bother to update. And that pisses off a lot of people.

    Look. There’s no feasible way to force the developers to update their plugin documentation right now, and even if we did, there’s no way to assure they got it right! People make mistakes, which is why we have to learn to use our brains and think about what we want to do before we act. Yes, it’s work. As I’ve said many times, running a website is work. It’s always going to be, so at least try to work smarter.


    I didn’t touch on code reviews at all, but what tips and tricks do you use when you’re collecting all the dots and evaluating a plugin for use?

  • Highway To Plugin Danger Zone

    Highway To Plugin Danger Zone

    Danger ZoneThis post is dedicated to Mark Jaquith, who donated to help me get to WCSF. Thank you, Mark!

    There’s nothing wrong with using someone else’s code. All of us do it. That’s how we make something new: by building off the old. And we all build code that relies on someone else, even when we write operating systems. Everything is interdependent, and that’s okay. The problem with relying on someone else’s code, is that you’re open to their vulnerabilities.

    Recently there was a kerfluffle about TimThumb, where the community came together and made a script, used by many themes and plugins, better and safer. This was an awesome moment, where we saw disparate strangers overcome FUD and live up to the dreams of Open Source.

    In more recent days, there have been a lot of problems with the Uploadify script, to the point that Sucuri wonders if it’s the new TimThumb when it comes to overuse and vulnerability. Unlike TimThumb, Uploadify isn’t actually insecure due to a bug, but the design of how it works is insecure. Yes, it’s insecure by design. Uploadify allows easy multi-file uploads to your site, but it does it without integration with any user verification, so basically anyone who knows where the file is can upload anything they want to your site.

    Uploadify offers some security suggestions, which encourages you to use the right folder permissions, keep the file outside of your public_html, and use SSL. The problem there is you’re still not checking to make sure that the code is only accessed by the right people. This isn’t a flaw in Uploadify. It’s a flexible product that can be used with anything, so they don’t want to lock it down to just WordPress, Drupal, Joomla, or whatever. This is, alas, the reason it’s so dangerous. Anyone can hook into it, if you don’t make it secure enough.

    Now. A handful of WordPress plugins have been closed due to uploadify exploit potential (between 10 and 20). Not a lot, when you think about it. That’s because, perhaps surprisingly, not as many people are using it as you’d think. In part, this is from WordPress’s shift to plupload in WordPress 3.3, which allows you to hook into it in themes and plugins. By the way, I recommend you use plupload, because if you’re going to rely on third party code, it should be the one that comes with WordPress core.

    Beware! Insecurity AheadThe point is not to not use third party code, however, but to use it wisely and to use it safely. It’s your responsibility as a developer to make sure your plugin is secure, and to know what it does. If you don’t understand how someone else’s code works, don’t use it in your plugin, because by using it, you are now responsible for updating it, securing it and keeping it safe. How can you do it if you don’t get it? Furthermore its your responsibility to educate your users as to what a plugin does and how you’ve secured it. This is open source code, the bad guys can already peek in and see what’s up. If they know, then you owe it to the users to arm them with education.

    The weakest link in the security chain is the education of the end users. The servers, we hope, know what the heck they’re doing. Ditto the software writers. But the users, they’re often the new guy, the one who doesn’t know what’s what yet, and they trust you. They trust you do your best. Note, I am not saying they trust you to be perfect. Anyone who expects perfection is ridiculous. We all desire it, of course, but you cannot expect it unless you yourself can deliver it. Can you? I thought not.

    Alright then so what can you do to protect uploadify and similar scripts? First, lock it so it’s only accessible from the WordPress dashboard panels. If you can only get to it via WP, then you’ve locked yourself so no non-logged in users can access the tool. Then if you slap this code into the top of your file, no one can access it directly:

    if ( ! defined( 'ABSPATH' ) ){ die( 'Direct access not permitted.' ); }
    

    Next we should look into how we check for the user. Can any member of your site upload? Probably not. So let’s use capabilities and roles to lock it all down and make sure only the right users have access. We can use two simple lines to verify the user is logged in, and has the right capabilities to upload. The ‘manage_options’ cap is for Administrators, so loosen it up as you need:

    if ( ! current_user_can('manage_options') )
    die( 'Not allowed to upload.' );
    

    You can hook an upload handler up as an AJAX handler via WP’s admin-ajax.php, per AJAX in plugins. If you need a non-AJAX handler, you can handle form submissions on your plugin admin pages. Going through WP gets you authentication and capabilities checking, and easy usage of nonces (see wp_create_nonce() and related links at the bottom of that page for more info).

    There are of course more ways to secure things. There are nonces and AJAX, as well as using WordPress’s image tools to help double check if a file really is an image. After all, not everyone can use .htaccess, and some servers are silly enough to let you run a php file with a jpg extension.

    But all that really only works if you want to restrict your uploads to members of your site. What if you want to let anyone upload an image? Honestly, you should re-think that. You are not imagur or imageshack. They have layers of server protections which you don’t, and they have levels of checks and balances in software written specifically for image uploads and protections. You don’t. They are a tool specifically for the job of images. WordPress is not. Do you see where I’m going? Do you really need to allow images be uploaded to your site? I bet you don’t.

    One Insecure Link in the ChainShortly after TimThumb was exploited, it was yanked from the theme repository. Since WordPress 3.3 no theme can contain TimThumb. From what I can gather, part of the reason is that code like that should be a plugin, not a theme. But personally, I think that both TimThumb and Uploadify should have official plugins (supported by the original/current developers), and anyone who wants to use that code can hook into those plugins. Then, if there’s an exploit, it’s one plugin to fix and not a couple hundred.

    Of course there are as many flaws with that as with any other approach. If the original devs don’t want to support a plugin for WordPress or any other platform, the users would be SOL.

  • jQuery – Why U No Enqueued?

    jQuery – Why U No Enqueued?

    DevoThis is a followup to my how to get your plugin in the WordPress repository post.

    While code isn’t outright rejected for being ‘bad’ code (only security holes and guideline violations), a lot of plugins are doing the easy things wrong. These plugins will get approved, but they won’t work with all setups, they’re more likely to have issues with Multisite, and they’re just not thinking forward. They aim to solve a, singular, problem, without looking beyond. Primarily I see this when people are trying to bring in some js code into their plugin. Heavens knows I do it, and I’ve done it wrong too. But as I see more and more plugins, I’m starting to get better and better at knowing what’s wrong when I see it.(“I know it when I see it” thanks to United States Supreme Court Justice Potter Stewart)

    The easiest way to show you is to give you some really bad examples and go through some of the steps to fix it. The best part is that I’m actually going to use real plugins I’ve seen. Only the name has been changed to protect the innocent.

    Ready? Here’s what we’re doing wrong.

    Not using functions to define locations

    The very bad code:

    echo '<script src="/wp-content/plugins/myplugin/myscript.js"></script>';

    I wish this was something I made up. Worse, I’ve see it more than once. Recently.

    This install is assuming WordPress is installed in the root of your HTML folder (i.e. domain.com). This is not always the case, as many people install WordPress in subfolders. We’ll need to fix that first with home_url().

    echo '<script src="'.home_url('wp-content/plugins/myplugin/myscript.js').'"></script>';

    Now it’s a little better, as by using home_url() we’re letting WordPress define where ‘home’ is. Great! This has two pretty obvious problems, however. First, if I have WordPress installed in a folder, like /public_html/wordpress/, but I’m running it out of the main domain by giving it its own directory, this won’t work. Your code would point to http://example.com/wp-content… when mine is in http://example.com/wordpress/wp-content.. instead! The ‘easy’ fix is to change home_url() for site_url(), but what if I’m not using wp-content? You didn’t know we could Move wp-content? We can. So let’s address that.

    echo '<script src="'.content_url('plugins/myplugin/myscript.js').'"></script>';

    By using functions to determine plugin and content directories, we can make this much more flexible. That works, but it could be better. What if we didn’t have to define the plugins or myplugin folders? We could just do something simple like this.

    echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';

    Now we have a simple, flexible, functional script embed of js. Except there’s one, minor problem. We’re not including the script correctly.

    Not enqueuing files

    This isn’t ‘wrong’ really. I mean, if I put this in my plugin, it would echo out the script, and that’s what I want, right?

    echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';

    But let’s say I want to put it in my header:

    function my_scripts_method() {
        echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
    }
    add_action('wp_head', 'my_scripts_method');

    And now I want to include my CSS so it looks pretty:

    function my_scripts_method() {
        echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
        echo '<link rel="stylesheet" type="text/css" href="'.plugins_url('myscript.js',__FILE__).'" media="all" />';
    }
    add_action('wp_head', 'my_scripts_method');

    Oh, wait, no, I wanted my JS in the footer:

    function my_scripts_method_foot() {
        echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
    }
    function my_scripts_method_head() {
        echo '<link rel="stylesheet" type="text/css" href="'.plugins_url('myscript.js',__FILE__).'" media="all" />';
    }
    add_action('wp_head', 'my_scripts_method_head');
    add_action('wp_footer', 'my_scripts_method_foot');

    And really, this will work. But it’s not efficient, I’ve got extra actions, and I’m not considering any jquery dependencies anymore. By using wp_enqueue_script is better. Weblog Tools Collection did a series on how to properly add scripts (note that it’s a bit out of date with the use of WP-CONTENT constants). From that we can extrapolate to use just this to include our js and css:

    function my_scripts_method() {
        wp_enqueue_script('my_script', plugins_url('myscript.js',__FILE__) );
        wp_enqueue_style('my_script', plugins_url('myscript.css',__FILE__) );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');
    

    What enqueue does is put your code in the best possible location and can be extended to load dependencies. wp_enque_scripts has a lot of power, and because it’s a WordPress function, it’s got options that make it more flexible. Like when I look at my above code, I remember, oops! I wanted to run my js out of the footer! Not a problem. Look at my options.

    wp_enqueue_script('handle', 'source', 'dependencies', 'version', 'in_footer');

    jQuery Logo looks like a Devo HatThe ‘handle’ is what I want to name my script, it should be unique. If I register my script, I can call the handle over and over again. We’re using my_script right now. The ‘source’ is where my file is located. We’re lifting that from our other code, the bad code, because it works. Your ‘dependencies’ are the other js files yours needs to function. If I put in array('jquery', 'scriptaculous') then both jQuery and Scriptaculous would get loaded before my script. Curiously, you don’t actually need the ‘version’ option, as you can leave it blank and WordPress will automatically add a version number equal to the current version of WordPress you are running. So every time you upgrade WP, it will get updated and force a re-download. This is good, since if you have dependencies to scripts included in WordPress, and they change with a new version (which is the only way they can change), then you get updated too. Finally we have the value I was looking for, ‘in_footer.’ Leave it blank and it’s in the header, put in true and it’s not.

    This makes my code:

    function my_scripts_method() {
        wp_enqueue_script('my_script', plugins_url('myscript.js',__FILE__), '','', true ););
        wp_enqueue_style('my_script', plugins_url('myscript.css',__FILE__) );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');
    

    Yeah, isn’t that a lot easier?

    Using a different jQuery

    This last one I’m going to touch on today is the exact code I saw, in the wild, and it’s got two of my three buggaboos in it.

    wp_enqueue_script('jquery-1.4.3.min.js', '/wp-content/plugins/myplugin/js/jquery-1.4.3.min.js');

    Okay. You already know the right way to call the script, so we’ll edit that into something more flexible.

    wp_enqueue_script('jquery-1.4.3.min.js', plugins_url('js/jquery-1.4.3.min.js',__FILE__) );

    That should be okay, but it’s totally not.

    Most importantly here, we’re calling jquery, which is actually built in to WordPress. Now, we’re calling it by a different handle, but that’s no guarantee that it won’t cause conflicts. In fact, I’m pretty sure this will cause no end of problems with some plugins. The right thing to do would be this:

    function my_scripts_method() {
        wp_deregister_script( 'jquery' );
        wp_register_script( 'jquery', plugins_url('js/jquery-1.4.3.min.js',__FILE__) );
        wp_enqueue_script( 'jquery' );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');

    Now we’re making sure we won’t have conflicts by re-registering jquery, replacing it, and moving on.

    A lot of people would actually recommend using Google instead, as it takes the responsibility off you for including a file you don’t ‘control.’ Also it makes your plugin smaller and load faster.

    function my_scripts_method() {
        wp_deregister_script( 'jquery' );
        wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js' );
        wp_enqueue_script( 'jquery' );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');
    

    Devo Hat looks like Devo HatGreat! Now we’re done, right? Wrong. As of this writing, WordPress is using jQuery 1.7.2. Now I couldn’t come up with a reason to include an old version of jQuery in WordPress (newer, yes, older, no), so I asked around and none of my friends could either. Using an older version is more likely to cause issues with newer code included in WordPress, as well as plugins which are upgraded to take advantage of the new features. You’re shooting yourself in the foot. The only thing you might be using this for is to include deprecated fictions, and really you need to update your code to fix that instead.

    If the whole point is to load the scripts from Google, though, there’s an awesome plugin for that.