Category: WordPress Maintenance

  • WordPress Updates with WP-CLI

    Most people do plugin, theme and WordPress core updates via the WordPress Update page.

    But if you are managing multiple sites, you might find it’s easier for you if you use the command line.

    Once you are logged into the site via SSH (a secure encrypted text-based terminal for accessing your web hosting account’s files and many Linux commands), then many WordPress command line functions are available to you.

    One requirement: you have to be using a website hosting company that gives you access to the command line, via SSH. I recommend SiteGround for hosting almost all sites.

    WP-CLI works in your WordPress folder (for most people, that’s the public_html folder, aka the www folder). It also works in WordPress sub-folders, e.g. ~/www/wp-content/

    cd ~/www

    Plugin and Themes Updates

    Get a list of plugins your site uses:

    wp plugin list

    Plugins that need updates:

    wp plugin list --update=available

    Update all plugins:

    wp plugin update --all 

    Update all plugins excluding WooCommerce (or any other plugin that itself has plugins, and therefore you should update all the plugins-plugins first and then update the main plugin). Substitute the name of the plugin, from the “wp plugin list” command:

    wp plugin update --all --exclude=woocommerce

    Updating Your Themes

    wp theme list
    wp theme update --all

    Updating WordPress Core from SSH

    wp core update

    What Other WP-CLI Commands Are Available?

    wp help

    That shows you a list of commands, and a brief description. You can then get help on any of those commands

    wp help core

    Many of the WP-CLI commands have several levels, and several parameters. For example:

    wp user create bob bob@example.com --role=author

    So use “wp help user create” to see what the available parameters and options are for the “wp user create” command.

    If you simply type the command without the required parameters, you will get a brief usage prompt.

    wp user create
    usage: wp user create [--role=] [--user_pass=] [--user_registered=] [--display_name=] [--user_nicename=] [--user_url=] [--nickname=] [--first_name=] [--last_name=] [--description=] [--rich_editing=] [--send-email] [--porcelain]

    Some plugins have their own WP-CLI access, check the plugin’s documentation or the “wp help” list.

    The help documents are displayed using “less” (the Linux command for paging through a text document, at least on some flavors of Linux; your flavor of Linux might use “more”), PgUp and PgDn work, as does searching for text with the “/” key, or getting help on using less by pressing the “h” key. Exit by pressing the “q” key.

  • What if your hacked site has custom code?

    Normally when a potential client brings you a site that is hacked, you do everything you can to get it cleaned thoroughly. That would include updating all files for WordPress and plugins and your theme, to the latest version. New versions of the software often contain fixes for recently discovered security issues.

    But what do you do if that client says there is custom code for WordPress or plugins? Code that is needed for something in the site, and updating WordPress and the plugins, would remove that. They have concerns that updating WordPress, the plugins, and the theme, would break something necessary for the site.

    The WordPress blog of a friend of mine has been hacked. It’s his fault because the core and a lot of plugins are out of date but he customized a lot of code and now he doesn’t want to update and manage (pay for…) the maintenance on the customization. I’ve reverted back the posts into pages, restored original revisions, changed all the password. I’ve installed WP security plugin. Now the site is apparently back to the normal condition but I’m not allowed to update the core nor the plugins so it’s not a safe condition. What other things can I do to prevent this kind of attack again?

    What Exactly Are the Changes For?

    Site owners have little ability to predict whether the change they want, that might be a big change visually, is going to take a slight tweak or a major change in the code. Developers have that expertise, not people whose businesses are other than website development.

    Most of the time, the changes made to WordPress or plugins are actually small changes, from a developer’s point of view. No matter how the change looks on screen, in code it is usually a very little change. Developers know that big changes would be better done by making a plugin specifically for this site’s needs. Developers who have the skills to make large changes, to a WordPress site, know how to make a plugin, and know the issues with making several changes to some other plugin or WordPress core.

    Good developers know WordPress well enough to know what small changes will produce the results; good non-WordPress developers might be able to make a change but in a way that is incompatible with WordPress updates; bad developers make changes not knowing what WordPress updates will do to their changes.

    Said another way, only amateurs make changes to someone plugins written by someone else, to be updated by someone else. (That of course is different than people submitting fixes or improvements to the author of the plugin, hoping they will be incorporated into future releases of the plugin.)

    The changes are likely to be inserting code for some external script; or changing the HTML of something. Small, targeted, specific changes. There are always better places to make these changes than in the WordPress core files.

    These probably seem “major” to the site owner, bringing some obvious visible changes to the site. But these would not be major changes for an experienced developer. These changes very likely can be brought into a simple plugin, or into a child theme’s CSS. Or maybe WordPress now has features that handle the information directly, no modifications needed. Examples would be incorporating YouTube videos, or Google Analytics code.

    Find out what the customized code is, and you might discover that there are simple ways of accomplishing the same thing while keeping your plugins and WordPress itself updated.

    While you are identifying the changes made to your site’s code, also have a programmer assess whether there are security risks in that code. Any form handling must be coded to prevent SQL injection. Any file uploads must be carefully screened, to not allow uploading malware; all files installed on your hosting account are given full permission to execute — if hackers install one file they can take over everything on your site. (Upload only into the default uploads folder, and have security blocking execution of all files in that folder, except image files and audio files, which still should be validated with your audio player.)

    Should You Update?

    What is the cost to their business of losing the custom code?

    What is the cost to their business of the site being hacked again, perhaps very soon? How is their reputation affected? How is their “reputation” with the search engines affected?

    If the changes were for important business information being displayed, move the changes into a properly written plugin.

    The costs of getting hacked almost certainly outweigh the costs of re-doing the changes the right way. Update early, at least weekly.

    What order do you perform updates in? Update your plugins, then your theme, then WordPress. There could be changes in the plugins to make them compatible with upcoming changes in WordPress, so update WordPress after the other updates. And, update WordPress now.

    What if there have not been any updates in a very long time? Probably best to update a few minor version updates at a time. That way, any changes to the database are more likely to be done correctly. (Plugins, themes, core, in that order, a few months at a time.)

    Do They Really Need to Re-Think Their Site?

    Have they clearly identified the specific people they want to talk to? So they can write as if to a single person, addressing exactly what that person is looking for?

    Do they know what problems that specific person is hungry to solve, that they can take care of?

    The old site is very likely not focused on the right person, or even worse is talking to “everyone” (which winds up meaning “no one”). The old site likely knows nothing about what search engines are looking for, which is current relevant content for exactly what their users are looking for.

    The old site likely doesn’t work well with mobile devices, which might be the biggest group of visitors that might become customers or clients.

    Is it time to redo the site, to fit what they want to accomplish with their potential clients via their website?

    What questions should the site answer for people? What is important to their visitors, that they really want to see on the site? What actions do they want visitors to the site to take? How can the site best have people interacting with them?

    Even if only briefly, find out what they want with their site, before updating it.

    Maybe the way to stop the malware is to quarantine the entire site, and copy/paste the text into the re-designed site.

    Ongoing WordPress Maintenance

    I do WordPress maintenance for small businesses. I know how to keep sites working well. Maybe it will make sense for you to have me take care of your site for you, so you focus on what to say to your visitors.

    Don’t get hacked, especially not again. I’ll keep your site safe.

  • Security — Block Executing Files Uploaded in wp-content/

    One of the most common hacker techniques on WordPress sites is to find a plugin that has a vulnerability, and use that plugin to upload an initial malware file onto your site. The hackers would then access the malware file directly (bypassing WordPress) to install any malware they want, and/or access your database. Hackers know the most common place plugins would put files is in your WordPress wp-content/uploads/ folder. You must Block executing files in your wp-content folder.

    There are folders such as wp-content/plugins/ and wp-content/themes/ where you should allow files to execute (or your plugins and theme won’t work). You could even get more specific, and enable just the folders that each plugin specifically uses. However, that is more maintenance work for you; let a top security plugin (WordFence) take care of that for you.

    You Must Protect Your Uploads Folder

    This is a serious security issue. One reason you must do plugin updates frequently, is plugin authors (well, the good ones, at least) will patch security issues as soon as anyone informs them. That’s because there are security people who check the hacker’s bulletin boards for issues the hackers are bragging about, and alert the plugin authors.

    Here is an example of the kind of hacker junk you would see if your security software were capturing the information:

    errorstatuserrortriggerrequriquerystringuseragentcookiesallowheaderspostvariables
    403badRequestString:wpcontent/wp-content/plugins/work-the-flow-file-upload/public/assets/jQuery-File-Upload-9.5.0/server/php/index.php Mozilla/5.0 (Windows NT 6.1; rv:34.0) Gecko/20100101 Firefox/34.0 Accept: */* Accept-Encoding: gzip, deflate–31aa900beb174efa942c7958119e7885
    Content-Disposition:_form-data;_name–>”action”upload
    –31aa900beb174efa942c7958119e7885
    Content-Disposition: form-data; name=”files”; filename=”wp-classes.php”
    Content-Type: text/plain–31aa900beb174efa942c7958119e7885–
    403badRequestString:wpcontent/wp-content/plugins/work-the-flow-file-upload/public/assets/jQuery-File-Upload-9.5.0/server/php/index.php Mozilla/5.0 (Windows NT 6.1; rv:34.0) Gecko/20100101 Firefox/34.0 Accept: */* Accept-Encoding: gzip, deflate–f2ee98a757e94b9897a2c9b1a9ffa74f
    Content-Disposition:_form-data;_name–>”action”upload
    –f2ee98a757e94b9897a2c9b1a9ffa74f
    Content-Disposition: form-data; name=”files”; filename=”wp-classes.php”
    Content-Type: text/plain
    –f2ee98a757e94b9897a2c9b1a9ffa74f–

    What Do These Columns Mean?

    ErrorStatus 403 means “Forbidden”, the server or hosting account security rules are blocking this.

    ErrorStatus 404 means “File Not Found”, but there is nothing forbidding them accessing the file if it did exist.

    (If the requested file did exist, the hackers found a file that, at least in some version of the file, they think had a vulnerability; you wouldn’t see an error. Your site access log would have the file name with an ErrorStatus 200 “OK”, or 304 “Not Modified”.)

    ErrorTrigger is my security system letting me know what caused this to be blocked, in this case the use of “wp-content” in the Request String.

    Requri is the Request String, in this case beginning with “/wp-content/plugins/work-the-flow-file-upload”. So we guess that some version of the “Work The Flow File Upload” plugin had a vulnerability (because somebody, probably a hacker, was looking for it). We don’t know that the current version of the plugin is flawed, we know that hackers are interested in some version of the plugin.

    This plugin looks risky, in the description at https://wordpress.org/plugins/work-the-flow-file-upload/faq/ . However, know that all plugin authors can mess up and allow a hacker to gain access beyond the plugin author’s intentions.

    You want to specifically block hacker behavior, and only attempt to guess whether the plugin author is to be trusted while you decide whether to install a plugin.

    In this example, simply the attempt to access program files directly in wp-content/ is enough to conclude the request is by a hacker. Only images or music or video should ever be accessible directly, in wp-content/uploads or any sub-folders.

    Query String is, in these examples, not used. If you type a URL in, and it has a question mark in it, everything after the question mark is the query string. For the URL http://computerhelp.lc.lndo.site/wp-admin/post.php?post=abcde&action=edit the query string is “post=abcde&action=edit”.

    User Agent is used by all software that accesses web pages, letting the server know what capabilities or special formatting to use. Some hackers use web bots with unique names, “bragging” about who they are; these can be blocked by the user agent. In this case, it’s simply Firefox version 34. If there is the word “semalt” or “nutch” or “ImageSucker” in the User Agent, those are known baddies. You can find several lists of user agents, e.g. http://www.useragentstring.com

    Cookies aren’t set here. Hmm, if they were actually using WordPress, there would be several cookies set. So, this is another clue they are hackers.

    Allow Headers: These are meant to be used to let the server know what language the browser prefers, for example “I want to read the French version of the page if you have one, but if not I’ll take British English or any other version of English”. Similarly, the header is used to indicate if the browser can take compressed output. In this case, no foreign language preferences, and can use gzip or deflate for compression. Nothing to look at here, in this example, for security; this is useful for troubleshooting other types of problems.

    Post Variables: Every form you fill out on the Internet uses Post Variables (or rarely, the URL) to submit the data. In this case, the “Action” is “Upload” (the hacker is submitting a file for the server to upload), and the file name is “wp-classes.php”. Well, that looks like a legitimate file name, right? Wrong! This is being uploaded, which is a definite give-away, but if you didn’t catch the upload the hackers are hoping you won’t notice a file with a name that looks legitimate.

    How Do I Block Files Uploaded to wp-content/

    The easiest way is use a good security plugin such as WordFence (my preference) or iThemes Security (doesn’t include a Web Application Firewall in the free version, and sends useless emails to me, for example “file changes found”). Both will do far more than block uploading executable files and block executing files in wp-content. Definitely use either WordFence or iThemes Security

    If you want to modify your own .htaccess file? Don’t, it’s a lot more work! Okay, if you really want to, here’s what I use, including setting a server environment variable that my error page can read:

    SetEnvIf Request_URI (?i)^/wp-content/(.*)$  badRequestString=wpcontent
    SetEnvIf Request_URI (?i)^/wp-content/themes/(.*)\.(css|js|gif|jpg|jpeg|png|eot|svg|ttf|woff)$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/plugins/(.*)\.(css|js|gif|jpg|jpeg|png|eot|svg|ttf|woff)$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.flv$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.gif$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.jpg$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.jpeg$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.m4v$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.mp3$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.mpeg$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.mpg$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.png$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.pdf$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/uploads/(.*)\.txt$  !badRequestString
    SetEnvIf Request_URI (?i)^/wp-content/cache/supercache/(.*)$  !badRequestString
    Order Allow,Deny
    Allow from all
    Deny from env=badRequestString

    I make exceptions for style sheets and images and fonts in your theme folders and plugin folders; and for images, pdf files, text files, movies in your WordPress uploads folder (the WordPress Media Library folder). You also should allow cache files (I’m no longer using WP Super Cache, my hosting provider has better).

    Want Me to Check Your Security and Do Regular Maintenance?

    I do WordPress Ongoing Maintenance and Security for small business sites, making sure your site runs smoothly and is safe from most hackers. I can’t block the CIA (or Russian, Chinese, etc equivalent) from getting in, but I can thwart many hacking attempts at the WordPress and Plugin level. I have your site run quickly, and without errors. I can make sure your pages are showing up well in social media sites, including Facebook, Twitter, LinkedIn, Pinterest.