This Blog Is Not For Reading

A blog, just like any blog, only more so

  • Subscribe

  • Categories

  • RSS Bob Jonkman’s Microblog

    • Delete 27 August 2023
      Bob Jonkman deleted notice {{tag:gs.jonkman.ca,2023-08-27:noticeId=1114720:objectType=note}}.
    • New note by bobjonkman 3 August 2023
      From a few years ago... All gone now, and I promised $SPOUSE it would never come back. https://gs.jonkman.ca/attachment/221480
    • Favorite 3 August 2023
      bobjonkman favorited something by clacke: I tried for over four decades to grow an impressive personality, but it was a lot of effort and not much payoff, so now I'm just trying to grow an impressive beard instead.
    • bobjonkman repeated a notice by clacke 3 August 2023
      RT @clacke I tried for over four decades to grow an impressive personality, but it was a lot of effort and not much payoff, so now I'm just trying to grow an impressive beard instead.
    • bobjonkman repeated a notice by clacke 27 July 2023
      RT @clacke did you watch Oppenheimer, the film about the moral implications of the things we create, starring an actor who also played a Gotham City psychiatrist who went insaneordid you watch Barbie, the film about the moral implications of the things we create, starring an actress who also played a Gotham City psychiatrist who […]
    • Favorite 27 July 2023
      bobjonkman favorited something by clacke: did you watch Oppenheimer, the film about the moral implications of the things we create, starring an actor who also played a Gotham City psychiatrist who went insaneordid you watch Barbie, the film about the moral implications of the things we create, starring an actress who also played a Gotham […]
    • New comment by bobjonkman 29 June 2023
      @steve Wait, you or Dr. Cooley are at Perimeter? Giving any public lectures? If so, I'll hop on my bike to attend! @Perimeter
    • bobjonkman repeated a notice by steve 29 June 2023
      RT @steve From jodi on Mastodon: I’m looking forward to meeting students at TRISEP 2023 being held @Perimeter!
    • New note by bobjonkman 8 June 2023
      Several other authors of software that accesses the Twitter API have come to that conclusion as well. When #Twidere, my phone app to access Twitter stopped accessing Twitter back in January I pretty much abandoned Twitter. I still check Twitter with its WebUI, less than once a week, but I no longer post or engage […]
    • Favorite 8 June 2023
      bobjonkman favorited something by steve: I finally had a chance to figure out why my social bridging software was no longer able to talk to Twitter. Indeed, it's because under Twitter's new leadership, python-twitter has been deemed as violating something in their terms of service. It says I can submit a ticket, but they make […]

Archive for the 'code' Category

Recovering from a WordPress hack

Posted by Bob Jonkman on 29th October 2013

WordPress logo cleaved by axe

WordPress Hacked!

Last Friday I was finally getting around to upgrading the WordPress installations on the SOBAC server from v3.6 to v3.6.1. Surprise! WordPress v3.7 had just been released the night before!

WordPress upgrades are famous for their ease of installation. Surprise! After upgrading the first installation most of the plugins were missing, and the theme was broken. A quick look at a directory listing showed that the plugins and themes were still installed. A quick look with a text editor showed some peculiar PHP code at the top of every .php file in the plugins folders. Surprise! This WordPress installation had been hacked! Fortunately, of the five instances of WordPress on this server, only two appeared to be affected. This Blog Is Not For Reading was not one of them.

Each .php file started with something like this:

