Corey Prophitt's Website

August 17, 2020

Bookmarklet fun, and Github's email privacy issue.

According to Wikipedia, bookmarklets have been around since 2001. The usefulness and popularity of bookmarklets has certainly waned in the last 20 years. Browser extensions have since grown in popularity and pretty much replaced bookmarklets. However, you can still create bookmarklets today and unlike browser extensions bookmarklets work in all major browsers (even mobile browsers).

The Github bookmarklet used on mobile Safari to find an email address.

I currently maintain a few businesses that rely on browser extensions to provide convenient functionality for our end users. We have had our fair share of issues with Google's web store as others have also experienced. I have been toying around with the idea of using a bookmarklet for the functionality instead. I was pleasently surprised with the viability of bookmarklets in 2020.

Bookmarklets have a lot going for them. Unfortunately (or, fortunately) bookmarklets have been stripped of some useful functionality. Due to a number of security issues and concerns most sites place content policies on their webpages. These policies make it impossible to contact an external website or service to load code or styles dynamically. Furthermore, bookmarklets have to adhere to URL length limitations for inlined JavaScript urls.

I tested two different bookmarklets. One with 110,000 characters and another with 45,000 characters. Chrome was able to create a bookmarklet for both. Firefox was unable to create a bookmarklet with 110,000 characters, but worked perfectly with the smaller bookmarklet. If you dig around the web you will find recommendations to create bookmarklets no larger than 2,000 characters. That seems antiquated, but it's generally a good idea to try an keep code minimal.

What does Github have to do with this?

Github has nothing to do with bookmarklets, but I wanted to create a bookmarklet to test various things like web requests, window manipulation and so on. Long story short, I decided to build a bookmarklet that works on Github profiles to demonstrate something that always irked me; Github's default privacy settings suck.

Github has an option to mask the email address used in your public commits. It's a great feature, but sucks because the masking is disabled by default. As a result the vast majority of Github profiles with public commits have exposed their email address(es). I am willing to bet most users don't even realize it.

I created a bookmarklet to demonstrate how easy it is to find a Github user's email address and you don't even need to be logged in to do so. Maybe this will convince some people to enable email masking, or at the very least shed some light on how recruiters find your email address and spam you.

If you are interested in the bookmarklet code, it's open source. You can find the code and build instructions here. Given how common content policies are these days, I suggest creating a bookmarklet only if the code you want to run is isolated to the active page and no external code or styles are required. Another useful use case is if the end result of your bookmarklet is a new window or tab (such as collecting and passing parameters into a url you control).

Using the Github Bookmarklet

There are two ways to set up a bookmarklet. The first and simplest way is to drag any bookmarklet link into the bookmark bar. The bookmarklet will be created automatically (here's mine: Githublet).

Alternatively, you can set up the bookmarklet manually. I recorded a demo to show how this can be done:

Here's the bookmarklet code for copying:

javascript:(function(){var name=document.querySelector(".vcard-fullname");var match=location.href.match(/github\.com\/([a-z0-9-_]+)/i);if(!name||!match||!match[1])return;fetch(""+match[1]+"/events").then(function(r){r.json().then(function(data){var emails=[];var seen={};var nameTokens=[];name.innerText.trim().toLowerCase().split(" ").forEach(function(n){nameTokens.push(n.slice(0,5))});data.forEach(function(e){if(e.type=="PushEvent"&&[1]){var email=e.payload.commits[0];if(!email.match(/noreply\.github\.com/i)&&!seen[email]){nameTokens.forEach(function(t){if(email.indexOf(t)>-1&&!seen[email]){seen[email]=true;emails.push(email)}})}}});if(emails.length)prompt("We found their email(s):",emails.splice(0,5).join(", "))})})})();

If you are interested in setting up a bookmarklet on mobile you need to follow the manual steps for your mobile browser.