Widget A Day: Take 2

Since I’m bored, and some of my old widgets have had some feature requests, so I think I’ll try Widget A Day again. I’m going for at least 14 widgets, so 2 weeks, some being updated versions of the older ones.

It would most likely start the beginning of next week. (Edit- not happening this week, but should be next week)

If you have requests or ideas, post them here. I need them to be able to do this.

Paintball Headlines Theme

I said I would post the theme for headlines when I thought it was acceptable. There are still problems, but whatever.

Anyways, this theme is based upon this tutorial theme, but changed to have multiple author support, support tags and categories, and be a double right column instead of a column on both sides. There are a few other little changes in there.

SVN: http://svn.devjavu.com/skeet/headlines-new-theme/
Trac: http://skeet.devjavu.com/browser/headlines-new-theme

Diff between both themes

I’ll try to update the theme whenever I change anything; I just have to remember to do a svn ci each time.

To run by default and not get errors, you need do need a few plugins, like wp_dtree. There’s also a classifieds plugin that I wrote just for headlines that’s needed, but I don’t plan on releasing that, since it contains db info and it’s pretty much just a MySQL query. In sidebar.php, just comment out the get_classifieds_new(10); code.

WordPress Widget-A-Day

I’ve been wanting to do a ‘Something-A-Some-amount-of-time’, and since I just made a WordPress Widget, which is pretty easy, and with WordPress 2.2, widget support is available by default, I decided to do a ‘WordPress Widget-A-Day’.

Over the next week, though I’ll probably start today, so I guess it’ll have 4 extra or maybe just 1 depending on my motivation, I’ll make and release a widget for WordPress everyday. These might not be fancy, they might not even be original, though I’m going to try to not make ones that already exist with the same functionality, but they’ll be widgets.

If you have any ideas or suggestions, comment or contact me.

View posts about Widget-A-Day or subscribe to the Widget-A-Day feed

Hopefully, I won’t fail at this.

Simple XML is Simpler!

Genius!

Sucks that it isn’t for PHP 4. For this site, at the moment, I’m forced to use PHP4, since PHP5 breaks permalinks for WordPress for some reason. It’s not Wordpress’s fault, though. Just the crappiness that is this shared hosting.

Anyways, I’ve used SimpleXML for most of XML parsing in PHP. Mainly for the reason that I’m lazy. This time, I wanted the site to run on here under PHP4, so I didn’t have that success. But PHP’s XML Parser shouldn’t be too bad, right?

Here’s how to go through all the <item> tags in an RSS feed via SimpleXML and placing them into an associative array:

$sxml = new SimpleXMLElement($xml);
 
foreach($sxml->channel->item as $item) {
	$items[$i]['title'] = $item->$item_title;
	$items[$i]['link'] = $item->$item_link;
	$items[$i]['desc'] = $item->$item_desc;
	$items[$i]['date'] = $item->$item_date;
}

Now in XML Parser:

$parser = xml_parser_create('UTF-8');
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($parser, $xml, $vals, $index);
xml_parser_free($parser);
 
$feed = array();
$items = array();
 
$length = ($item_title == $title) ? count($index[$item_title]) - 1 : count($index[$item_title]);
 
$titleoffset = ($item_title == $title) ? 1 : 0;
$linkoffset = ($item_link == $link) ? 1 : 0;
$descoffset = ($item_desc == $desc) ? 1 : 0;
$dateoffset = ($item_date == $date) ? 1 : 0;
 
for($i=0;$i<$length;$i++) {
	$items[$i]['title'] = $vals[$index[$item_title][$i+$titleoffset]]['value'];
	$items[$i]['link'] = $vals[$index[$item_link][$i+$linkoffset]]['value'];
	$items[$i]['desc'] = $vals[$index[$item_desc][$i+$descoffset]]['value'];
	$items[$i]['date'] = $vals[$index[$item_date][$i+$dateoffset]]['value'];
}

Only about 10 more lines and ridiculous looking arrays.

This also doesn’t show that you have to run strtoupper($tagname) on all of the tags you want.

