Getting the post ID from a WordPress content on an external site

In case you need to get the post/page/{$custom_type} ID from a WordPress content, from a remote site or no direct access to the database, here’s an easy and reliable way to do it.

When you make a request to a WordPress site for a “singular” content (that is, the detailed view of a single post, whatever type it is), you should receive a Link HTTP header that uses the database ID of the content, something like:

Link: <https://some-site.com/?p={$POST_ID}; rel=shortlink

From then on, you can extract the {$POST_ID} param from the URL using your favourite technique.

If you do have access to the database, you might want to check this post: How to Get Post and Page IDs in WordPress.

Copying theme mods to child theme using wp-cli

“Child themes” in WordPress allow for specific modifications of the look and functionality of those inherited from their “parent” theme.

Unfortunately, when you switch to the child theme, the customizations configured on the parent theme are lost, because they’re saved with the active theme slug.

So, here’s a quick and simple way to “inherit” those settings by copying those options to the child theme.

Using wp-cli:

wp option get theme_mods_PARENT-THEME --format=json | wp option add theme_mods_CHILD-THEME --format=json

… where PARENT-THEME and CHILD-THEME are the theme slugs for each theme.

It’s time for Debian

Jonathan Carter, Debian Project Leader, writes about the end of CentOS as we know it — their recent decission to base newer releases on CentOS Stream instead of a more stable branch now makes it a less-than-ideal choice for servers.

Earlier this year, I switched away from Ubuntu after close to 10 years of using it as my primary OS, mainly because of their push of Snaps on the newest LTS.

Debian it’s not only stable, but also really easy to install and configure as a desktop or server OS to the point of almost being boring (if it wouldn’t have as many desktop enviroments to choose!)… which it’s actually just perfect for getting your work done!

Javascript para programadores impacientes

JavaScript for impatient programmers — a pesar del título, explica con harto detalle incluso los aspectos más básicos del lenguaje.

Está actualizado hasta ES 2019 por lo que es especialmente útil para refrescar cosas de sintaxis y nuevas funcionalidades que se han ido incorporando al lenguaje.

El libro está prácticamente entero, sólo hay un par de capítulos bonus que son de pago.

Registering custom URLs with custom templates in WordPress (without using page templates)

It’s fairly common to find yourself on a situation where you want to use a specific URL to show a custom content (perhaps something an archive page with two different custom post types), and think: “well, that’s easy. I’ll just create a page to register the URL and a custom page template where I’ll query the contents I need”.

Well, it turns out that there’s a better way of doing this using rewrites and hooking into the right WordPress’ filters — which, by the way, it’s the recommended way to do it by the WordPress VIP team.

Let’s check this technique with an example.

Continue reading “Registering custom URLs with custom templates in WordPress (without using page templates)”

Mitigating CVE-2018-6389 WordPress DoS attack with lighttpd

Early in 2018, Barak Tawily published a possible DoS attack for WordPress, that basically works by requesting all possible scripts on the /wp-admin/load-scripts.php, a script that fetches and concatenates javascript files — there’s also a load-styles.php file that does the same for styles.

His vulnerability report was rejected by the WordPress team, on the account that this type of attack should be mitigated at the server or network level… so how do you do that using lighttpd?

Actually it’s pretty easy using mod_evasive, a “very simplistic module to limit connections per IP”, as advertised on the lighttpd docs.

First, you must make sure that mod_evasive it’s enabled on the server.modules block:

server.modules = (
  "mod_access",
  "mod_alias",
  "mod_compress",
  "mod_redirect",
  "mod_rewrite",
  "mod_accesslog",
  "mod_evasive"
)

Then, on the main lighttpd config file you can add the following:

$HTTP["url"] =~ "/wp-admin/load-(styles|scripts).php(.*)" {
  evasive.max-conns-per-ip = 8
}

This will effectively limit the amount of allowed connections to 8 by IP. Of course, you can adjust that value to whatever you need; 8 connections by IP it’s plenty enough for a “normal” editor use.

You can test if it’s working by “attacking” your server with siege or ab or your favourite benchmarking/load testing tool and checking your lighttpd error log, where this should appear:

2018-03-22 21:05:53: (mod_evasive.c.183) 192.168.33.1 turned away. Too many connections.

After testing, you might also want to add this to the lighttpd config:

evasive.silent = "enabled"

… that way, blocked IPs won’t be logged on the errors.log (which, on its own could trigger a DoS by repeatedly writing to the log file)

If you’re using nginx with HTTP/2, there’s an even better way.

Filtering active menu element class on WordPress

When using a navigation menu on WordPress, you’ve probably seen the various HTML classes that are added on active elements, such as current-menu-item, current-menu-parent, current-menu-ancestor

While that kind of classes are fine if you must fully reflect the navigation hierarchy on the menu element, there are some times that you just need a more simple approach, such as just knowing when a certain menu element must look like the active item —for instance, when using Bootstrap.

For these kind of situations, you can use a simple filter to add such a class; something like:

<?php

add_filter('nav_menu_css_class', function ($classes, $item, $args, $depth) {
    // filter by some condition... for instance, only on the "main" menu
    if ( $args->theme_location !== 'main' ) {
        return $classes;
    }
    // all the different "active" classes added by WordPress
    $active = [
        'current-menu-item', 
        'current-menu-parent', 
        'current-menu-ancestor', 
        'current_page_item'
    ];
    // if anything matches, add the "active" class
    if ( array_intersect( $active, $classes ) ) {
        $classes[] = 'active';
    }
    return $classes;
}, 10, 4);

Let’s talk about usernames

Usernames are a much, much harder problem than what you might think at first glance… even if you can get away with a really simple and naive implementation on a prototype, a large, global and secure service must consider lots of not-so-obvious details and possible attack vectors.

Let’s talk about usernames deals with the problem with uniqueness, homograph attacks, confusables and other security concerns that you might need to consider.

In Praise of Theory in Design Research: How Levi-Strauss Redefined Workflow

It is now well known that people use technology in unexpected ways (at least, in ways that software engineering and product teams had not intended) […] Our original charge was to find ways to improve and optimize users’ browser workflows following software and design-oriented assumptions. Instead, we saw that users were doing just fine with the tools they were already using.

In Praise of Theory in Design Research: How Levi-Strauss Redefined Workflow