<?php $zend_framework="\x63\162\x65(…)\x6e"; 
@error_reporting(0); 
zend_framework("", "\x7d\7(…)

Injected, obfuscated PHP code at the top of every .php file, referencing the zend_framework

Searching the Internet for “wordpress plugin invalid header zend_framework” I found a reference that makes me think this may have been possible because of a flaw in an earlier version of the WordPress code that handles comments. Most likely one of the comment fields (user name, e-mail, web address or the comment text itself) wasn’t properly sanitized, and allowed some kind of code injection (probably PHP injection, not a MySQL injection; the contents of the databases appeared to be untouched).

From the backups of the server it appeared that the breach occurred in or before August — either just before the release of WordPress 3.6 on 1 August 2013 or just before the release of WordPress 3.6.1 on 11 September 2013. If I had not been slack in upgrading to WP v3.6.1 then this breach might have been identified much sooner.

The upgrade to WordPress identified the modified files because the injected code preceded (and corrupted) the WP headers, and so WP v3.7 disabled any affected plugins and themes.

The Fix Is In

I renamed the directory containing the WordPress code, installed a fresh copy of WP3.7, cleaned and copied the wp-config.php and .htaccess files, uploaded a small image to create the wp-content/uploads hierarchy, then copied the upload folder (which didn’t contain any .php files), and then re-installed and re-configured the themes and plugins directly from the WordPress site.

Aside from the additional PHP code, there didn’t appear to be any other damage to the system. So I used the original wp-config.php (but cleaned, and with the “Authentication Unique Keys and Salts” section refreshed), and the new installation just used the existing databases. If there’s any malcode in the databases then that could re-infect the system, so I’m keeping an eye on it.

I have no idea what the malcode was intended to do. It didn’t corrupt the databases or anything else, but it’s possible it was acting as a keylogger or phoning home some other way. If I feel inclined I might try to de-obfuscate the injected code, but right now I don’t really feel like doing forensics.

Someone suggested using AppArmor to make the WordPress directories read-only. I’m not sure that locking down the WP directory is a good idea. The big new feature in WordPress 3.7 is its automatic update feature. If the WordPress directories are locked down then future security updates won’t be applied automatically. If there is an exploit and WordPress issues a new release to fix it, then a locked-down site will experience a delay in upgrading until the SysAdmin notices and upgrades manually (which is what used to happen before v3.7, but it seems a bad idea to delay upgrades when that’s no longer necessary). Also, the plugin and themes directories would be locked down, and they still require fairly frequent manual upgrades.

I sent the users on the affected sites this message:

While doing upgrades on WordPress yesterday I saw that your blog had been hacked sometime during or before August. I’ve fixed it (re-installed the code, copied your media library, re-installed themes and plugins). I don’t think any damage was done beyond the insertion of malicious code in some of the WordPress files. I don’t know what the action of that code was intended to be, but you should change your WordPress password just in case the bad guys captured it. You can change your password on the “Users, Your Profile page” once you’ve logged in.

After spending some time on Saturday fixing the two hacked WordPress sites I’m a little paranoid, and making sure to implement updates quickly. But a little paranoia is good — it’ll ensure I won’t become complacent again.

–Bob.

WordPress Hacks by Rafael Poveda is used under a CC BY-NC-SACreative Commons — Attribution-NonCommercial-ShareAlike — CC BY-NC-SA license.

Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
Posted in code, How To, security, System Administration | Comments Off on Recovering from a WordPress hack

OpenDataDay Hackathon at Kwartzlab

Posted by Bob Jonkman on 27th February 2013

Open Data Waterloo Region

 

On International OpenDataDay four teams of hackers from OpenDataWR gathered at Kwartzlab to work on Food Premise Inspection Data, modelling new transit routes and route changes with GTFS data, improving the server for the Catchr transit app, a proof-of-concept pushbutton app for Android, and creating a Get Map button for OpenStreetMap in the Thunderbird Lightning add-in.


Hackers at Kwartzlab OpenDataDay Hackathon at Kwartzlab. Clockwise: Koo (back to camera), Ralph, Michael, Mike, Brett, Jonathan. Missing: Darcy, William, Katherine, Bob.

 

William and I worked on the Get Map button. Although we had hoped to create some working code, we got only as far as making a mock-up of Lightning’s Edit Event screen:

Screenshot of Thunderbird Lightning Edit Event screen
Lightning “Edit Event” screen, showing the new “Get Map” button

 

The first hurdle we ran into is that Lightning source code is kept in a Mercurial repository. Although William was familiar with Perforce (another code revision system), I haven’t used Mercurial until now. And the repository contained all of Thunderbird, Firefox, SeaMonkey, and the Mozilla addins. We certainly didn’t want to clone the entire Mozilla code base! So William found the Lightning tarball, which I unpacked in a new folder. This let us poke around the source files to find where our new code should go.

Then we found that Lightning isn’t straight Javascript, it’s mostly XUL. XUL is close enough to XHTML, CSS and DTD files that we could figure out what needed to be done. But we had a limited amount of time, and I didn’t want to spend it waiting for source code to build. So I created a new profile in Thunderbird, installed a fresh copy of the Lightning add-in, and we hacked at the installed files directly. This gave us instant feedback on the changes we made, just by restarting Thunderbird and running Lightning. Some of the changes were in plain text files, but others needed to be made to files in JAR format. One of those was the localized language file. We weren’t sure which language file we were using, en-GB or en-US. Of course, we picked the wrong one to start with, and spend maybe two hours trying to debug a misleading error message about a missing entity definition while we were working on the wrong file.

But it all turned out OK in the end. Now we need to take the work we did on the installed files and replicate it on the source files from the Mercurial repository, properly build Lightning from source, and offer our changes to the Mozilla Calendar project. And, once we’ve got it working, we’ll make the changes available on this site too.

–Bob and William.

Tags: , , , , , , , , , , , , , , , , , , , ,
Posted in code, FLOSS, Open Data, Software | Comments Off on OpenDataDay Hackathon at Kwartzlab

Blogging Etiquette – Deletions

Posted by Bob Jonkman on 6th November 2011

The word "Delete" as grafitti

Delete

Primarily Perfect People are Permitted to Perfunctorily Pass this Post .

The rest of us, Prone to Pecadillos, may occasionally write blogposts and then change our minds about the content. When that happens it’s best not to make changes or delete posts without letting your readers know.

Instead of making a wholesale change to a post it’s better to create a new post. Imagine if someone wrote about a similar issue, quoted from your post and provided links to it. Now your post has changed, and the links no longer make sense because the content has changed. Or someone makes a comment on a post, the content of the post is changed, and now the comment has nothing to do with the post.

Instead, create a new post with a new link. It’s a good idea to keep the original post; you could delete it, but then other people’s links would return an error (that’s called “link rot”).

About the only good reason for modifying an existing post is to correct an error. Even then you shouldn’t delete the incorrect material, but indicate it should be deleted by using the <del> tag, and marking the new material with an <ins> tag. For example:

The Javan Rhinoceros <del>has only one survivor </del> <ins> is now extinct</ins> in Vietnam.

This would show with crossed-out text for <del> and highlighted text for <ins>, like this:

The Javan Rhinoceros has only one survivor is now extinct in Vietnam.

(which is a sad development, and may be worthy of a post of its own).

If you really want to delete a post then replace it with text like “This post has been removed by the author”. If you do that then you should delete or hide the comments too.

These are open and transparent ways to indicate deletions. It’s merely an online publishing convention, since there really isn’t a style guide for HTML like Strunk and White’s in the online world. Or, more accurately, there are far too many Strunk and White’s in the online world!

–Bob.


Delete by delete08 is used under a CC-BY-NCCC-BY-NC license

Tags: , , , , , , , , , , , , , , , , , , ,
Posted in blogging, code, valid html | Comments Off on Blogging Etiquette – Deletions

Four things to improve your search result rankings

Posted by Bob Jonkman on 26th December 2010

A bottle of juice with a Google label

Google Juice by Johannes P. Osterhoff

Now there’s a spammy title for you!

 

There are many people who specialize in Search Engine Optimization (SEO). They claim to be able to improve your rank on search engines, but here are some common-sense tips you can apply yourself.

1

The best thing to maintain good page rank with ANY search engine is to have good content. This isn’t something an SEO company can do for you — you have to provide that content yourself. Repeating someone else’s content may bring you a few hits, but the search engines will quickly determine that the original site has hosted that content longer, and rank them higher.

Google is additionally funny in that they will count the number of sites that link to you, assuming that if you warrant many links, you must have something the Google customers want. If you switch Hosting Providers or change to a different domain name then anyone linking to the old domain name may have (temporarily) dead links. That will drain your Googlejuice right quick. If you have multiple domain names with the same content then the Google page rank is diluted. Better to have one domain with 1000 links than two domains with 500 each. You should ask your Hosting Provider to set up “301 redirected permanently” for any non-primary domains. Google is smart enough to figure out that http://www.example.com is the same as http://example.com, but I prefer no www. Why? See http://no-www.org/.

2

The second best thing you can do is to have valid HTML for all your Web pages. Sadly, many sites fail badly on that account (including this one). Have a look at the W3C HTML validator for this home page. As I write this, this blog’s home page has 29 errors. That will drain my Googlejuice right quick. If a search engine can’t parse HTML it won’t index content, or rank the page up high. That counts for all search engines, not just Google. I’ve written about this in Invalid HTML Considered Harmful. There are consultants that can help you correct invalid HTML; you may know one or two already 🙂

3

The third-best thing is to make sure your pages are accessible. If your site works well on alternative browers (PDAs, game consoles, cell phones) and assistive devices (braille readers, text-to-speech readers) and plain text browsers like Lynx then it’s a pretty sure thing that search engines can index the content too. Avoid Javascript, but if you use Javascript make sure that content delivery isn’t Javascript dependent — make plenty of use of the <noscript> tag. Don’t use non-indexable technologies like Flash, PDFs, Silverlight, or ActiveX. Google is getting pretty good at indexing PDFs and even Flash, but you’ll get better results with plain HTML. I’ve never seen a PDF that wouldn’t work as well-designed HTML. Non-indexable technologies won’t drain your Googlejuice, but they do nothing to boost it either.

4

The fourth best thing you can do is not play jiggery-pokery with hidden text, irrelevant keywords, cloaking, “sneaky” redirects, comment spam on other sites, or fake affiliate sites. If you try to outsmart search engines’ ranking algorithms to artificially boost your ranking, you may succeed for a few days or weeks before you’re banned altogether. That will drain your Googlejuice right quick. Besides, jiggery-pokery is a lot of hard work, better spent creating good content.

Update 1 March 2011: Told you so!

–Bob.

Google Juice by Johannes P. Osterhoff is used under a Creative Commons by-nc-nd license.

Posted in Accessibility, blogging, Internet, Javascript, Search Engine Optimization, search engines, valid html | 5 Comments »

Telephone Number Format Standards

Posted by Bob Jonkman on 20th March 2010

Telephone Dial

Standardized Telephone Number formats work even on old phones!

There are many different address books and directories online, and there are almost just as many different ways they store telephone numbers. I guess most people don’t realize that there are actually standards for representing phone numbers. A little bit of standardization would go a long way towards interoperability.

The standard for phone number formatting is set by the International Telecommunication Union in [E.123] and [E.164] (see the references below). The standards documents are available for a fee from the ITU [available at no charge since 2010 –Bob.] . A summary is available in the Google (UseNet) discussion group, titled Need ITU-T E.123 summary.

In short, a North American telephone number should look like:

+C-AAA-PPP-NNNN;ext=xxxx

  • “+” shows where the dialing prefix goes. This is one of either the International Direct Dialing (IDD) prefix (for Canada this is “011” for overseas dialing) or the National Direct Dialing (NDD) prefix (“1” for calls within North America, omitted for toll-free calls),
  • “C” is the Country Code (North America’s CC is “1”, and it is omitted for dialing within North America),
  • “AAA” is the area code (always required for dialing in Kitchener, Toronto, and other jurisdictions),
  • “PPP” is the Exchange (or Private Branch Exchange “PBX”; look in the phone book to see which exchanges are supported),
  • “NNNN” is the local portion of the number,
  • “;ext=” optionally identifies the next portion as an extension and “xxxx” are the digits for that extension. This syntax is usable in URIs and e-mail.

Note that the sequence “AAA-PPP-NNNN” is called a “local number” and “+C-AAA-PPP-NNNN” is called a “global number”. The “-” (hyphen) is a visual separator, as are “.” (period) , “(” (left bracket) and “)” (right bracket), which dialing applications should ignore.

I’m mostly interested in making phone number formats in e-mail addressbooks compliant with e-mail standards. The document that covers this is the IETF’s [RFC3191], "Minimal GSTN address format in Internet Mail" . The requirement is that GSTN (Global Switched Telephone Network) numbers use the global-number syntax (“+C-AAA-PPP-NNNN”).

Global-number GSTN numbers can be used for other purposes as well, such as Web page URIs. See [RFC3966], "The tel URI for Telephone Numbers". This document re-iterates that:

5.1.4.
Global Numbers Globally unique numbers are identified by the leading “+” character. Global numbers MUST be composed with the country (CC) and national (NSN) numbers as specified in E.123 [E.123] and E.164 [E.164]. Globally unique numbers are unambiguous everywhere in the world and SHOULD be used.
5.1.5.

Local Numbers Local numbers are unique only within a certain geographical area or a certain part of the telephone network, e.g., a private branch exchange (PBX), a state or province, a particular local exchange carrier, or a particular country. URIs with local phone numbers should only appear in environments where all local entities can successfully set up the call by passing the number to the dialling software. Digits needed for accessing an outside line, for example, are not included in local numbers. Local numbers SHOULD NOT be used unless there is no way to represent the number as a global number.

Local numbers SHOULD NOT be used for several reasons. Local numbers require that the originator and recipient are configured appropriately so that they can insert and recognize the correct context descriptors. Since there is no algorithm to pick the same descriptor independently, labelling numbers with their context increases the chances of misconfiguration so that valid identifiers are rejected by mistake. The algorithm to select descriptors was chosen so that accidental collisions would be rare, but they cannot be ruled out.

If you work at a company that does work with organizations and staff members outside of the context of your area code (ie. internationally) be sure to standardize your directory on global-number syntax.

–Bob.

Need a consultant? Bob Jonkman can be reached by telephone at +1-519-635-9413

References:

Image: Telephone Dial by Leo Reynolds, used under Creative Commons v2.0 BY-NC-SA.

Posted in code, smtp, telephone, valid html | 4 Comments »

Welcome back!

Posted by Bob Jonkman on 16th October 2009

Crossing the Floor

Crossing the Floor

This blog is not for reading at its new location… Here!

In politics, this would be called “crossing the floor” — not only did this blog move to a new domain name, but the underlying software has changed from Blogger to Wordpress. There’s a political statement if ever there was one.

The move isn’t done yet. There may be some superficial colour and layout changes, some slightly more substantial tweaking of sidebars and widgets, and possibly a very substantial URL change (I’d really like to get rid of “blogs” in http://bob.jonkman.ca/blogs/2009/10/16/welcome-back/, but keep the sign-in page at http://jonkman.ca/blogs/. Technical advice for crafting Apache rewrite code is welcome, and will be duly credited.

Now that it’s on the Jonkman Family web site, I hope there are other Jonkman family members who start their own blogs here too. You’ll need an e-mail address in the @jonkman.ca domain, but those addresses are available for the asking.

–Bob.

(image from Nizzlebop’s Gallery, labelled for re-use by Google Image Search)

Posted in blogging, code | 2 Comments »

Invalid HTML considered harmful

Posted by Bob Jonkman on 28th April 2009

Valid HTML is not just useful for browsers. One of the big benefits of having valid HTML is that search engines can properly index your site. If the HTML is invalid, then the search engines may index you incorrectly, or not at all. Google isn’t the only search engine out there, and you want to drive as much traffic to your site as possible.

There appears to be some contention whether valid HTML makes a difference to search engines or not. Some say it doesn’t; or that it depends on the search engine; others have evidence it matters a lot.

Favicon - HTML DogHTML Dog (blue and white posterized picture of a dog's head (boxer?) between two angle brackets, as if it were an HTML element)https://htmldog.com/

Even if you’re not coding by hand, I urge you to have a look at HTML Dog, a set of tutorials on creating valid HTML. When things don’t work as expected you can turn here for examples in XHTML.

Favicon - Kompozerhttp://kompozer-web.de/

If you’re going to be using an editor for your Web pages, pick an editor that creates proper HTML code. Abandon FrontPage. I suggest using KompoZer, which is based on the same rendering engine as Firefox (Gecko).

Favicon - Opera.comhttp://opera.com

You should also be checking your pages in Opera, which is a browser that is even better for standards-compliance than FireFox. The Chief Technology Officer for Opera is the same guy that wrote the Cascading Style Sheets specification, so it has a good pedigree.

If you’re using Firefox then be sure to check your pages with the HTML Validator addon:

Favicon - Skynet.behttp://users.skynet.be/mgueury/mozilla/

And when you think your site is done, check each page with the full-strength validator:

Favicon - W3C HTML Validatorhttp://validator.w3.org/

Favicon - CSS Validation Servicehttp://jigsaw.w3.org/css-validator/

<heavy sigh… />

–Bob.

Posted in considered harmful, valid html | 5 Comments »

Putting up the Christmas tree

Posted by Bob Jonkman on 14th December 2008

Christmas Tree

# Program: trimtree
# Purpose: To prepare a Christmas tree before decorating
# Date: before 25 December

repeat until (height == 0)
{
if (wife == “It’s lopsided!”)
{
trim_bottom_branches(leftside)
}

if (wife == “It’s leaning!”)
{
trim_bottom_branches(rightside)
}

if (wife == “It’s bare at the bottom!”)
{
saw_off_base(to branches)
}
}
end loop

Image by Tom Carmony, used under CC

Posted in Christmas, code, pseudocode, tree | 6 Comments »

 
Better Tag Cloud