One thing that SimpleXML couldn’t do is parse elements with a colon in them. Like <dc:creator> or <content:encoded>. A simple fix was just to run str_replace("<dc:creator>","<creator>",$xml)

Uggh. At least the annoying part is finally out of the way, I hope.

Update- Haha. That doesn’t even work. It’s nowhere near the correct order. But I totally forgot about MagpieRSS. I’m using that instead.

Fun with Digg’s API

Digg’s api was released about a week ago a while ago, and since that time, various flash projects have surfaced, probably due to that pesky contest. But I don’t have any flash experience, so PHP, here we come.

We’re going to make various tag clouds, a Reddit clone, Reddit/Better RSS feed, and a live diggs app.

Update - 05/09/07 - 3 PM - Stupid host seems to be having database issues. Great. I wish I could afford a dedicated, or I guess VPS, so I don’t have to put with this crap.

Update - 05/09/07 - 6 PM - It seems that it was a combination of their db sucking and the fact they got rid of some essential pear packages. WTF?

Update - 05/12/07 - 11 AM - Yup. They cut off my MySQL abilities. I can’t connect to any of my databases on xrho.com. This site is fine however. I guess inserting 100+ entries a minute might have annoyed them?

Update - 05/17/07 - 7 PM - The MySQL abilities are still cut off. Fucking netfirms. Also, it seems in one of my updates, it cut off the bottom, which also happened to include the download links. You can download a ZIP or Gzip of the files. Since I’m having problems with that, feel free to download them and run them on your own site. Let me know if you do so I can add the link.

Demos of most of the scripts are available here, and more specifically:

Due to the length of this post, I’m splitting it. I hate making people click through, but it’s long enough to constitute it.
Continue reading…

Great. Friendly URLs aren’t working anymore.

So for some reason, friendly urls are broken. I mentioned earlier how to get friendly urls working on Netfirms, but now that is fucked up. Great Netfirms, keep sucking complete ass. For the time being, I’ve reverted back to the old style, however result in Google will still be messed up. Expect a rant about the shittiness of the Netfirm’s service soon, once I find a new host. Anyone have any recommendations?

I also was going to have a big post about Digg’s API today, but that’s looking much less likely now.

Update: I think I got them working. The only explanation I can think of is that I switched from PHP 4 to 5 last night. That really shouldn’t have fucked it up, but I put it back to PHP 4, and now it seems to work. Fucking stupid, since I need PHP 5 for the digg script. I guess I can distribute it on xrho.com.

WP-Cache and Netfirms

In order to get WP-Cache to work with an account on Netfirms, you have to go through a few extra steps. In order to do these, you need to have SSH enabled, and have some sort of way to connect to it, like PuTTY on Windows.

First, download the wp-cache files and upload them to your plugins directory.

Then, connect via SSH and cd to your wordpress directory, and chmod ‘wp-content’ to 777. This is done by executing, chmod 0777 wp-content.

Now, go to the Plugins tab in your Wordpress admin panel, and activate WP-Cache.

Next, go to the Options->WP-Cache tab and click Enable it.

This will show an error and your blog will not be accessible. This is expected, and will be fixed quickly

Now, connect via SSH and cd to your wp-content directory, and chmod the ‘cache directory’ to 777. This is done by chmod 0777 cache.

Now, you need to create a symbolic link and chmod that correctly. This is done by:

ln -s plugins/wp-cache/wp-cache-phase1.php advanced-cache.php
chmod 0777 advanced-cache.php

Now, reload the Options->Wp-Cache page. Click Enable it again, and it now should be enabled and working.

If you have problems, you can disable WP-Cache by editing wp-config.php and removing the line
define('WP_CACHE',true);

PEAR & Efficiency = Crap

pear logoI needed to convert times from different timezone. Now, I could hack together something, like I usually do, but I decided to try to make my life easier.

First, I found some timezone PHP script that amount to nearly 800 lines + 75 entries into a database, which also happened to be easily SQL Injectable. Great, this wasn’t going to work.

Next up, PEAR. This Date package looks promising. Can convert times from timezones easily, and DST seems to work. It was all looking good. Even after a few hacks to get it to work right, everything was good, until I looked at the generating time.

