Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: wordpress

  • Mailbag: Site Security Plugins

    Mailbag: Site Security Plugins

    This one comes from Gabriel and WordCamp LAX:

    Hello, I met you at WordCamp LA 2014. Thank you so much for speaking there and giving me great advice. I am now in a pickle again though, I wanted to ask you as an expert. What premium/pro version of site security protection would you find to be the best for a WP site? I am now using the free version of iThemes but I want to start buying pro version of iThemes, which would be $40 a year for a client.

    I don’t use any security plugins on this site. I use Mod Security, some complex .htaccess rules, and a firewall app on my server. None of the weight of the security is on my WordPress install for a few reasons.

    This site may be a nice massive Multisite, but on this server I have a dozen other WordPress sites and not all are my own. I also have a gallery and a wiki, a forum, and a few other non-WordPress things. Using just a WordPress plugin leaves about a third of my site not protected. Worse, it means I have to be sure all my ‘customers’ are equally protected all the time and upgraded and configured right. I opted to take that out of their hands.

    Most major hosts (DreamHost, BlueHost, GoDaddy, LiquidWeb, etc) all have Mod Security and a firewall, or some equivalent. Some of them have fail2ban and others have CSF but they all do have server level protections that frankly do a better job of protecting you against a brute force attack than a plugin ever can. I’ve said this before in many different ways but I’ll spell it out again. I don’t believe a plugin is ever the best choice to protect you from a DDoS. That does not mean a plugin doesn’t help, but it does mean I would never use it as my first and only defense against attacks and hacks. The practical reason is that it makes a site slower, to have it recursively check things.

    With that said, there is a different sort of ‘protection’ to be gained from a security plugin, and that is notifying me as to what files are changed. If you’re using cPanel, WHM has a feature to email you about Recently Uploaded Cgi Scripts which emails me when certain core files on my server changes, but also when a plugin upgrades and messes with email:

    /home/ipstenu/public_html/wp-content/plugins/contact-form-7/includes/submission.php:240:
    /home/ipstenu/public_html/wp-content/plugins/contact-form-7/includes/submission.php:241:       private function mail() {
    /home/ipstenu/public_html/wp-content/plugins/contact-form-7/includes/submission.php:242:               $contact_form = $this->contact_form;
    

    That’s one of my favorite things, by the way. It’s a rare email to get, but I love getting it because I know what dangerous emails are sent. There’s also an add-on feature of CSF called ConfigServer eXploit Scanner which can be used to send emails when any file is changed. This is awesome for scanning PHP changes and even is aware of WordPress though it’s probably going to have a lot of false positives given the nature of WordPress upgrades.

    And this does get us to where I do use security plugins. Rarely, yes, but when I do use them I use products like a malware scanner to make sure my files aren’t changed without me knowing. You hear that called “Security File Integrity Monitoring” sometimes, and the idea is that I want to know when any files on the server are changed. But since Gabriel mentioned ‘for a client’ I can guess that he doesn’t have admin access to the server, which makes the whole thing a lot messier.

    The weakest leg in the security tripod is users. Sorry. Users are people. We make mistakes, we eat gas station sushi (hush, Otto, you get the point), and we don’t think about our actions.

    With that in mind, which plugin would I use? It depends on the client and how much help I think they’ll need cleaning up, and how much help I’m going to be expected to provide. I’d be inclined to hook them up with a service that can help unhack them if I’m worried about that, or if I know they can follow directions well, then a simple scanning plugin is fine.

    It’s really not a simple answer, though.

  • Working With A Translator

    Working With A Translator

    Well I messed that up.

    I’ve never been on a panel before, and I’ve never worked with a live translator before, except once and that was ASL which is different. This time, at WordCamp Tokyo, I was on a panel to talk about the Worldwide Community of WordPress, and other things, and we had a wonderful translator with us, Shinichi Nishikawa. But I’m afraid we made things very hard for him.

    My father, who’s more experienced, gave me a critique later and I have some points to share with everyone.

    • Speak one sentence, wait for it to be translated, then move on.
    • Keep your English simple.
    • No cliches, idioms, or slang. Not even technical slang.
    • No jokes. They won’t translate. Don’t even try.
    • Don’t laugh at yourself either.

    It’s remarkably hard to do this. I’m getting a little better at it, because my father’s wife is Japanese. While she understands some English, I would say her English is better than my French, and she’s mostly fluent in French. So we dance between three languages to try to communicate. With that in mind, I find myself trying for the smallest, easiest, most common words when I want to explain something.

    For example, at dinner she was trying to say that my father has no sense of direction. This is true, but in Japanese there’s a word to mean ‘you lack this skill.’ You can apply it to anything, and as we were talking about it, she asked what the word was, in English, for someone who has no sense of music. We explained it was ‘unmusical’ or ‘no sense of music’, but I also mentioned ‘tone-deaf.’ This lead to us saying things like “You are tone-deaf in driving!” Where English will put a modifier on the word, the Japanese have a second word to add in front that puts the proper emphasis.

    Understanding that one, small, thing changes what words I want to use when explaining WordPress (or anything) to someone who doesn’t speak my language natively. I’ve done this before, with normal conversations and travel, but doing it for WordPress was very hard because we’re used to things like ‘doing_it_wrong()’ and even ‘Howdy, Ipstenu.’ Those are small words we think of as normal and simple, but their concepts are so large they lose something in the translations.

    Besides just words, I’ve learned we definitely need to translate our brochures into the language of the country we’re in. Not having the pamphlet be in Japanese was a killer. Also our little DreamHost Robots need names!

    Our DreamHost Robots

    Everyone thought our mascots were adorable, but they needed names. Since we have three stickers, one of them being tiny, I said we should call the little one “Yume-chan” because Yume (夢) means Dream in Japanese, and ‘chan’ is a diminutive. My father calls me ‘Mika-chan.’

    Wapuu Just for an example, Wapuu is the mascot of WordPress in Japan. So really anything small and cute like this needs a name.

    Knowing that, I feel more prepared next time not just should I come again to Japan, but also in general for how I present at a WordCamp. Every time I come to one, I learn a little more and a little more about myself, WordPress, and how we all communicate.

    WordPress democratized publishing in more than just your website, after all.

  • Featured Image Size Redux

    Featured Image Size Redux

    One of my themes didn’t have a Genesis Featured Image.

    Actually it did, but it didn’t have it as an named additional image. And this was a problem because I like to have the featured image size listed in my featured image box, as I explained how to do in my post about how to do this in Featured Image Size. That theme was using the ‘medium’ size for featured images, which meant by code made the box look like this:

    Busted Featured Image Size

    This is because I had no $_wp_additional_image_sizes, and that’s what I meant when I said there was no named additional image size. So I had to change up my calculation and check first if the name of the image size was one of the defaults, ‘thumbnail’, ‘medium’, or ‘large’, and size off that and then check the other options.

    Which gives me this:

    // What is my image size?
    add_filter( 'admin_post_thumbnail_html', 'helf_admin_post_thumbnail_html' );
    
    function helf_admin_post_thumbnail_html( $content ) {
    	// Define what the name of our featured image size is
    	$genesis = get_option('genesis-settings');
    	$genesis_image_size = $genesis['image_size'];
    
    	// Get featured image size
    	global $_wp_additional_image_sizes;
    
    	if ( in_array( $genesis_image_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
    		$size_width = get_option( $genesis_image_size . '_size_w' );
    		$size_height = get_option( $genesis_image_size . '_size_h' ); 
    	} elseif ( isset( $_wp_additional_image_sizes[ $genesis_image_size ] ) ) {
    		$size_width = $_wp_additional_image_sizes[$genesis_image_size]['width'];
    		$size_height = $_wp_additional_image_sizes[$genesis_image_size]['height'];
    	}
    
    	$my_featured_image = $size_width.'x'.$size_height;
    
    	// Apply
    	$imagesize = '<p>Image Size: ' . $my_featured_image . 'px</p>';
    	$content = $imagesize . $content;
    
    	return $content;
    
    }
    

    Right below the global check, I do an if to scan the array and grab the sizes based on that. It’s exceptionally simple, and the major change was moving it to set variables and then setting based on those outside of the if/else check. But it works perfectly on both my sites with regular sizes and the fancy sizes.

    I still don’t have a check to see if the theme is Genesis or not, but this multisite is 100% Genesis for all sites, so it’s not an issue for me. If anyone has a way to check “Is this active theme on this site Genesis or a child,” please share. The world will thank you.

  • Single Site Login Loop

    Single Site Login Loop

    Have you ever tried to log in to WordPress and have the login page just refresh with no errors?

    No, I don’t mean that Multisite Login Loop.

    After upgrading a bajillion people to WordPress 4.0 on DreamHost, I noticed something a little weird. People couldn’t login and they didn’t get an error. They would put in their ID and password and the screen just refreshed. So I took a look and decided to start with the obvious tests.

    Assuming that the username and password were correct, I checked what happened with a fake account and password. I put in ‘admin’ with a password of ‘areyouduckingme?’ (which no one but me would use) and expected to see a nice login error like this:

    WordPress failed login  - invalid username

    I did not. Right away I knew what was wrong. There was a miss-match with the home and site URLs!

    At DreamHost, we allow you to pick if you want to force www or non-www or not at all for your domains, and I always go to check what the customer did there, just to see. If they picked ‘neither,’ then I’ll usually flip it to non-www because I hate www in your domain and I’m fixing things. Of course, if they have set it to www or no-www, I make a note and honor that.

    Then I go check the home and site URL and make sure they’re both the same in so far as the domain does. If one is www.domain.com and the other is just domain.com, and 50% of the time, it was this all along. The other 50% is that WordPress thinks it should have www and the domain settings think it should not. The point here is that everything needs to match up nicely when it comes to your domains.

    It’s also a good idea to check the .htaccess to see if they’re forcing it one way or the other in there (I do).

    And you’re done. Refresh the page, see if you can login. Should be magic.

    Of course the question is then why did this happen, and the answer is that WordPress is trying to make it harder for people to break into your site. Part of these means making sure that cookies match domains properly, and when you have an inconsistency like www.domain.com and domain.com, the cookie is invalid and WordPress doesn’t know where to go. It wants to go to one but gets tossed to the other.

  • Self-Update Your Plugins

    Self-Update Your Plugins

    When your plugin is hosted on WordPress.org, this isn’t a problem at all. But if you’re selling your own work, or hosting it on a non WPORG resource, there are other concerns. You see, if you host a plugin on WordPress.org, your plugin can’t have it’s own updater script. You have to use the default .org updater. This is just fine, except when you have an add on that you want to be pay-only. Then what?

    Take a look at Easy Digital Downloads. You can get the main plugin from WordPress.org, and if you buy add ons from their site, they get magical updates too! How did they do that? They put an updater script in the main plugin which is then called by the paid extensions. You can even use their Software Licensing add ons to run your own updates on your server! If you want to sell on their site, they’ll help you take care of that too.

    Todd Lahman also has an WooCommerce API manager, so if you’re using WooThemes, you’ve got that covered too.

    Success on a mountain top

    Speaking of self hosting, if you’re hosting your own code on Github, then you want to use Andy’s Github Updater. While it’s not allowed on .org (sorry Andy), this will let you push updates from your GitHub or Bitbucket hosted WordPress plugins and themes.

    My buddy Norcross has his own free updater for you as well.

    You can also look at services like Auto Hosted or WP Updates, both of which promise to make it even easier and faster for you.

    Jeremy Clarke has a automatic theme/plugin updater as well if you still want to be self hosted.

    If you’re using ThemeForest, there’s the Envato WordPress Toolkit, which your users (not you) will need to install on their sites to get updates. I don’t know if there’s a way to include an updater in your packaged theme or plugin, but that toolkit needs to be all over the place for users. That it’s not brings all the issues you see with their products being out of date.

    There are hundreds of other ways around this. And really, there’s no excuse to not keep your plugins and themes up to date, no matter where they live. Keep those users updated and make it easy for them to do it! What resources do you use when self-hosting a plugin or theme, to keep it on the up and up, and keep everyone updates?

  • Mapped Domains And Google Search

    Mapped Domains And Google Search

    The other day I was surprised to learn that Google still looks for tech.ipstenu.org

    Kind of.

    If you go search for it, Google still believes that URL is a real thing: https://www.google.nl/search?q=site:tech.ipstenu.org

    Some of those URLs were made long after I mapped the domain, by the way. And yes, of course I have a 301 redirect for the subdomain.

    <If "%{HTTP_HOST} == 'code.ipstenu.org' || %{HTTP_HOST} == 'tech.ipstenu.org' ">
        RedirectMatch 301 (.*) https://halfelf.org$1
    </If>
    

    What’s going on here? Strictly speaking, Google’s right and stupid. The URLs are correct, but Google should be honoring the 301 redirect. Because it’s not, you have to tell it not to trawl your subdomains and use a robots.txt file, just for your mapped subdomains.

    First we’ll need to make a special robots.txt file, like robots-mapped.txt, and put the following in it:

    User-agent: *
    Disallow: /
    
    User-agent: Googlebot
    Noindex: /
    

    This tells Google to sod off. Then you need to specify when to use this special file, and that brings us to the lands of options. Since .htaccess is a top-down file, that is it reads from the top of the file down, you can get away with this:

    RewriteCond %{HTTP_HOST} = (code|tech).ipstenu.org
    RewriteRule ^robots\.txt$ /robots-mapped.txt [L]
    

    Just have that above any redirect rules for other things. But what if, like me, you’ve got Apache 2.4?

    <If "%{HTTP_HOST} == 'code.ipstenu.org' || %{HTTP_HOST} == 'tech.ipstenu.org' ">
        RedirectMatch 301 ^/robots\.txt /robots-mapped.txt
        RedirectMatch 301 (.*) https://halfelf.org$1
    </If>
    

    Of course, that sends tech.ipstenu.org/robots.txt to https://halfelf.org/robots-mapped.txt which is scary but still works, so don’t panic.

    Another way to do it would be to have a massive rewrite for all my subomains:

    # All Mapped
    <If "%{HTTP_HOST} == 'code.ipstenu.org' || %{HTTP_HOST} == 'tech.ipstenu.org' || %{HTTP_HOST} == 'photos.ipstenu.org' ">
        RedirectMatch 301 ^/robots\.txt /robots-mapped.txt
    </If>
    

    I will note, it should be possible to have (code|tech).example.com work in there, instead of all those OR statements, but I’ve yet to sort that out (corrections welcome in the comments!).

    The last step is to fight with Google Webmaster Tools. Add your subdomains and you should get this on the robots.txt checker:

    Example of robots.txt for tech.ipstenu.org in Google Webmaster

    If you don’t, don’t panic. Go to the Fetch as Google page and tell it to fetch robots.txt. That will force it to recache. Once you have it right, ask Google to remove the URL from their index, and in a few days it’ll sort out.

    It’s very annoying and I don’t know why the 301 isn’t honored there, but oh well. At least I can make it work.