# Git-Privacy ## _Because Git's defaults are bad for your privacy_ --- ## ❌ Default Git Privacy ❌ Git has a _major_ privacy problem. With only 3 commands _anyone_ can find out the times and dates (down to the second) someone worked on their Git repo. ``` git clone cd git log --format=fuller ``` An unmodified Git repo reveals too much about a developer's life. It reveals what dates and times they made commits and when those commits were modified. Based on that, with some inference techniques, others can deduce when the developer sleeps, their range of likely timezones and roughly how efficient they are as a developer. Combined with other data sets, Git poses a serious privacy issue. ## 📅 Git Timestamps 📅 [Git commit objects](https://mirrors.edge.kernel.org/pub/software/scm/git/docs/user-manual.html#commit-object) have exactly 2 (sometimes 3) timestamps to worry about. I'll get to the 3rd later. Here are the 2 main ones: - `GIT_AUTHOR_DATE` represents the time and date the _changes_ were made, not the _commit_. - `GIT_COMMITTER_DATE` represents the time and date the changes were _committed_. #### Removing Timestamps For Commits Git doesn't have a way to _remove_ timestamps, but both the `GIT_AUTHOR_DATE` and `GIT_COMMITTER_DATE` can be set to any arbitrary date. For instance `1 Jan 2000 at midnight`. This gives maximum privacy. Simply set `GIT_AUTHOR_DATE` and `GIT_COMMITTER_DATE` in your shell's environment variables. For Bash: ```bash export GIT_COMMITTER_DATE="2000-01-01 00:00:00+0000" export GIT_AUTHOR_DATE="2000-01-01 00:00:00+0000" ``` To make the changes permanent in bash, append the commands to ~/.bashrc: ```bash echo -e "export GIT_COMMITTER_DATE=\"2000-01-01 00:00:00+0000\"\nexport GIT_AUTHOR_DATE=\"2000-01-01 00:00:00+0000\"" >> ~/.bashrc ``` However, if necessary it's just as simple to set both the `GIT_AUTHOR_DATE` and `GIT_COMMITTER_DATE` to the real date without the seconds, minutes and hours. This provides greater privacy yet still meaningful timestamps: ```bash export GIT_COMMITTER_DATE="$(date +%Y-%m-%d) 00:00:00+0000" export GIT_AUTHOR_DATE="$(date +%Y-%m-%d) 00:00:00+0000" ``` To make the changes permanent in bash, append the commands to ~/.bashrc just as before: ```bash echo -e "export GIT_COMMITTER_DATE=\"$(date +%Y-%m-%d) 00:00:00+0000\"\nexport GIT_AUTHOR_DATE=\"$(date +%Y-%m-%d) 00:00:00+0000\"" >> ~/.bashrc ``` Environment variables don't change after they're set. Therefore the date updates when you open a new shell, not upon a new day. #### 🔑 Removing Timestamps for Digital Signatures 🔑 It's important to digitally sign Git commits and especially releases to prevent man-in-the-middle attacks. These signatures contain their own timestamps which can be just as bad for privacy as Git timestamps, especially if every commit is signed. To automatically 'remove' timestamps in Gnupg signatures in new Git commits, the system time needs to be faked. Luckily Gnupg has a flag for just that: `--faked-system-time `. Git needs to run a version of the Gnupg program that _always_ fakes the system time. To accomplish that a bash script can be placed somewhere in `$PATH`, for instance `/usr/bin/gpg2-git`. `gpg2-git` should contain: ```bash gpg2 --faked-system-time ! $@ ``` The `` time can be any time _after_ the signing key was generated. For reference, my iso value is `20201130T000000` (30 November 2020 at midnight). My key was created 29 November 2020. For enhanced privacy, exclude Gnupg version number and comments from signatures in `/usr/bin/gpg2-git` with: ```bash gpg2 --faked-system-time ! --no-emit-version --no-comments $@ ``` And don't forget: ```bash chmod +x /gpg2-git ``` Finally, to make Git use the new gpg2-git program, add the following lines to `~/.gitconfig`: ``` [gpg] program = gpg2-git ``` Done. Git will now use a fake system time for every signed commit. [Git preserves almost no metadata](https://git.wiki.kernel.org/index.php/ContentLimitations) by design, so privacy is looking pretty good. ## 📝 Additional Notes 📝 The most popular code hosting platform Github is known to record [when commits are pushed](https://api.github.com/repos/cirosantilli/china-dictatorship/events). See the ticket about [Github contribution activity](https://github.com/isaacs/github/issues/142). Push times aren't really exclusive to Github. It's _possible_ that other code hosting platforms track them outside of the public API. It's easy enough for anyone to crawl a public repo and track push times anyway. Unless the developer controls the code hosting platform then they can't know for certain whether push times are being tracked. The easiest way to resolve this is _don't push any code manually_. Instead use a cron job that pushes all repositories to the remotes automatically at midnight. Environment variables may seem a very _crude_ way to obfuscate Git timestamps. It's possible to use Git hooks to accomplish timestamp obfuscation, but it doesn't work very well since it's still necessary to manually override the date for some Git commands. Git developers need to make timestamp obfuscation a feature of Git to finally resolve the privacy problem. ## License This README file is also licensed under [CC-BY-SA 4.0](LICENSE.txt).