P'unk Avenue Window

Archive for ‘Uncategorized’

Security hole in Mobile Safari PDF support a bigger story than jailbreakme

August 2nd, 2010 by Tom 2 Comments

The buzz today is that a new site, jailbreakme, will jailbreak your iPhone without the need to install any software on your host computer.

What’s bizarre about this is that everyone thinks it is cool and no one is pointing out that this site must be exploiting a truck-sized security hole in Mobile Safari.

Understand this: if jailbreakme can take over your phone, then any website run by a malicious hacker with skillz can take over your phone and run executables that do anything it pleases. This is very bad and Apple needs to issue iOS 4.0.2 today.

Of course, when they do, people will accuse them of being meanies, completely missing the point that exploitable browser bugs are extremely dangerous and are not always used to do cool stuff by nice white-hat hackers.

As one friend tweeted back, “not from what I understand. It just dls a package that that then, as allowed, unpacks and runs. It’s basically a web app.”

No, it is not a web app! A web app is something that stays in your browser and goes away when you close the page. Taking over your entire phone’s operating system is not how a web app behaves. It is the reason why we patiently tell all of our friends not to install .exe files people email to them.

Alas, now iPhone users are so trusting that if Mobile Safari allows something to happen, they assume it must be intentional.

Just because this particular site delivers what it says it will deliver and even asks nicely doesn’t mean that other sites exploiting the same hack must be innocent or will ask at all before installing malware on your phone.

But what is the security hole? Apparently it’s PDF-related. I ran the source code of www.jailbreakme.com through a couple of prettyprinters and tracked down this snippet determining what page it loads in an iframe:

("/_/" + model + "_" + firmware + ".pdf")

Apparently Apple’s PDF viewer on the iPhone has a security hole that allows native code to be loaded and run. This is not awesome. Raising the profile of an exploitable security hole before Apple has a chance to fix it is not awesome either as it will lead to innocent people getting their phones hacked.

This is a Big Bug, and hopefully Apple will patch it before the week is out.

Happy Birthday to Us!

April 1st, 2010 by Tom 5 Comments
P’unk Avenue is five years old today!

In honor of this momentous occasion, we’ve reshuffled our roles.

Effective immediately, I (Tom Boutell) am the lead designer.

As my first official act, I’ve changed our default font here on the window blog to the timeless and brilliant Comic Sans.

Rick has also changed jobs. Please welcome him as our lead developer. I’m informed that he plans to switch us all over to Visual BASIC .NET immediately. The goal is to recreate Drupal in Visual BASIC. In the meantime we’ll be porting our Apostrophe sites to Drupal as a transitional step.

Geoff is already happy in his role as chief compost engineer, and we aim to keep him that way. Jake will be making a lateral move from designer to chief executive, and Dan will be our business development lead. He plans to win new clients to our cause by explaining the Symfony embedded forms API to them, drowning them in source code until they surrender one by one.

Alex and John have announced plans to open a bakery producing exclusively apostrophe-shaped cookies.

Just kidding, dear friends. Would we do such terrible things to you?

Beware of Geeks Bearing Gifts

March 11th, 2010 by Tom No Comments

@odysseus is now mayor of Shiny Wooden Horse Disco Everybody Come Check It Out! on #foursquare!

@agamemnon just checked in from Shiny Wooden Horse Disco Everybody Come Check It Out! via gowalla

@cassandra IT’S A TRAP!

@priam @cassandra SHUT UP ADMIRAL AKBAR THIS HORSE IS AWESOME

@agamemnon is now mayor of Sacked Ruin of Troy BOOYEAH! on #foursquare!

Tonight: toast the Spirit Mars rover!

January 27th, 2010 by Tom No Comments




After exceeding its 90-day mission by SEVEN. FREAKING. YEARS, the Spirit Mars rover is permanently stuck. So sad!

Yes, they plan to do some stationary science work with it when the winter is over, but let’s face it… this is the end.

Philadelphians, please join me tonight at 7pm at National Mechanics (*) to pour out a drop for our fallen robot homie!

To be followed, no doubt, by watching the State of the Union address. Which might even touch on space policy for once.

Let’s give Spirit a Viking funeral! (**)

(*) 3rd between Chestnut and Market if anybody doesn’t already know.
(**) Failure to get this joke is punishable by deportment to the Phobos reeducation camp.

svncampfire: svn commit notices in campfire, take 2

December 18th, 2009 by Tom No Comments

screenshot of svncampfire source

Using svn for version control? Have lots of repositories you’re interested in? Maybe some of them aren’t under your control, so you can’t set up postcommit hooks?

Check out svncampfire (literally… haha, see what I did there). svncampfire pastes svn commit notices into your Campfire chatroom.

We’ve just released version 1.1, which supports the new official 37signals API for campfire. It’s a great API, much more fun than screenscraping; I chose the JSON flavor because it’s so darn easy. Version 1.1 also adds friendly labels for commits from each distinct repository so it’s easier to see what is going on.

Right now svncampfire is monitoring over half a dozen repositories for us, all thanks to the magic of svn log --xml.

Dear Gmail: let us map filters to “From” addresses

December 2nd, 2009 by Tom No Comments

Dear Gmail,

labels.
multiple “From:” addresses.
Now, please let me select a default “From:” address when replying to messages with a particular label. Then I can manage my various secret identities business roles with a much lower rate of accidental goofage.

Yours in the wearing of many hats,

Tom “tommybgoode P’unk Avenue Boutell.Com salsadelphia.com” Boutell

UX Show & Tell

November 9th, 2009 by Geoff 2 Comments

Please join us at P’unk Ave for a UX Show & Tell workshop hosted by Chris Avore.

From the UX Show & Tell website:

UX Show and Tell is a casual workshop that’s all about the work, where you get feedback on your UX, IA and IxD deliverables from practitioners instead of stakeholders.

Because let’s face it: even the most involved practitioners of the UX community have few places to share work with other helpful colleagues in a face to face environment.

Even if you don’t have something to show, help your fellow IA’s, designers, and researchers by sharing solutions with those who are showing work.

We’ll supply the tomato pie if you bring the deliverables!

UX Show & Tell at P’unk Ave
Wednesday, November 18th @ 6:30pm
1168 E. Passyunk Ave [map]

A better strip_tags: pkHtml::simplify

September 21st, 2009 by Tom No Comments

Many web sites allow users to edit content via a rich text editor. And we all know what happens if the user pastes a Word document in there: the styles of the page wind up hopelessly munged. PHP coders can use strip_tags() to limit the HTML tags that get pasted in, but that doesn’t clean up the CSS style attributes that can be pasted in. So your page is still a mess. Often it is so broken that the user can’t figure out how to edit again. This is the point where they pick up the phone and plead with you for help.

strip_tags also won’t help if the HTML is invalid. Unclosed tags can create nightmares elsewhere in the page when users are allowed to submit snippets of HTML that leave a bold tag or a header tag unclosed.

A common workaround is to use the FCK (aka CK) rich text editor’s “paste as plaintext” mode, which thwarts attempts to paste rich text from another program. That works, after a fashion, but users are forced to do all of their styling all over again. Bold, italic and bulleted lists must be recreated from scratch.

And none of the workarounds are sufficient if you can’t at least trust the intentions of your users. This is not a problem when your client logs in to update his site, but it’s a big issue when his customers are creating personal profiles and the like.

HTML Tidy can tackle this sort of filtering for you, but it is often not included in your build of PHP as it is not standard equipment (although some Linux distributions do include it in the box). This is especially important on client sites where you’ve been asked to live with the setup that is available.

HTML Purifier does much the same thing in pure PHP, but since it parses the document directly in PHP it is a bit slow and heavy. Which makes you long for the raw performance of strip_tags.

Enter pkHtml::simplify():

pkHtml::simplify($richTextHTML,
  "<h3><h4><h5><h6><blockquote><p><a><ul><ol><nl><li><b><i>" .
  "<strong><em><strike><code><hr><br><div>" .
  "<table><thead><caption><tbody><tr><th><td>");

If that looks a lot like the arguments to strip_tags(), you’re right. That’s because pkHtml::simplify() uses strip_tags() as a starting point. But pkHtml::simplify() follows up strip_tags() with a DOMDocument-based filter that removes attributes too, except for the attributes that actually make sense to permit for certain tags. That is, if you are permitting the tag at all, you need those attributes for it to be useful.

Currently these tags are:

A tag -> href and name attributes
img tag -> src attribute

If you’re coding for Symfony, you don’t have to call pkHtml::simplify() directly. Instead, you can use the sfValidatorHtml validator, also found in pkToolkit, which allows the above list of tags by default because they are well-suited to user-entered content. For the convenience of Symfony developers we also package Dominic Schierlinck’s sfWidgetFormRichTextarea widget in pkToolkit. It’s meant to be compatible with both MCE and FCK, although we always use FCK.

pkHtml::simplify is short and sweet because it uses the most straightforward tool for each job. For removing disallowed tags, nothing beats the raw speed of strip_tags. But strip_tags doesn’t know anything about attributes, so for that purpose we use DOMDocument. Many PHP developers aren’t yet familiar with this class, which is standard equipment in PHP 5.

DOMDocument has three great features from our perspective: it can clean up HTML automatically, ensuring that tags are closed. And it lets you manipulate attributes painlessly. And since it is built into the core of PHP, it is much faster than parsing HTML “from scratch” in PHP.

DOMDocument does want to give you back a complete HTML document with nifty things like a document type and html, head and body elements that we don’t need when we’re manipulating snippets of user-entered HTML, not truly complete pages. So pkHtml::simplify optionally undoes that for you, leaving you with an HTML container element that’s ready to snick into place in the middle of your page body.

So: how good is the performance of pkHtml::simplify? Very good indeed. On one project we need to separately clean hundreds of untrusted potential HTML containers in a single XML document, in real time, before presenting portions of that information to the user. pkHtml::simplify has no trouble keeping up in this scenario.

Our Apostrophe CMS takes advantage of pkHtml::simplify() to allow rich text editing without the constant “oops I screwed up my site” issues that come up without a robust server-side filter.

pkToolkitPlugin is available from the Symfony repository and is released under the open-source MIT license. Keep in mind that the pkHtml class is useful to all PHP developers, not just Symfony developers. Just download the tarball and copy it from the lib folder.

I recommend picking up the latest version of the code from svn. You can also use the tarball versions, but you may need to remove a few Symfony logging calls to use it in a non-Symfony context.

How to add ON DELETE CASCADE to an existing MySQL table without dropping any existing data

May 27th, 2009 by Tom No Comments

You created a MySQL table with a foreign key reference… for instance, a user_id field that refers to a separate table of users.

Then you realized you should have specified “ON DELETE CASCADE” when creating the table. Now, when you try to delete a user, you can’t because objects in the other table are still referencing that user object. Ouch.

What to do, what to do!

Do this (substitute your table and column names, of course):

SHOW CREATE TABLE pk_context_cms_access;

Note the name of the foreign key constraint, which is usually automatically generated, and looks like this:

CONSTRAINT `pk_context_cms_access_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sf_guard_user` (`id`)...

Now drop the foreign key constraint. Relax! You’re not dropping the column involved, so you’re not losing any data. You’re just giving up the integrity check that makes sure foreign IDs refer to stuff that really exists and prevents you from deleting records unless you have set ON DELETE CASCADE… which is probably why you are reading this. (This will temporarily relax referential integrity requirements. In English, that means you should probably temporarily disable the site while blasting through these steps, if it serves billyuns of people every micro-moment.)

alter table pk_context_cms_access drop foreign key pk_context_cms_access_ibfk_1;

Now add the foreign key constraint back again, this time with ON DELETE CASCADE:

alter table pk_context_cms_access add foreign key(user_id) references sf_guard_user(id) on delete cascade;

Boom. Check “show create table pk_context_cms_access” again to see that it worked:

CONSTRAINT `pk_context_cms_access_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sf_guard_user` (`id`) ON DELETE CASCADE...

Now buy me a beer.

How to open Google Calendar (or any URL) on your Mac at scheduled times of day

May 14th, 2009 by Tom 1 Comment

We make heavy use of Google Calendar here at work. Unfortunately I rarely remember to look at it unless an alert has specifically been set up to get my attention.

This morning I set up my Mac to open Google Calendar in my web browser every day at 10:15am.

How do you do that? Turns out it’s not hard.

You can open a URL at the terminal command line—

“Whoa! Did you just say ‘terminal command line?’ I thought you said this wasn’t hard?”

Well, it isn’t! All you really need to know about the terminal application is this:

1. It’s not hard.
2. Go to the Finder, click “Applications” (at lower left), open up “Utilities” in the pane at right, and then double-click “Terminal.” Now you have a terminal window to type commands in.
3. After each terminal command, one generally presses the Enter (return) key. So if I say nothing to the contrary, assume you’re meant to do that after each command.

You can open a URL in your web browser from the terminal command line by typing a command like this. Just copy and paste your Google Calendar’s URL from the address bar:


open 'https://www.google.com/calendar/hosted/punkave.com/render?tab=mc'

(Note that if your URL actually contains the ' character you’ll need to escape it with a \ in front.)

OK, you’ve opened a web page from the command line. Now, how do you schedule that to happen every day?

Luckily the Mac, like any good Unix box, offers a utility called cron which does things for you at scheduled times. To set that up, all you have to do is edit your cron jobs with the crontab command…

But this part is a little bit of a PITA: by default, the crontab command opens your cron jobs file with vi, an old-school Unix text editor. I’m happy with it, but you don’t need to be. So I’m going to first walk you through how to switch things around so that crontab opens things in good old TextEdit.

I’ll also show you how to set up a convenient command you can use in the terminal window to edit any file with TextEdit from the command line.

We’ll start by editing your ~/.profile file. This file contains commands that the terminal window runs when you first start it up.

First, use the touch command to ensure the file exists. TextEdit doesn’t like being asked to edit files that don’t yet exist:


touch ~/.profile

Now try this command (hint: don’t suffer, copy and paste it into terminal):


/Applications/TextEdit.app/Contents/MacOS/TextEdit ~/.profile

Your .profile file is open in TextEdit. This file contains Unix shell commands that should be run every time a new shell window opens for you. At first it will probably be empty.

Add these lines at the end of the file (which might be empty to start):


# Use TextEdit for crontab and similar commands
# that want to use your default editor
export VISUAL=/Applications/TextEdit.app/Contents/MacOS/TextEdit
# Use TextEdit when you type: edit filename
alias edit='/Applications/TextEdit.app/Contents/MacOS/TextEdit'

The lines that begin with # are comments and the command shell will ignore them. I provide them so you can remember why you did this stuff later.

A word of warning: when launched this way, TextEdit tends to open behind the terminal window. You might have to apple-tab around a bit to find it.

Finally, close your terminal window and open a new one. This ensures that the commands in ~/.profile have been run. Alternatively you can use this command to run the commands in ~/.profile in your current terminal window:


source ~/.profile

Now we're ready to edit your cron jobs... in TextEdit, not vi. At the terminal prompt, type:


crontab -e

And paste in this line (but substitute your Google Calendar URL of course, copied and pasted from your browser):


15 10 * * * open 'http://your.url.here/'

Then save your work and quit TextEdit. The crontab command can't continue until you quit TextEdit.

Now the URL you've pasted in will open every day at 10:15am. If Firefox is your default browser, it will open in a new tab. I haven't tried this with Safari as the default browser. Freel free to enlighten me as to how that works out.

What are those numbers and stars about? They represent minutes, hours, days of the month, months, and days of the week. We are only concerned with the first two: we want the job to run at 10:15am. If you want to run the job in the afternoon, be sure to use 24-hour time (for instance, set the second number to 13 for 1pm).

cron can do quite a bit more. If you want to know more about scheduling cron jobs, try this command:


man 5 crontab