Before you go, check out these stories!

0
Hackernoon logoHow to Hack GitHub (kind of) by@priansh

How to Hack GitHub (kind of)

Author profile picture

@prianshPriansh Shah

A commit a day keeps the bugs away! But we’ll be doing 100 commits a day.

It’s no secret that GitHub’s contribution chart isn’t very secure. In fact, by pushing a repository with pre-configured commit history, you can gain the commits as contributions.

I love coding. I really do. And I really love open source. When I started out, open source was my favorite thing to do: build software, release it for everyone, and contribute to others’ projects.

It’s something I still love to do, but it’s something I’ve been forced to sacrifice. Recently, I started working fulltime on Aiko AI, a startup aiming to bring the benefits of advances in AI to the general public by integrating them into everyday products. We’re behind popular products like Aiko Meet and Aiko Mail and our recent success has meant that I have had less and less time to do open source work.

Unfortunately, this means I had to choose between my passion for Aiko and my love for open source. I’ve continued to work on open source projects every now and then, but Aiko has taken priority, and that means I can’t commit with the frequency I used to.

And that means my contribution chart will dry up — unless we fill it up with commits 😉

Sneak peek of my contribs chart in 2 months

For those of you who don’t frequent GitHub often, the contribution chart tracks your commits on a daily basis to see your coding activity/cointributions to open source over time. It is simultaneously the weirdest of all flexes and a nice little trophy to show for your open source efforts.

So much so that even some employers will look at your GitHub contribution chart to gain an idea of just how much of an avid coder you really are. Of course this isn’t really a reflection of your coding ability; you may not use GitHub often, or you may be developing mostly closed source. Perhaps you’re in a role where you commit infrequently but with large features/heavy loads. Or perhaps you look to this chart and feel a sense of insecurity as you think, all my friends have more GitHub commits!

Whether it’s necessity, curiosity, or impostor syndrome that motivates you, there’s an easy fix to this — just get a bunch of open source commits!

Of course this would take time and you can’t go back and edit your history — or can you? I’m going to be showing you how to hack GitHub’s contribution chart, and get that green pasture you yearn for so much.

Pictured: the hacker known as _____

Before I get started I’ll point you towards Gitfiti, another project based on the same system that lets you draw art on your GitHub contributions.

Rather than art, we’ll focus on commit history to gain fraudulent commits! I’ll try my best to explain what I can about bash, but this assumes some familiarity with terminal and git— if you’re not comfortable with a CLI, I recommend you check out Bash Academy before diving into this.

Just want the script? Here it is.

Don’t want to code? Check out Github Gardener, a free to use website that’ll help you out!

How It Works

Exploiting commit history we can “author” commits using git’s commit timestamps.

Let’s start by authoring one commit at a date of our choice. To accomplish this we’ll need to change two environment variables that git uses to set the commit timestamp, GIT_COMMITTER_DATE and GIT_AUTHOR_DATE. These two variables hold standard YY-MM-DD HH:MM:SS ISO format timestamps. We’ll also commit on that timestamp to cover all the bases — this way we can be completely sure that there is no way to differentiate our fake commit from one actually at that point in time.

export Y = 2000
export M = 12
export D = 20
export GIT_COMMITTER_DATE="$Y-$M-$D 12:00:00"
export GIT_AUTHOR_DATE="$Y-$M-$D 12:00:00"
git commit --date="$Y-$M-$D 12:00:00" -m "Committed on $M $D $Y"

This above snippet will “author” a commit from 12/20/2000. This can also be extended to “author” a commit from, say, 1/1/1970; way before you could have possibly coded this! As a result, your “git” history is vulnerable (and not, in fact, a “history”, it’s more a collection of pre-authored structures).

Write your own history! Didn’t turn out so great for Churchill though…

We can then extend this to author a commit history every day from a set date. This is trivially achieved using a bash for loop, with structure:

for VAR_NAME in {start..end}

The indented block following will be able to use $VAR_NAME as a variable in its execution. As a result, bash for loops become ideal for us as we can iterate through years, months, and days, to author fake commit histories.

Let’s Make A Script

The final version of this script is available as a Gist here.

We can achieve this “exploit” by looping through years, months, and days in that order:

for Y in {1999..2018}
for M in {01..12}
for D in {01..28}