It was at .085 seconds, up from .025 s. That’s a 340% increase. That’s not going to work. I was just using it’s my own timer using microtime and didn’t try http_load, but the results were pretty damn consistent. You might think that it’s only 60 ms, but I always think about security and efficiency when making something. If it ever happens to get a lot page views, hopefully I can operate with less server power or not face scalability problems like Twitter.

All of the added time is from including this big ass class. The Date.php and it’s four sub files account to about 350 KB. All the files that are running my whole site are only 214 KB, which includes CSS, Javascript (with prototype.js), templates, and so on. Now, it does have a lot of documentation, but still, damn!

Another ridiculous thing, it decided to redefine the formating characters. Instead of following whats already used for date, it decides to just go through the alphabet. I’m sure there’s some methodology going through it, but I sure as hell don’t see it, except that M/m and H/h are minutes and hours respectively.

So now I’ve wasted 30 minutes fangling with 2 scripts, and both suck. Plus I’ve spent another probably 15 minutes writing my disgust with these 2 scripts. I could’ve just written the damn thing myself already, probably by just slightly modifying this.

Domain Names Are Fun

I had fun with domain names tonight. I wanted to find all 4 letter domain names that start with pb that were available. I tried doing a whois lookup for each one, but that never would work right, so I just did a DNS lookup for each one. If it didn’t resolve, I assumed it was available. Not a very great test, but it did cut down 4 letter domains down nearly 500 and 5 letter domains down a couple thousand.

One thing I didn’t account for was shown for pbusa.com. pbusa.com doesn’t resolve, but www.pbusa.com does.

Got 100 domains:
http://uploads.diabloowners.com/4letterdomains.txt

A lot of these are taken. Doing a whois will let you check if it’s been taken or not.

Next up, 5 letter domains. 15487 entries.
http://uploads.diabloowners.com/5letterdomains.txt

Let’s find which ones contain words using valid Scrabble words.

672 entries.
http://uploads.diabloowners.com/5letterdomainswords.txt

Here’s what I used to check them:
checkdomains.py (This is for 5 letter. Removing the innermost loop and changing domain will do 4. Done for OpenDNS, since for domains that don’t resolve, it’ll give back ash.guide.opendns.com)
http://uploads.diabloowners.com/checkdomains.py.txt

wordparse.py (Changes the Scrabble copy and paste to a 1 row file and then checks it against domains. And yes, the inner loop runs a ridiculous amount or times. 15037877 times to be exact. Should’ve kept a counter and such, but I did it really quickly and didn’t worry about the extra clock cycles)
http://uploads.diabloowners.com/wordparse.py.txt

Acunetix

I brought out Acunetix to test the script that I’m writing. It’s a pretty noisy web vulnerability scanner that tests for XSS, SQL Injection, server vulnerabilities, and other things that just shouldn’t be around. I’m not going to reveal too much about my script, but it consists of a user system, private messaging, posting with revision history, threaded replying, completely dependent on mod_rewrite, and some other things, all coded from the ground up with security in mind while doing it. So I was pretty surprised when Acunetix showed 352 ‘alerts’.

Acunetix 1

First off, SQL Injection. It showed 48 cases of successful SQL Injections. Crap! Luckily, all 48 injections were for one page, the deleting of private messages. These consisted of setting POST variable 5 or 7 or 1 to ‘ or %27 or %2527 or ” or ‘” and so on, and the response it would get would be:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘)’ at line 1

Once this gets out of development, I would change this to email me instead of just showing it, but it was still giving a valid SQL problem. This was kinda confusing, since it only cares if POST variable 5 is set and equal to “on”. If it’s anything else, it just ignores it.

First, I’ll explain how my message deletion system works. The inbox consists of a table of message titles, the sender, time sent, and a little checkbox to delete the message. The checkbox name is equal to the message id. Then there is a hidden input that lists all the message ids seperated by commas, like

<input type="hidden" name="messages" value="10,7,5,1" />

