Posts Tagged wordpress

Debugging Sociable

Not too long ago, I came across a nasty Sociable bug that completely prevented it from being used with certain server configurations. I located the source of the bug and nailed out a quick workaround that allowed the plugin to be used, but you lost the ability to change the site order. Tonight, I created a diff patch that is the first part of fixing that issue.

This diff has some lingering issues – namely dealing with legacy support and continued support. It works fine as is, but any previous installations will need to redo their social media choices, and future social media choices will need to be added in at the end of the data, rather than alphabetically. The first issue can be solved with some key scanning, the second issue isn’t a huge concern to me, since this array is only visible to developers, anyway.

When I got down to working on this plugin, I really had no idea what I was working with. I’ve never really looked into the Sociable code, and even less time on the Wordpress code. However, I was going to get this thing fixes come hell or high water, and I think I accomplished my goal.

The first thing I did was write a regex find / replace to adjust the array. This array had nearly 100 elements in it, so a manual adjustment was out of the question. After I had adjusted that array, I went through the sociable.php file and put a bookmark everywhere that this array was possibly being used. Wordpress is heavy on procedural code, so global variables such as this have to use the global command. I just sought out any function calling this variable globally. I also had to bookmark the end of scope on those functions, since the whitespacing and indentation was often done pretty haphazardly and in non-obvious ways.

I narrowed down my search to just three functions – sociable_html, sociable_restore_config and sociable_submenu. These three functions called this variable from the global scope and thus could be affected by my changes.

I first delved into sociable_restore_config(), which didn’t appear to actually use the array I modified. It really should not be calling it globally (which is horrible, anyway) and it might be some fragment of old code that never got properly cleaned up. The only place that things would be affected was the function to restore default settings. It was storing the keys based on the name of the engine, which won’t work under my patch. I modified this to save the IDs, but it is a bit hard to read. I’m not fully satisfied with this little trick, but it will do for now.

I next got into sociable_submenu() and noticed that most of the function will work with this new system. The most major concern is dealing with support on determining what is and is not an active site. Currently, it uses the string keys, but my patch changed those keys to autoincrement IDs in an array. This means that if you have Digg chosen, and it is #18, but a new engine is added before Digg, Digg is now #19, and the previous #17 will be chosen, as it is now #18. This could be a problem if the developer desperately wants to keep the array alphabetised, even though it really should be in the database.

This will also cause some legacy support issues in this area. Existing sites will store the value in the database as ‘Digg|Sphinn|Facebook’, but new sites will use ‘18|47|22′ instead. This means that when it removes active sites, it won’t recognize ‘Digg’ as meaning ‘18′ and will remove nothing. I can fix this with some variable scanning. If the variable is not an integer, do a foreach across the $sociable_known_sites and find which one it actually means. A single correction cycle will fix all issues – it won’t need to run that scan more than once per social media site.

The next thing I did was changed the form to display the correct information. Since the array has been adjusted and the keys no longer do what is expected, I had to change it to use the right value and display that on screen.

The only part I had difficulty with was the ternary statements in showing a social media site as being selected. Prior to my patches, it was doing an array merge on active sites and inactive sites, with the array keys being the name of the site. array_merge() leaves keys on strings, but wipes keys on numeric, so the keys used to remain intact but no longer would. This meant that if Facebook was ID #11, and it was chosen, it wouldn’t always display Facebook as being active. Instead it would merge active and inactive, and say the 11th item in the list is chosen.

In order to counter this issue, I did a little toying with array_combine(), array_keys() and array_merge() to merge the two arrays together and leave the array keys intact, even though they are numeric.

After this fix, all seemed to be well on the site. Legacy support for older key names and continued support to not break the data if the array is modified are going to be needed, but this patch changes the way the post data is sent to [hopefully] not cause an issue with certain Apache servers. Unfortunately, I can’t get my Virtual Machine (Ubuntu 9.04) to replicate the issue. I have a Fedora 10 VM that I may try to get the issue reappearing on, but if that doesn’t work, I can test the issue on Monday when I have access to the server that has a known issue.

Here is the diff patch, hopefully it will be implemented soon enough, as I think this does some good in correcting an issue that is out there. The traffic to my site searching for that issue is pretty substantial, and this patch covers the problem pretty well.

