Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: wordpress

  • WordPress Login Protection with ModSecurity

    WordPress Login Protection with ModSecurity

    No ModSec? Check out WordPress Login Protection With .htaccess

    LockIf you’re on Liquid Web servers, this was already done for you. If you’re not, you should still be able to use this code on your own ModSecurity instance. Since this is a way better method to block people than via a plugin, in my opinion, I thought it would be a good idea to share it here. With this rule, you won’t have quite as many http requests.

    WordPress is a popular publishing platform which is known for its robust features, numerous templates, and large support community. Unfortunately, due to such popularity, WordPress is also constantly subject to attempts at exploiting vulnerabilities. Ensuring WordPress and any associated plugins are installed with the most current versions is an important means of securing your site. However, ModSecurity provides a significant amount of further security by providing an application firewall.

    ModSecurity (also known as “modsec”) has proven itself useful in a variety of situations, and again this is true in assisting with WordPress brute force attempts resulting in a Denial of Service (DoS) attack. While a number of WordPress plugins exist to prevent such attacks, custom modsec rules can prevent such attacks for all WordPress installations on a server. Modsec immediately filters incoming HTTP requests, which assists against taxing server resources.

    These rules will block access for the offending IP address for 5 minutes upon 10 failed login attempts over a 3 minute duration. These rules have been automatically updated in the custom rules for Liquid Web’s ServerSecure service. For customers without ServerSecure, these rules can be added to their custom modsec rules. To accomplish this, edit your custom modsec user rules and append the file with the rules provided below. For CPanel servers, this file is likely located at /usr/local/apache/conf/

    SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},initcol:user=%{REMOTE_ADDR},id:5000134
    <Locationmatch "/wp-login.php">
        # Setup brute force detection.
    
        # React if block flag has been set.
        SecRule user:bf_block "@gt 0" "deny,status:401,log,id:5000135,msg:'ip address blocked for 5 minutes, more than 10 login attempts in 3 minutes.'"
    
        # Setup Tracking.  On a successful login, a 302 redirect is performed, a 200 indicates login failed.
        SecRule RESPONSE_STATUS "^302" "phase:5,t:none,nolog,pass,setvar:ip.bf_counter=0,id:5000136"
        SecRule RESPONSE_STATUS "^200" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:5000137"
        SecRule ip:bf_counter "@gt 10" "t:none,setvar:user.bf_block=1,expirevar:user.bf_block=300,setvar:ip.bf_counter=0"
    </locationmatch>
    

    Source: Liquidweb and Frameloss and MNX Solutions

    Logically, someone can extend this code to any file, like bb-login.php or Special:UserLogin, depending on where they’re being hacked.

    ETA: Rarst asked if I’d have to use wildcards with Locationmatch since WP is often in a subfolder. I read the Apache doc on locationmatch and it says that it’s using regex, so it should just look for ‘/wp-login.php’ in the URL. If I wanted to only look for example.com/wp-login.php then I’d use ^wp-login.php instead. If I got that wrong, please let me know!

  • Customizing Author’s Comments on Genesis

    Customizing Author’s Comments on Genesis

    commentsI like Genesis, but I wanted to make some tweaks to how comments looked.

    1) Bigger Avatar Size
    2) ‘Mark’ post authors and site admins

    This was pretty easy, since they have a filter in for comments, so all I had to do what tell it to replace their avatar size with mine, and then to use my callback. It’s in my callback that I did an extra check. If the commenter is an admin, they’re labled ‘Site Admin’ and if they’re the post author, it’s ‘Post Author.’

    The end result looks like this (I’m commenting on a CSI episode where someone’s hiding in the walls):

    Example Comment

    The only hard part of the code was finding I can’t filter the comment callback, but I have to totally replace it with my own. Bummer, but not insurmountable. StudioPress has a nice document on comment filters which explained how I could override settings like avatar size and callback, which lead me to my next step, the filter:

    // Customize Comments for avatar size and MY callback
    add_filter('genesis_comment_list_args', 'mysite_comment_list_args');
        function mysite_comment_list_args($args) {
            $args['avatar_size'] = '90';
            $args['callback'] = 'mysite_comment_callback';
            return $args;
    }
    

    Once I have the filter, I have to create the mysite_comment_callback. This is something I basically copied from the source of my theme, taking the whole function for genesis_comment_callback and changing what I wanted.

    /** replace comment callback with my own **/
    function mysite_comment_callback( $comment, $args, $depth ) {
    
    	$GLOBALS['comment'] = $comment; 
    	global $post; 
    	?>
    
    	<li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>">
    
    		<?php do_action( 'genesis_before_comment' ); ?>
    
    		<div class="comment-header">
    			<div class="comment-author vcard">
    				<?php echo get_avatar( $comment, $size = $args&#91;'avatar_size'&#93; ); ?>
    				<?php echo ( user_can( $comment->user_id, 'administrator' ) ) ? '<span class="mysite-title">Site Admin</span>' : (
    						( $comment->user_id === $post->post_author ) ? '<span class="mysite-title">Post author</span>' : '' ) ; ?>
    				
    				<?php printf( '<cite><span class="fn">%1$s</span></cite> <span class="says">%2$s:</span>',
    						get_comment_author_link(), 
    						apply_filters( 'comment_author_says_text', __( 'says', 'genesis' ) ) ); ?>
    		 	</div><!-- end .comment-author -->
    
    			<div class="comment-meta commentmetadata">
    				<a href="<?php echo esc_url( get_comment_link( $comment->comment_ID ) ); ?>"><?php printf( __( '%1$s at %2$s', 'genesis' ), get_comment_date(), get_comment_time() ); ?></a>
    				<?php edit_comment_link( __( '(Edit)', 'genesis' ), '' ); ?>
    			</div><!-- end .comment-meta -->
    		</div>
    
    		<div class="comment-content">
    			<?php if ( $comment->comment_approved == '0' ) : ?>
    				<p class="alert"><?php echo apply_filters( 'genesis_comment_awaiting_moderation', __( 'Your comment is awaiting moderation.', 'genesis' ) ); ?></p>
    			<?php endif; ?>
    
    			<?php comment_text(); ?>
    		</div><!-- end .comment-content -->
    
    		<div class="reply">
    			<?php comment_reply_link( array_merge( $args, array( 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
    		</div>
    
    		<?php do_action( 'genesis_after_comment' );
    
    	/** No ending </li> tag because of comment threading */
    
    }
    

    Finally it was a simple CSS to make it look snazzy.

    .bypostauthor span.mysite-title {
    	padding: 2px 5px;
    	padding: 0.15rem 0.4rem;
    	font-size: 11px;
    	font-size: 0.785714286rem;
    	line-height: 1;
    	font-weight: normal;
    	color: #7c7c7c;
    	background-color: #FFFFCC;
    	background-repeat: repeat-x;
    	background-image: -moz-linear-gradient(top, #ffc, #fc3);
    	background-image: -ms-linear-gradient(top, #ffc, #fc3);
    	background-image: -webkit-linear-gradient(top, #ffc, #fc3);
    	background-image: -o-linear-gradient(top, #ffc, #fc3);
    	background-image: linear-gradient(top, #ffc, #fc3);
    	border: 1px solid #d2d2d2;
    	border-radius: 3px;
    	box-shadow: 0 1px 2px rgba(64, 64, 64, 0.1);
    	float: right;
    }
    

    I should point out that I have no experience with editing comments.

  • Your Photos, Your Way

    Your Photos, Your Way

    PressGramI’m funding PressGram on Kickstarter and you should too.

    I like Open Source. Surprise!

    I don’t mind paying for products (as witnessed by the fact that I have paid for this theme, and even the old DevPress and ThemeHybrid ones I don’t use anymore. I have a slew of plugins I paid for, and all in all, I think every dime was money well spent. Paying for open source makes sense.

    So there’s this guy I know from the Internet, John Saddington, who likes taking photos, and he likes social media, but he wonders, like I often do, what happens when those outlets go away? Where are all my photos if TwitPic or YFrog vanishes? Or if Facebook deletes my account?

    They’re gone.

    John loves WordPress. So do I. John loves photos. Well. I fiddle around with them, but the point is he wants to built something that is way more than ‘just’ a plugin. He wants to make a free iPhone app… look, this is what he wants:

    The premise is simple: I wanted to post filtered photos from my iPhone 5 but without worrying about any privacy or licensing issues (and we’re not interested in asking you to upload photo IDs). In other words, I wanted complete and total creative control of my images and content (as well as the pageviews).

    photo-littleAnd this will post to WordPress, which is so simple, we have a one-click installer at DreamHost for you to use to make it. Imagine that. You could have a photoblog with a couple clicks.

    When I read that John was making PressGram, I had to poke at it, even though it’s not Open Source. It’s an Apple iOS app. I’m not shocked that it’s not open source, and after consideration, I don’t mind. It doesn’t have to be. As long as the plugin is open source (and frankly, given WordPress’s API, I can easily envision how it would be without stepping on closed source apps), it’s good to go.

    John knows his shit. He shares the same concerns and doubts about social media as I do, he rails on Facebook for the same things I do. He’s a guy whose ethics I can get behind. And he’s a guy whose code I can get behind. Remember I review plugins. I’ve seen his code. It’s good.

    So yeah, I’m supporting him so you can have a free app. Go figure. And as with most of the things I kickstart, I get no swag back (I think I get a kudos and a link somewhere), because I like to give for the spirit of giving most of the time. I’ll be getting the Veronica Mars DVD, but I’d be buying that anyway.

    Give in. You know you want this. Pay $5 instead of risking your content belonging to someone else.

  • Genericon’d Menus

    Genericon’d Menus

    Screen Shot 2013-03-31 at  31 Mar - 1.35.26 AMQuick and dirty, I wanted a menu to have Genericons. Menus are crazy extendible and I use them in sidebars all the time to make a list of links formatted in a nice way. So why not a Genericon? After all, I know menus are really glorified Custom Post Types.

    Don’t they look pretty? It’s stupid easy.

    Screen Shot 2013-03-31 at  31 Mar - 1.38.34 AM

    URL: http://facebook.com/you
    Navigation Label:
    Title Attribute: Facebook
    CSS Classes (optional): social-buttons

    Then all I had to do is fiddle with CSS. li.social-buttons .genericons is applicable here, and that’s why I gave it the CSS class. If I wanted to have it be a genericon plus text, then the Navigation Label would have been Facebook instead. If you don’t want the genericon to be part of the link, make the label just the link name, and add genericon genericon-facebook to the CSS classes.

  • Genericons: Plugin’d

    Genericons: Plugin’d

    banner-772x250 The thing about all this is that I really like Font Awesome. The licensing drives me to drink. The WordPress Repository has an extra rule, saying everything there has to be GPLV2 or later, for reasons that aren’t the point. What is the point is that the moment Genericons came out, I knew that it should be a plugin, because a totally GPL-compatible version of a font like this was what people wanted.

    Since I also knew Rachel Baker had made a killer Font Awesome Plugin (and yes, that’s the one I use), I quickly stripmined its code and made Genericon’d.(At this point it’s pretty much a re-write, but I always credit where I started!)

    ZabooThe name is not Genericons because it’s not official, and they may want that name later. With that in mind, I thought “Well I totally Genericon’d them all!” because sometimes I talk like Zaboo from “The Guild.” I think of him as the Patron Avatar of this Plugin (though he’d probably ask why there wasn’t a Genericon for his staff, or Codex’s).

    So what are these ‘font icons’ things anyway and how do they work?

    Normally if you want to insert a Twitter image, let’s say, you would have to go find the image, download it, edit it to the right size, upload, embed. On the other hand, with a font you can do this: That will look like this: Isn’t that cool? All you have to do is include the font and the CSS in your site and you’re good to go. All those files are smaller than most images, load faster, and best of all, they scale better.

    [genericon icon=twitter size=4x] Same font, bigger size. Isn’t that cool? Since they’re pure CSS, you can do whatever you want, from changing colors and size to inserting into menus, like I did on another site. When you add in their relatively small file size and scalability, you gain and added level of awesome because your little icons always look amazing on retina displays too! After all, they’re just fonts.

    The alternative to something like this would be to use sprites, which is actually what WordPress uses today on your dashboard, and they look like this:
    WordPress's Menu

    If you go look at your WordPress dashboard, you’ll notice that hovering over these images makes them change between the dull grey and the cool colorized version. In order to do that, you have two images. Not so with Genericons! .genericon-twitter:hover {background-color:pink;color:purple;} would do the same thing (in pretty garish colors…). Just as an example of how it works, here’s a link with a Genericon in it: [genericon icon=twitter] @ipstenu. It’s actually kind of nice how it automatically adapts to the CSS I have in place for hovering over links.

    Basically the reasons to use icon fonts instead of images are that you can style them with CSS, they look good on all displays at any resolution, they easily adapt to fit your site when you change themes and colors, there’s only one HTTP call for the icons, and they’re open source.

    Here are some features in Genericon’d (as of version 1.2) that I think are kinda awesome:

    On the fly color changing.

    You can make a Twitter Blue icon: [genericon icon=twitter color=#4099FF] makes [genericon icon=twitter color=#4099FF]

    On the fly resize.

    You can make a Facebook icon bigger: [genericon icon=facebook size=4x] makes [genericon icon=facebook size=4x]

    And it all pretty much works the way I want it to. I did tweak the CSS a little to use em instead of px, which isn’t perfect. Genericons works best when your font is a derivative of 16, and for some reason, people still default to 12px. Protip: Ask someone with imperfect vision to look at your site. If they squint, your font is too small.

    Genericons, and any font-icon add-on, aren’t perfect for everyone or every site, but they’re here if you need ’em.

  • IE 8 and SVG Smilies

    IE 8 and SVG Smilies

    I don’t like the default smilies in WP. There, I said it. They’re old and busted, so I use the smilies_src to replace them with nicer ones. Recently it came to my attention how old and busted my cute PNGs looked on my iPad and any retina capable computer, so I fiddled around and decided SVG graphics were the way to go. They scale well, and they work on all modern browsers, yay!

    Oh, wait, IE 8 is not a modern browser and it’s pretty common out there… In fact my old job still uses it on a lot of PCs. And so does at least one user on this site (actually 5, and one more uses IE 6, for crying out loud!) so I came up with this:

    // Move Smilies
    add_filter('smilies_src','my_smilies_src', 1, 10);
    function my_smilies_src($img_src, $img, $siteurl) {
        $img = rtrim($img, "gif"); // Remove GIF
    
        if ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE 8' ) || strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE 7' ) ) {
            $type='png';
        }
        else {
            $type='svg';
        }
        return 'http://domain.com/images/smilies/'.$img.$type.'';
    }
    

    That said, I wish we had more modern smilies available for WP. Finding a set that look okay (like the ones I have here) that are also retina capable are not easy. I could use user agents to go the other way, checking if the visitor was on a ‘new’ iPad or iPhone and show them retina that way, but to the best of my knowledge, there’s no way (yet) to do it so that a retina MacBook also gets the nicer view. With that in mind, I went just with SVG, which scale naturally and meet all of my needs.

    By the way, thank Otto for the smilies filter. You can use it for normal filtering too:

    add_filter('smilies_src','ipstenu_smilies_src', 1, 10);
    function ipstenu_smilies_src($img_src, $img, $siteurl){
        $img = rtrim($img, "gif");
        return $siteurl.'/images/smilies/'.$img.'png';
    }
    

    That’s what I use here.