So, once the form is submitted, it explodes $_POST[’messages’] and runs through each one to check if the POST variable matching the message id is set and equal to “on”. (Note: I could’ve just put the $_POST array in a foreach loop and done it from there, like foreach($_POST as $key => $value) { /* check it */ }, but for some reason I didn’t.

Here’s the code to it. There is also a check to make sure that the POST variable hash is set to what it should be. This is used to protect from someone putting a form to delete a user’s messages in an iframe or something.

if(isset($_POST['delete']) AND $_POST['delete'] == "Delete Messages") {
	if(isset($_POST['messages'])) {
		$messages = explode(",",$_POST['messages']);
		$where = ($_POST['type'] == "sent") ? " WHERE `sender_id` = '$logged_user_id' AND ( " : " WHERE `receiver_id` = '$logged_user_id'  AND (  ";
		$done = false;
		foreach($messages as $message) {
			if(is_numeric($message) AND isset($_POST[$message]) AND $_POST[$message] == "on") {
				if(!$done) {
					$where .= " `msg_id` = '$message' ";
					$done = true;
				}
				else {
					$where .= " OR `msg_id` = '$message' ";
				}
			}
		}
		$where .= " ) ";
 
		$query = "UPDATE `privmsgs` SET ".(($_POST['type'] == "sent") ? "`senderbox` = 'Deleted'":"`receiverbox` = 'Deleted'")." , `timedeleted` = ".time()." $where";
 
		mysql_query($query) or die(mysql_error());
 
 
	}
}

If you notice, the POST variable 5 doesn’t get anywhere near the query. It’s checked to see if it’s set and equal to “on”. The variable from $_POST[’messages’] is the one put in the query, and that’s only if it’s also numeric.

So, I launched the attack in it’s HTTP Editor and set the page to just echo the query, and it printed:

UPDATE `privmsgs` SET `receiverbox` = 'Deleted' , `timedeleted` = 1175118688 WHERE `receiver_id` = '1' AND ( )

Aha! No messages where equal to “on”, but the query still fired. Simple fix. Just enclose the query in the if statement if($done), and that bug is squashed. There was no possibility of SQL injection though. So even though it was inaccurate, it did help me find a bug.

Next, Blind SQL/XPath Injection. It states that the variables post and posthash are vulnerable. Uh, no? These are never placed into the database, just to make sure the person is posting instead of previewing and prevent people from automatically creating posts just by running a script or the iframe protection like mentioned for the PM’s. It’s never even close to the query.

Apache mod_ssl vulnerabilities. XAMPP problem. It’s not for production anyways.

PHPSESSID session fixation. This means that someone can set the session id using a GET parameter, like

http://example.com?PHPSESSID=h4x0redsessionid

Now, the attacker knows that value and doesn’t have to steal it at a later time. But since there is no sensitive data being stored using sessions in my script, this isn’t so much a problem. To fix this, set session.use_only_cookies = 1 in php.ini.

User credentials sent in clear text. 48 of these. I actually have it built to be able to use a secure login, but probably won’t use it.

The rest were basically all false positives. It says it found sensitive directories, files, ASP.NET files, Access databases, and most anything you can think of. This turns out to just be a simple glitch with mod_rewrite. Here’s the line:

RewriteRule ^browse-posts/show-sold(/category/([a-zA-Z0-9-]+))?(/page([0-9]+))?/? browse.php?show=sold&category=$2&page=$4 [L]

I didn’t put $ behind the match. So, /browse-posts/show-sold/password.txt would be show a page, and /browse-posts/show-sold/Web.config would show the same thing, /browse-posts/show-sold/CVS/Repository same thing.

Even though there was no real problem, just an annoyance, it was an easy fix:

RewriteRule ^browse-posts/show-sold(/category/([a-zA-Z0-9-]+))?(/page([0-9]+))?/?<b>$</b> browse.php?show=sold&category=$2&page=$4 [L]

Now, /browse-posts/show-sold/password.txt sends a 404.

So, if you don’t include the mod_ssl problem, it found 0 vulnerabilities, 1 bug, 1 possible problem, and about 300 false positives, so I’m not really sure of the usefulness of this. If you have an app you want to easily test, it can help, but I don’t see this as a sure fire way to test it.

Close
E-mail It