Update: I did some further thinking on the array_combine() trick and ended up removing it. It seemed like there should’ve been an easier way, and apparently you can just use + to union arrays based on keys, which is exactly what I doing. So, I adjusted the diff patch to use this setup, which is far cleaner and easier to read.

, , ,

No Comments

Debugging is a hell of a drug

Lately, I’ve been spending some time on the Wordpress support forums just helping debug issues. I don’t really know much about Wordpress, but nothing makes you learn the ins and outs of a system like isolating and fixing bugs. I set up a new Wordpress site on one of my virtual machines just to do these tests. If I trash it too much while debugging, I can always just scrap and start over and get myself cleaned up again.

While setting up this new Wordpress site, I somehow managed to trigger the no credentials updating system that visual77.com and septuro.com use, but I’m not sure how I did that. Whenever you update or install a plugin, it often asks for FTP / SSH credentials to transfer the data, but neither visual77.com nor septuro.com require credentials. Every other Wordpress site I have set up does require credentials – but this test bed does not. It may be a permissions issue, and since this test site is 0777 for everything, I have sufficient permissions. I’d never set a live site to 0777 for everything, but since it is on a virtual machine that is inaccessible outside of my network, it’s safe to do that.

I’m having a good time on the Wordpress support forums with these bugs – anything I can replicate, I can fix. Much of my early PHP days was just based on trying to make small tweaks to PHPNuke, and that helped me learn much more rapidly than some boring tutorials or bullshit code exercises. I learn by doing, and doing stuff on fully built systems is my favorite way to understand the system. At this rate, I’ll know Wordpress as well as the creators within a month and I can start debugging Wordpress core bugs.

, ,

No Comments

A fix for the Wordpress Sociable plugin Method Not Implemented error!

In my last post, I mentioned I was hitting an error in my Wordpress installation where anytime I tried to save the Sociable settings, I got this error:

Method Not Implemented
POST to /wp-admin/options-general.php not supported.

I dug around a bit further, looking into the error logs on my Apache server and I found this…

[Thu Jun 04 09:48:15 2009] [error] [client ***.***.***.***] ModSecurity: Access denied with code 501 (phase 2). Pattern match "(?:\\b(?:(?:n(?:et(?:\\b\\W+?\\blocalgroup|\\.exe)|(?:map|c)\\.exe)|t(?:racer(?:oute|t)|elnet\\.exe|clsh8?|ftp)|(?:w(?:guest|sh)|rcmd|ftp)\\.exe|echo\\b\\W*?\\by+)\\b|c(?:md(?:(?:32)?\\.exe\\b|\\b\\W*?\\/c)|d(?:\\b\\W*?[\\\\/]|\\W*?\\.\\.)|hmod.{0,40}? ..." at ARGS:site_order. [id "950006"] [msg "System Command Injection. Matched signature <|ping>"] [severity "CRITICAL"] [hostname "*********"] [uri "/wp-admin/options-general.php?page=Sociable"]

That’s a pretty big error, but the important things are:

  • ModSecurity – this is a security error, not a technical error. It spotted something it doesn’t like.
  • Pattern match – that is a big regex. I didn’t want to reverse engineer it (and luckily, I didn’t have to do that), but if it came to it, I would’ve figured what it was seeking.
  • System Command  Injection – the server thought it saw an injection attack and blocked it outright.

Basically, when the Sociable form is sent through post data, some part of the information sent is flagged as a potential injection, and the server rejects the data outright. I saved the sociable page to my computer and set up a .php file to dump post data, then I sent the form to that page. This was so I could see what the post data looked like. This is what I got, after unchecking all of the checkboxes and clearing all text fields:

Array
(
    [_wpnonce] => c05fbc3c51
    [_wp_http_referer] => /wp-admin/options-general.php?page=Sociable
    [site_order] => BarraPunto|Bitacoras.com|BlinkList|BlogMemes Fr|BlogMemes Sp|blogmarks|Blogosphere News|blogtercimlap|Faves|co.mments|connotea|Current|del.icio.us|Design Float|Digg|Diigo|DotNetKicks|DZone|eKudos|email|Facebook|Fark|Fleck|FriendFeed|FSDaily|Global Grind|Google|Gwar|Haohao|HealthRanker|HelloTxt|Hemidemi|Identi.ca|IndianPad|Internetmedia|Kirtsy|laaik.it|LinkArena|LinkaGoGo|LinkedIn|Linkter|Live|Meneame|MisterWong|MisterWong.DE|Mixx|muti|MyShare|MySpace|MSNReporter|N4G|Netvibes|NewsVine|Netvouz|NuJIJ|Ping.fm|ppnow|PDF|Print|Propeller|Ratimarks|Rec6|Reddit|RSS|Scoopeo|Segnalo|Simpy|Slashdot|Socialogs|SphereIt|Sphinn|StumbleUpon|Symbaloo|Technorati|ThisNext|Tipd|TwitThis|Upnews|Webnews.de|Webride|Wikio|Wikio FR|Wikio IT|Wists|Wykop|Xerpi|YahooBuzz|Yahoo! Bookmarks|Yigg
    [tagline] =>
    [imagedir] =>
    [save] => Save Changes
)

Whoa! What is that site_order thing in there? That’s a pretty weird looking block of text. Weird enough that it might just be flagged as injection. I started hunting down where that comes from, and identified it in /wp-content/plugins/sociable/sociable.php and removed it. After removing that line, the error stopped showing up! I can no longer change the site order of the social sites, but that’s a small price to pay for being able to save my settings!

To fix this error:

  1. Open /wp-content/plugins/sociable/sociable.php
  2. Find the line that looks like this (it was line 855 for me)
    <input type="hidden" id="site_order" name="site_order"
    value="<?php echo join('|', array_keys($sociable_known_sites))
    ?>" />
    
  3. Delete it!
  4. Save the file.

That is it. You lose the ability to reorder the sites, but you get past the error. Some apache servers apparently see this post data as an injection attempt and block it, so we just remove this line and it no longer sees this injection attempt.

4 Comments

Why is Wordpress such a pain to install properly?

When I installed Wordpress on visual77.com, I used the Fantastico installer, and it worked perfectly. Plugins can be automatically installed, all of my plugins work fine, uploading is great, the whole nine yards. At my day job, I’ve had to set up a few Wordpress blogs, without the benefit of Fantastico, and I can never get the install working correctly. This most recent install takes the cake for pain in the ass. I tried using Plesk’s installer (fuck Plesk, by the way, I hate that system), and here was the sequence of events…

  1. Use Plesk installer to install Wordpress 2.0… 2.7 is the most recent stable, so this version is pretty old, and really ugly. I log into wp-admin okay, but get permission issues on any other page.
  2. Do a manual upgrade to 2.7. This seems to go smooth, but now I can’t log in, it seems to accept my credentials, but deny all page requests.
  3. Find out where it is checking permission, bypass that function to give permission to anyone on any request.
  4. Go to the user editing to change my role to Administrator. There are no roles. The dropdown is blank.
  5. Sift through code, finding how that dropdown is populated. Find out it’s looking for an entry in the options table called ‘user_roles’, without a prefix, because this install doesn’t use a prefix.
  6. Go to the database and find an option called ‘wp_user_roles’. Upon install, Plesk fucked this name up. Change the name to just ‘user_roles’.
  7. Remove my permission bypass and log in again successfully.
  8. Attempt to install a new plugin, but instead of the automatic install visual77.com does, it asks for FTP credentials. I don’t know why visual77.com doesn’t need FTP credentials for installing a Wordpress plugin, but once I find out, I’ll write about it. I just use FTP instead.
  9. Install Sociable plugin for Wordpress, attempt to save the options, and get this error…
    POST to /wp-admin/options-general.php not supported.

This is where I am currently at – stalled while fighting Sociable. I’ll write more once I have a solution. I looked around the web and couldn’t find one.

Wordpress is fantastic when all goes smoothly, but it seems to die ungracefully. It is a fickle system that is only good when it all goes well. If it wasn’t for visual77.com, I’d hate Wordpress, but the install here went perfect, and now I really like it. They just need to get better at letting you know what is wrong and how to correct it.

, ,

No Comments