This was originally posted on a website I was developing over a year ago called Keenotes.
I've been immersed in HTML since I first got a computer in 1999, and I've picked up a few tricks along the way (especially after I learned CSS). Here are a few of the ones I consider pretty interesting or useful.
Bypassing HTML Whitelists with CSS
Let's wind the clock back to 2008. There was a big explosive controversy over a UCF student named Webster Cook who took a communion wafer (eucharist) without eating it to show his friend. The Catholic community overreacted by trying to get him expelled for "religious intolerance," which provoked a nasty flamewar. At the center of this flamewar was a blog called Pharyngula, written by the outspoken atheist, PZ Myers.
Pharyngula was hosted on Science Blogs, which allowed anyone (at the time) to comment on blog posts (until they were locked by the blog author), but it only allowed certain HTML tags and would block out the rest. Of particular note, the
<img> tag was disabled, preventing anyone from posting images on Pharyngula.
A couple of months prior to this flame-war, Anonymous had initiated Operation Chanology which drew a lot of media attention and embedded 4chan and its offshoot imageboards into the forefront of cyber-culture. By now, posting image macros in response to another commenter was something many were used to (myself included). But there was no way to post the image, and just typing a hyperlink that other readers would have to click on to see was unsatisfactory.
So I did what any good computer geek fresh out of high school would do: I toyed with the system to look for a way around it.The first step with any hack (whether benevolent, benign, or malicious) is to do some poking around. I tried to change my text to be blue and bold, and it worked:
<p style="color: #00f; font-weight: bold;">Test</p>
So it seemed that there was nothing blocking the style="" attribute from the allowed HTML elements. Bingo. So the next thing to test was if a background image would be caught by the filter:
<p style="background-image: url(http://offsite-location/file);"></p>
And nothing appeared. So I thought, "That's discouraging, I'll have to try to play around with URLs to the same website," and tried to embed images hosted by Pharyngula in my post. No dice. At this point, I was considering giving up and finding something better to do with my time when I realized, "Wait, it's an empty paragraph tag! Of course nothing is going to display." So I gave it some definition:
<p style="background-image: url(http://offsite-location/file); width: 640px; height: 480px;"></p>
... and it worked. Presto! One image, coming right up, served piping hot to a comments box near you.
But let's say it hadn't worked (if Science Blogs blocked url(http) inside of style="" attributes) and I had the knowledge and experience I have now. Could it still have been pulled off? Possibly, but if it did, it would function at the cost of increasing the bandwidth of the blog by a substantial amount.
First, you would need to base64 encode the PNG binary (for example):
<?php // Base64 Encode an image // Written by Scott Arciszewski // USAGE: // Command line: php thisFile.php localfile // Website: http://localhost/thisFile.php?file=localfile // Restrictions: Doesn't support directories header("Content-Type: text/plain"); $file = str_replace('/', '', ($ARGC > 1)?$ARGV:$_GET['file']); ob_start(); echo file_get_contents($file); $b64 = base64_encode(ob_get_clean() ); exit;
Then, you would need to make your embedded code look like so:
<p style="background-image: url(data:image/png;base64,CODEHERE); width: 640px; height: 480px;"></p>
If their filter blocked http:// requests in CSS (which is reasonable), then this would still allow you to bypass the filter and embed your image on the page.
Fix an Image's Size without Distorting the Aspect Ratio
This one's a little less involved, but could be combined with the above technique (using CSS's background-size property).
Let's say you've taken a bunch of pictures with a webcam and want to embed them on a webpage in a table. Simple enough, yes? But a common problem that people run into is that they crop pictures to different dimensions. This creates two issues:
- If the pictures are left as-is, the table breaks and it looks horrible.
- If the pictures are resized to a thumbnail size, then they look distorted and ugly.
The solution I use is to fix the height and set a maximum value for the width. So each picture might look like this:
<img src="/file01.jpg" style="height: 90px; max-width: 160px;" />
An image with a 16:9 aspect ratio will display as 160 x 90 pixels; an image with a 4:3 aspect ratio will be 120 x 90. Now all you have to do is center them in their table cells and everything looks a lot prettier.