Archive for the ‘PHP’ Category
Saturday, February 19th, 2011
As a follow up to last week's post (How to comment on this blog), this week I bring you the results of the no-captcha test.
After much spam slipping through reCAPTCHA, I decided to nix a captcha all together. Originally I thought that just requiring a field via javascript and doing no server side checking would work. This was silly of me, of course. The spammers, having the source code of WordPress, would just blindly submit a comment to any post, bypassing any client side JS checks I had in place.
The fix was to create a field that was not known to spammers like the reCAPTCHA is. Further, if it is appended via javascript, then it is even harder to automate. I wrote the simple-math plugin (have a copy!) and implemented it as follow:
- Turn off reCAPTCHA
- Add a field via javascript
- Ask a simple math question, validated in client side JS
- Only validate that the field exists, not that the math is right, on the server side
The jury is, and I'm fully vindicated. Here's the stats:
|
Hits |
Comment Attempts |
Comment Succeses |
Attempts per Visit |
Defense Success Rate |
| Feb 6th-12th |
1191 |
57 |
17 |
4.79% |
70.18% |
| Feb 12 11pm – Feb 13 10am |
58 |
20 |
13 |
34.48% |
35.00% |
| Feb 13th-Feb18th |
1204 |
132 |
0 |
10.96% |
100.00% |
The important thing to note is twofold. The first is that the average number of raw hits (excluding me, yahoo and google) was the same week to week. Further, the number of attempts went up 200% of which 100% were thwarted (Defense Success Rate). Again, I suspect this is all possible because it's not easy, nor worth while (it's OK, plip isn't a big blog, I know…sniff) to automate spamming against one off solutions like mine.
I should note that I used the free version of Splunk to garner the ad hoc stats for this post. As I was hemming and hawing on whether to count cookies or IPs or hits, it wasn't worth while to use the old school command line style stats. Splunk scoffs at this level of stats and reporting. Really, it's above it, but will happily crank out what you ask for it with ease. Here's a purty graph:
Caveat Emptor: I work at Splunk.
Posted in Linux, PHP, Tips | Comments Off
Saturday, February 12th, 2011
It seems that reCAPTCHA is a victim of its own success. Y'all know I'm a huge, huge fan. However, recently the spammers have started to submit comments, successfully getting past the reCAPTCHA . I suspect this is a mechanical turk or some such tomfoolery. Of course the comments don't get approved, but they're still a bother to have to delete.
Our friend over at hanskellner.com ( guess which friend?) also has the same problem with submitted span. This makes it clear that reCAPTCHA is being targeted (well, not clear, but it's better than n=1!). However, he found a solution to stop the spammers. He added a static math question to his comment form. That is, it's always "what is 5 + 6", never any other question. Funny enough, his spam stopped all together. He still has his reCAPTCHA giong, but now it's a two factor anti-spam.
I posit that the reCAPTCHA code is easy enough to programmatically detect, but some random math question isn't, so it breaks the spam scripts. Let's test this theory, shall we? I've just written a word press plug-in called simple-math. Using a simple to hack, all client side javascript there's now an easy to solve math problem on the comment form. It is random, choosing two numbers between 0 and 9. I haven't tested it too broadly, but you're welcome to a copy.
I'll let it run for a week and see how it goes and report back.
Feb 13th Update: I fought the law, and law won! Spammers got past round one of simple math. I've updated it to now check for the existence of the field on post, but still, no checking for a right answer on the server. As well, the field is created via javascript. Spammers, back to you for round 2.
Posted in PHP, Ramblings, Tips | Comments Off
Tuesday, September 14th, 2010
Remember way back when we posted 404er? Well, good news! We jumped through the hoops and now our plugin is officially on the WordPress site. Clearly the readme needs to be updated so the page is a little more full featured.
Soon, when we're indexed, you can search for us by name at your nearest WP admin control panel. Here's a 'recently changed' listing showing the 404er:
Noteworthy is that WordPress.org has really gone above and beyond to help developers. We get a full SVN environment, lots of PR on their site, detailed yet easy to read docs and best off, a really rich code base to code against. Thanks WordPress!
Posted in PHP, Ramblings, Tips | Comments Off
Saturday, October 24th, 2009
Here's a random collection of items that happened over the last 10 or so days.
My friend's blog got hacked! This is because of a WordPress exploit that allows a user to create an admin user and log into your blog. They can then upload random stuffs to do all sorts of nasties. Your best bet is to first check that your blog hasn't been hacked and then upgrade to the latest version. Sadly, if you've already been hacked, the new admin user in there and upgrading won't boot this user. Plip has upgraded as we weren't hacked, but we lost our Plipish theme. That'll come back soon, promise.
Our friend from twtitw joined us for a commute on the Ferry to SF. It's a lovely way to commute, they take bicycles and sometimes you get spooky fog! Then, when you get to SF, you're at the ferry building where you can get tasty treats. See pics below.
I was commuting home from a friends house on Wednesday night and there was a big sign that said "Wet plates ahead". Just before there was one that said "Dirty Knives on Left" and after one said "Sporks in Road".
Our fave famers market still has strawberries. OMG, do they! Look at this huge one. Can you believe it's organic?
With the sunlight fading sooner and sooner each night, I'm going for more and more sunset rides. Here's another pic for the latest on Thursday night.
Finally, our venus fly trap is blooming! Fun.
Posted in Bikes, Food, Photos, PHP, Ramblings | Comments Off
Tuesday, September 29th, 2009
I've recently taken a serious look at the reality of theft of computers as well as ensuring privacy and reducing data loss should such a theft occur. Take a moment and and take inventory of where you store you data and how accessible and backed up it is. What would happen if:
- You dropped your cell phone in the toilet? (data loss)
- Your cell phone got stolen? (data loss & theft)
- What about that 'it will never be stolen' desktop computer at home? What if some one stole that? Do you have a password on login, do you have your email password saved and your browser remember all your passwords? Do you file your taxes online and store copies? Do have resume with references, previous address and social security number? (Data loss, theft, and loss of privacy)
With the sheer number of accounts we create at every new site we register with, we've become lazy and no longer want to remember passwords. Most folks either check 'remember password' in their browser of choice, use the same password for every site, write down the password or all three. Further, most folks don't password protect their smart phones. Compliment with all personal data stored on a laptop or a desktop, this creates a recipe for catastrophic data loss, serious violation of privacy potentially leading to identity theft.
In this post, I'm going to outline a number of suggestions to help fight data loss and identity theft while protecting your privacy. I'll give each suggestion a PITA rating of how hard and how long it will take to implement. A PITA of 1 is easy a PITA of 10 is, well a real PITA!
Master Passwords
PITA: 1
If there's one thing you actually do, do this one. I use both Thunderbird and Firefox. As I said, most folks are lazy and want all their passwords stored and remembered for them as needed. This is all fine and dandy until your laptop walks an the thief can use all your accounts with out ever touching the keyboard. Both Firefox and Thunderbird offer the ability to set a master password. Every time you open your browser or mail client and a password is needed, you will be prompted for a your master password once. Then all other passwords will be filled in for as normal. Note: close your browser and mail client often ; )
OS Level Passwords
PITA: 1
A no brainer. Both Windows and OS X (video) have it.
Set a phone password
PITA: 9, then less
When I first set a password on my phone it was a real pain in the ass. I had to enter it every time I wanted to make a call or check my email. I have a Palm OS phone (not a Web OS phone), so it's not that sophisticated. I know that Android based phones have a quick pattern you can trace which is quite easy. The iphone has a number pad you can use. Any which way, over time, this becomes second nature, so the PITA rating will fade from 9 to a lower number.
Remote Backup
PITA: 7
I'll explain my backup technique in a sec, but take this one seriously. If your house were to burn down while you were out of town, how much data would you loose? I hate to be all doom and gloom here, but most folks don't shoot analog any more, so all photos are digital. Maybe you upload to flickr or the like, but there's nothing like have all your photos organized just so. I strongly suggest you look at commercial providers for this.
Our household has both local and off site backup. We start by backing up all devices (two laptops and a desktop) to our local qnap server via robocopy (think rsync for windows). The qnap is just linux, so it runs all sorts of great things like rsync and secure copy (scp). A friend has a qnap as well. We first connected an external drive to our own qnaps and made a backup of all our backups. We then swapped external drives and connected them to our respective qnaps. We now have a remote backup that we can rsync our data to over ssh and the initial gigs of data are already there.
Remote, Secure Backup
PITA: 10
I have a subset of my data that is hundreds of PDFs. I generate them via my trusty and some what spendy sheet feed scanner. This guy creates searchable PDFs that have the OCR text embedded in them. Genius. In comes a bill, tax return or sensitive document, out comes a PDF and some shredded paper to recycle. Cross cut, of course.
This data set is a treasure trove. Should my desktop with hundreds of megs of PDFs walk out my front door one sunny afternoon in a thief's hands I'd be up you know what creek with out a paddle. Data loss aside, it would be little effort to apply for a credit card after a little address change. Bad times indeed.
Enter Drop Box. This is an excellent free service (for the first 2 gigs) that allows you to do what I would call very rich man's rsync. Store all your PDFs in this folder, and now they're not only backed up, but remotely accessible!
Wait – what about the stolen desktop? The default behavior of Drop Box is to remember your password. Should someone take your computer and gain access to it, the PDFs on Drop Box are good as local on the drive.
Now enter the second layer: TrueCrypt. TrueCrypt is the no-joke way to store data securely. They support both an encrypted boot drive as well as the spook spy stuff: plausible deniability. Ignoring the more advanced features, TrueCrypt's quick start guide will walk you through creating an encrypted volume that's encapsulated in a single file. This file can be any size, thus the drive can be any size. You could then store you hundreds of PDFs in a TrueCrypt volume in a file on Drop Box. True secure offsite backup.
I've even gone so far as to create a small TrueCrypt volume that has all my passwords. It's the keys to the kingdom, but I'm going to be vigilant about protecting this file and only the one closest to my heart knows how to get in there.
Caveat emptor
I'm not a security expert, take my advice with a big grain of salt. There are ways of hacking the master password for firefox and thunderbird. OS Level passwords are trivial to bypass for a skilled IT professional or evil intentioned googlist. Even TrueCrypt can be accessed via social engineering or a sloppy operator who writes down their password.
Good luck and happy securing!
Posted in Linux, PHP, Reviews, Tips | 2 Comments »
Tuesday, September 15th, 2009
I just spent some time trying to outrun my cobbler's child-dom by using mod_rewrite to make the old URLs for contact, about and projects pages to drop the oh so late 90's ".phtml" suffix. They turned out pretty great I think! mod_rewrite is worthy of a whole separate post, I'd say.
http://plip.com/contact
Along they way, I remembered that my contact page, simple as it is, was actually a target for spammers a couple times a week. Do they think I just fell off the radish truck? Silly geese. The solution of course is to use a captcha. There's a number of them out there, but a while ago I stopped rolling my own and started using Recaptcha. Aside from being super easy to install and deploy, you're helping their worthy cause. Sweet.
Now that you have your captcha stopping those geese from spamming you, you need to make it look like your site. Hours of hacking? Nope! Minutes of CSS stylings. Recaptcha is highly structured DOM with easy to reach classes for CSS. In just a few minutes I turned the the vanilla captcha into the the, well, even more vanilla plip captcha. OK, yes, I'm a geek who loves CSS. That's me.
-
- Plip Captcha
-
- Stock Factor Captcha
Posted in PHP, Tips | Comments Off
Tuesday, May 12th, 2009
After my friend over at The Worst Thing in the World (TWTITW) recently had a post about Radar charting a salad's many axes, I thought it'd be funny to write a page that actually made the graphs. I'd been meaning to write a post about using Maxmind's GeoIP library and data to do heat map of web activity, but this will be a good warm up. Behold the fully functional Plip Salad Tosser.
Let's take a look at the components of the Tosser:
The Chart: I like using APIs that are easy, make me look good, and are well documented. That's why I love Google's Chart API. For this page I used a their radar chart and referenced which features are available at the handy chart feature matrix. A few nice touches were adding the dotted lines and the extra data point to complete the loop (is a that radar chart faux pas?).
Arrays and quick forms: Arrays are really handy. They make a form like these easy to change and you can implode them like mad for loop-less string creation of chart labels and the like. Further, you can bust out a quick loop to check for posted values or init random values for the form. WAY easier than hard coding the HTML and making edits over and over again.
Final Product: Here's a salad radar chart made from step 3, Publish!

PHP: Here's the top part of the page which does the actual form processing and image source concatenating.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
| // seed all options
$options = array(
'Architectural',
'Conceptual',
'Cultural',
'Financial',
'Gustatory',
'Logistical',
'Taxonomic',
);
// see if they want a random one
if (isset($_POST['No,_no,_wait____toss_me_a_random_salad!'])){
unset($_POST['d']);
}
// hand POST or init
if (isset($_POST['d'])){
// grab vals if posted, pull name into local
// and unset name for easy imploding below
$postedAxes = $_POST['d'];
$name = $postedAxes['name'];
unset($postedAxes['name']);
} else {
// init empty chart
foreach ($options as $axes){
$postedAxes[$axes] = rand(1,100);
}
$name = "Random Chart";
}
// seed drop down vals
$i = 1;
while ($i < 101){
$dropValsRaw[] = $i++;
}
// build up form HTML by looping through
// every axes
$formHTML = "";
foreach ($options as $axes){
$formHTML .= '<label for="Architectural">'.$axes.':</label> ';
$formHTML .= '<select name="d['.$axes.']" id="'.$axes.'" />';
// loop through evey axes value and check for
// posted value so folks can easily tweak graphs
$i = 1;
while ($i < 101){
if ($i == $postedAxes[$axes]) {
$formHTML .= "<option value=\"$i\" selected >$i</option>";
} else {
$formHTML .= "<option value=\"$i\" >$i</option>";
}
$i++;
}
$formHTML .= $dropValsHTML;
$formHTML .= '</select>';
$formHTML .= '<br />';
}
// concat final img src and use
// implode along the way where needed
$imgSrc = "http://chart.apis.google.com/chart?";
$imgSrc .= "cht=r&chs=500x400&";
$imgSrc .= "chd=t:".implode(",",$postedAxes).",".array_shift($postedAxes)."&";
$imgSrc .= "chco=669933&";
$imgSrc .= "chls=2.0,4.0,0.0&";
$imgSrc .= "chxt=x&";
$imgSrc .= "chxl=0:|".implode("|",$options)."&";
$imgSrc .= "chxr=0,0.0,360.0&";
$imgSrc .= "chm=B,66993380,0,1.0,5.0&";
$imgSrc .= "chg=25.0,25.0,4.0,4.0&";
$imgSrc .= "chtt=$name"; |
HTML: Below the PHP I have some descriptive text and a few headers and then I output the fruit of our lil' scripts labor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| <H1>Salad Maker</H1>
<p>My friend over at <a href="http://twtitw.firebus.com/">The
Worst Thing in the World (TWTITW)</a> recently had a
<a href="http://twtitw.firebus.com/node/85">post</a> about the
axes of salad complexity. Based on their findings of 7 axes*,
I wrote a lil' form to enter and toss your own salad. Read
up on the code behind this page over at yon
<a href="http://plip.com/blog/toss-your-salad-code/">blog</a>
.</p>
<P>Go forth, make your salad, rate it, and use this form to
publish your salad's findings (or is that finding your
salad?).</P>
<I>* - Subject to TWTITW's whim and research</I>
<h2>Step 1: Data Entry</h2>
<form action="/salad/" method="POST">
<label for="name">Salad Name:</label>
<input name="d[name]" type="text" size="20" id="name" value="<?= $name ?>" />
<br />
<?= $formHTML ?>
<input name="Toss Mine!" value="Toss Mine!" type="submit"/>
<input name="No, no, wait....toss me a random salad!"
value="No, no, wait....toss me a random salad!" type="submit"/>
</form>
<h2>Step 2: Analize</h2>
<img src="<?= $imgSrc ?>" />
<h2>Step 3: Publish</h2>
<textarea cols="70" rows="7"><img src="<?= $imgSrc ?>" /></textarea>
<style type="text/css">label { display:block; width:150px; float:left; }</style> |
Final Thought: Projects like this that take about two hours are fun and very gratifying for me. Leveraging existing code bases like Google's Chart API is a great way to make a friend's funny blog post into a fun educational experience that looks snazzy. Send in questions or comments!
Posted in PHP, Tips | Comments Off
Tuesday, February 24th, 2009
Hi faithful readers! Notice anything different about the news on ol' plip? No? Probably not because there's been none since December of aught 4. It's no surprise no one noticed. However, to fight the stale news, encourage freshness, thus garner a new, rejuvenated mass of readers, old open source solutions have taken hold of news: WordPress on our LAMP stack running on Linux! Ok, the last two are not new, but WordPress is and all our news will live there.
On deck in the news section are geeky, bloggy types news: PHP tips and tricks, adventures and places to see, media consumed and ramblings. I guess the last one is redundant, as they'll all start to ramble.
To give you a taste, here's the PHP tip of the week: I used to use Magpie RSS to consume RSS feeds I wanted to re-syndicate on another site. Though it does have some nice features like normalizing different feed formats and using a cache file, it was a but heavy to just suck in some news for my own use. In this case, I wanted self syndicate to plip's home page. Enter the simplexml_load_string() function! I can grab the latest news at the top of my home page:
//prep loading blog contents
$blogURL = "http://".$_SERVER['HTTP_HOST']."/blog/feed/";
$blogRSSraw = file_get_contents($blogURL);
$blogXML = simplexml_load_string($blogRSSraw); |
And then further down, I can loop through all the entries and do a little formatting to output the latest news for y'all. Note that each child item (a blog post in this case) is it's own SimpleXMLElement object. Further note that each key value pair (eg title, date etc.) has a magic "to string" function (which as my co-worker and I found can do unexpected things if you're print_r-ing).
foreach ($blogXML->channel->item as $post){
print "<B><a href=\"".$post->link."\">".$post->title."</a></B>";
print "<I>".strftime ("%d %b %Y",strtotime($post->pubDate) )."</I><BR>";
print $post->description."<BR><BR>";
} |
This tricks works great if you're consuming search results from a Google Mini search appliance, which is where I first deployed this technique.
Posted in PHP, Ramblings, Tips | Comments Off
|
|