Skip to content

Instantly share code, notes, and snippets.

@FlorianFranzen
Last active March 5, 2020 09:35
Show Gist options
  • Save FlorianFranzen/ab92f1817a2ee4d2f2dac60109045ce8 to your computer and use it in GitHub Desktop.
Save FlorianFranzen/ab92f1817a2ee4d2f2dac60109045ce8 to your computer and use it in GitHub Desktop.

Summary

This is a quick investigation into what happens to an encrypted file if git-crypt is removed from the PATH. This could for example happen if git-crypt is uninstalled or if an already checked out repository is accessed from a different environment or host.

As git-crypt is currently implemented as a filter, its required flag controls the behavior on failure (according to man gitattributes). If it is not set or set to false, a failure of git-crypt (e.g. to re-encrypt the file) does not result in an error being raised.

To find out if the required flag is set, you can use the following command:

❯ git config filter.git-crypt.required     
file:.git/config	true

You can use the flag --show-origin to see where this flag is set and --local and --global to change if you want to evaluate the config in the scope of the current repo (based on its .git/config) or your global environment (e.g. ~/.config/git or .gitconfig).

Test Scenario

Here is out test scenario:

❯ cd $(mktemp -d)                                                            
❯ git init                                                
Initialized empty Git repository in /tmp/tmp.rR9mcDNcAV/.git
❯ git crypt init
Generating key...
❯ echo "secret.txt diff=git-crypt filter=git-crypt" > .gitattributes
❯ echo "Secret secret\!" > secret.txt
❯ git add .gitattributes secret.txt
❯ git commit -m "Add secret"
[master (root-commit) a7dce4b] Add secret
 2 files changed, 1 insertion(+)
 create mode 100644 .gitattributes
 create mode 100644 secret.txt

Lets simulate the change of a secret, before we switch environments

❯ echo "This will leak\!" > secret.txt 

Test Results

After a few quick tests it seems the leak can only occure during stagging, when the required flag is not set and only on the second attempt:

❯ nix-shell --pure -p git
$ git config filter.git-crypt.required
false
$ git add secret.txt
git-crypt clean: git-crypt: command not found
error: external filter 'git-crypt clean' failed 127
error: external filter 'git-crypt clean' failed
$ git add secret.txt

With the required flag set, all attempts to add the change fail without git-crypt in path:

❯ nix-shell --pure -p git
$ git config filter.git-crypt.required
true
$ git add secret.txt
git-crypt clean: git-crypt: command not found
error: external filter 'git-crypt clean' failed 127
error: external filter 'git-crypt clean' failed
$ git add secret.txt
git-crypt clean: git-crypt: command not found
error: external filter 'git-crypt clean' failed 127
error: external filter 'git-crypt clean' failed
$ git add secret.txt
git-crypt clean: git-crypt: command not found
error: external filter 'git-crypt clean' failed 127
error: external filter 'git-crypt clean' failed

It does not matter if the file is commited with or without git-crypt in the path.

To check if secrets where leaked in a previous commit, the commit has to be run through the filter again (wit git-crypt being installed). This can be done by having git list all commits and their content:

❯ git log -p  
commit b9b8880380ba8b4133f49e97098d8c5e79aae80f (HEAD -> master)
Author: Florian Franzen <Florian.Franzen@gmail.com>
Date:   Wed Mar 4 21:47:05 2020 +0100

    Leak secret

git-crypt: Warning: file not encrypted
git-crypt: Run 'git-crypt status' to make sure all files are properly encrypted.
git-crypt: If 'git-crypt status' reports no problems, then an older version of
git-crypt: this file may be unencrypted in the repository's history.  If this
git-crypt: file contains sensitive information, you can use 'git filter-branch'
git-crypt: to remove its old versions from the history.
diff --git a/secret.txt b/secret.txt
index 31a8f8c..cac1630 100644
--- a/secret.txt
+++ b/secret.txt
@@ -1 +1 @@
-Secret secret.
+This will leak!

Conclusion

To make sure that a failure of git crypt leads to an error, make sure your global required flag is set for your user:

❯ git config --global filter.git-crypt.required true

Alternativly, you can add the following to your git config file:

[filter "git-crypt"]
  Required

For any git-crypt repo you might share on a file system level, you should also set the repos local required flag:

❯ cd ~/path/to/repo 
❯ git config --local filter.git-crypt.required true 

Just keep in mind that this has to be done whenever you check out the repository again. There is no way to automatically distribute a git config with a repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment