Sharing Links From iOS Twitter Appends Garbage To The URL

There’s been a change to the official Twitter app in the last few months that affects anyone who tries to share a URL from inside the app. Using the standard activity view controller, recognised as the system share sheet, the Twitter app surreptitiously appends some query string parameters to the original URL.

The query parameters are effectively garbage to end-users that have no utility to anyone but Twitter itself. There’s honestly not much Twitter can do with it either apart from some very coarse tracking of user behaviour.

If the user commits to sharing the URL without amending the link, Twitter can see that its iOS app was the origin of the engagement if that URL is posted publicly.

Query parameters are just plain text. They can’t snoop in iMessage conversations or your private email. If someone re-shares the link to a public website or social network post, then theoretically Twitter knows that at some point that URL was made from its iOS app.

Here’s an example of an URL that Twitter mangled when I shared my profile in the Twitter app to the Messages app.

http://twitter.com/bzamayo?ref_src=twcamp%5Eshare%7Ctwsrc%5Eios%7Ctwgr%5Ecom.apple.UIKit.activity.Message

Focusing on the query string only, the bit after the question mark, the weird percent signs look scary but that’s just an artefact of forming a valid URL. The entities can be easily decoded to give a relatively human readable result:

ref_src=twcamp^share|twsrc^ios|twgr^com.apple.UIKit.activity.Message

It’s not hard to see here what information Twitter is trying to attach to the original URL; the action came from a share sheet on iOS, and it was shared to the Messages app extension. The bit after the ‘twgr^’ is the activity type of the particular share action selected.

Whilst there isn’t a directory of activity types to lookup, it’s not hard to track them down as they start with the app bundle identifier. Apple provides a bunch of built-in ones with the com.apple.UIKit.activity prefix and third party apps tend to use obvious names. If you share to Bear, the string will literally contain the words ‘Bear-iPhone-Sharing-Extension’. One of the more obtuse ones I’ve seen is com.tinyspeck.chatlyio.share … but a quick Google search reveals that it represents the Slack sharing extension.

The fact that the last component changes dynamically based on what action the user selects feels invasive if you don’t know what’s going on at the API level. Users are told that the activity share sheet is managed by Apple so instinctively it feels like being able to grab the activity type is nefarious.

In reality, this is very easily achieved. As part of the activity provider API, the system asks for content to share for each sharing extension the user has installed. The Apple framework openly passes the activity type to the app. Twitter simply takes the base URL it wants to share and appends the ‘garbage’ before returning.

If you are interested in the technical implementation, here’s a working code snippet. Even if you are not a programmer, the brevity highlights that there isn’t anything fancy going on here.

The important thing to note here is that the mechanism is innocuous and uses valid APIs provided by Apple. Twitter is not exploiting private APIs to achieve this. A cursory look at the app review guidelines suggests to me there are no grounds for Apple to scold Twitter (or any other app) for doing it.

My personal stance is that this is annoying but does not violate user privacy. Importantly, Twitter cannot append arbitrary information to its URLs system-wide; it is confined to cases where users share something from inside the Twitter app itself. I don’t really see a justification for Apple to amend the guidelines to disallow it. I just take it as another reason not to use the official Twitter app.