We loop through every year from 1999 to 2018 (I chose 1999 as a guess pre-2000). We then loop through each month, and finally each day. Note that we only loop from 1 to 28, as February can be a 28 day month! We could loop through every day if we wanted to, but it wouldn’t be valid for February; in this case you can use a conditional to select the days. Another approach I’ considered is using Python to set the year, month, and day to weekdays in order to choose only working days — whichever you pick is up to you! I’ll stick with 1–28 as this works the best from a speed perspective (it can take some time to author this many commits).

We also need to create a new file each time:

echo "Committed on $M/$D/$Y" > commit.md

Here’s a completed script to just create files and commit them en masse:

for Y in {1999..2018}
do
mkdir $Y
for M in {01..12}
do
cd $Y
mkdir $M
cd ../
for D in {01..28}
do
cd $Y/$M
mkdir $D
cd $D
echo "Committed on $M/$D/$Y" > commit.md
cd ../../../
export GIT_COMMITTER_DATE="$Y-$M-$D 12:00:00"
export GIT_AUTHOR_DATE="$Y-$M-$D 12:00:00"
git add $Y/$M/$D/commit.md -f
git commit --date="$Y-$M-$D 12:00:00" -m "$M $D $Y"
git push origin master
done
done
done

This will then author commits from 1999 to 2018. You can execute this from any bash prompt--I recommend placing it in an executable bash file and running that.

But this is clearly extremely slow! How can we make this faster?

  1. First off, unless you have nested git repos, we don’t need to traverse back up the directory tree each time we commit.
  2. It also turns out that the “push” to GitHub doesn’t take into account the timestamps present (hence allowing you to push your old local git repos to GitHub), so we can just push at the end of our script.
  3. Lastly, while not really a speed enhancement, adding support for days 29 through 31 doesn’t really affect our performance anymore with the above improvements, and GitHub will sanitize extra days automatically.

This increases the speed tenfold, and we can reach greater heights by pushing at the end.

for Y in {1999..2018}
do
mkdir $Y
cd $Y
...
git add commit.md -f
git commit --date="$Y-$M-$D 12:$i:00" -m "$i on $M $D $Y"
done
cd ../
done
cd ../
done
cd ../
done
git push origin master

Implementing these changes, along with removing the folders at the end for cleanup, we arrive with the final script:

You’ll notice I’ve introduced another bash loop with variable i — this controls how many commits are made each day, and can be used with this much, much faster script. If you get an “invalid” date format error, please check you’re using a date that exists after computers (the earliest date you can do is January 1, 1970), and that your version of bash is new enough to support leading zeroes in for loops.

The neatest part about this is that it authors commits in the FUTURE. 
This means that in the future you will have a commit every day!

I’ve put the completed script here. (shortlink: git.io/vxnon)

Example Run-through:

priansh@laptop:~$ cd ~/Documents/github
priansh@laptop:~$ mkdir gitsploit # make the repo folder anywhere
priansh@laptop:~$ cd gitsploit && git init
priansh@laptop:~$ # Next we'll set up tracking a GitHub repo
priansh@laptop:~$ git remote add origin <YOUR GITHUB REPO LINK HERE>
priansh@laptop:~$ echo "Hello World" > README.md && git add --all
priansh@laptop:~$ git commit -m "init" && git push -u origin master
priansh@laptop:~$ wget https://git.io/vxnon -O a_million_commits.sh
priansh@laptop:~$ chmod a+x a_million_commits.sh # make executable
priansh@laptop:~$ ./a_million_commits.sh

Post-Mortem

I’ll mention that GitHub can also be further exploited using bots (as they have no captcha!) and used for stars, follows, and more, although I won’t cover that in this quick article (nor do I encourage this as it borders on malicious).

Just a quick pic to prove this works:

20k commits!

You can delete the repo you’re committing to in order to remove the fake history, or make it private and set contribution settings to public only, to accomplish the same effect as removing the fakes from your chart. (You can also overwrite the branch/commit history entirely.)

While we’re not exploiting GitHub in a malicious way, this is still somewhat significant as some companies check your contribution count in the hiring process — meaning this could (potentially) affect your chances of landing a job. It will also make you the coolest kid at recess. Happy “hacking!”

Like this, and more? At Aiko AI, we love open source projects and exploring and visualizing data!

Tags

The Noonification banner

Subscribe to get your daily round-up of top tech stories!