3

Here's the scenario...

I have a git repository on a server that may have been compromised. My development team say that they can trust the files in the directory that houses the git repository because all commits (diffs) and new files being added to the repository are checked and signed off by the repository 'owner' and any new files would show as new to the local version when a status or pull is made.

However I believe that if a person has compromised the server on which the git repository is housed, there must be some way to add a file to that repository and cover it up so that when a developer does their next pull, the new file doesn't show up in their git status. Is this the case?

David Scholefield
  • 1,824
  • 12
  • 21
  • (I don't really know but am making an educated guess). I suspect if you can create a new file with the same hash as an existing file you could replace the existing file with the new file and git would not be the wiser. This would be really difficult to achieve. – emory Jun 23 '15 at 18:02
  • AFAIK the commit history log is not signed, so could you edit the log to make it look like that file was in the initial commit (or any arbitrary commit)? – Mike Ounsworth Jun 23 '15 at 18:05
  • So I've not checked this personally to be certain, but it looks like git-rebase may be usuable to modify commit logs http://stackoverflow.com/a/4110978/537897 . also the identities that git stores aren't checked server side, anyone with access to the repository can call themselves anything they like when they commit (again AFAIK) – Rory McCune Jun 23 '15 at 18:13
  • @emory "I suspect if you can create a new file with the same hash" can two files have the same hash and have different contents at the same time? – Ulkoma Jun 23 '15 at 18:40
  • @Ulkoma Yes, it's called a [Collision Attack](https://en.wikipedia.org/wiki/Collision_attack) and it's a very common method for breaking hash functions. – Mike Ounsworth Jun 23 '15 at 18:56
  • @MikeOunsworth Oh yes, I remember that now but what are the chances that a malicious file's hash matches a good file' hash? also would not it be easy to detect that by comparing the hashes of a different hashing function? – Ulkoma Jun 23 '15 at 19:02
  • @Ulkoma Yup, both good points. I didn't say that collision attacks are easy to pull off, just that they're possible :P ... and that attackers do use them to good effect. – Mike Ounsworth Jun 23 '15 at 19:04
  • @MikeOunsworth yes, that is the word I was looking for. Is it really common? It seems extraordinarily difficult. – emory Jun 25 '15 at 17:37
  • @emory I can't say myself how common collision attacks are "in the wild", but they are the main reason that MD5 and SHA1 are retired. According to `en.wikipedia.org/wiki/MD5` and `en.wikipedia.org/wiki/SHA-1` you can find a collision pair for MD5 with 2^18 computations, which runs in under a second on a normal computer, and for SHA1 in ~2^60 computations which is currently intractable but scary enough to make people move off SHA1. – Mike Ounsworth Jun 25 '15 at 17:50

2 Answers2

3

Your developers are correct in that any changes to the repository will be reflected by a new commit. Previous commits cannot be modified without all developers being notified of a serious conflict when updating from the remote repository.

That said, it would be trivial for an attacker to add a new commit to the repository that would automatically be downloaded and applied to developers' local repositories when pulling from the server. I find it extremely implausible that all commits to the repository are manually reviewed unless this is a very infrequently-used project. Even if they are reviewed, a motivated attacker could make an innocuous-looking change that has security implications. For example, in 2003, an unknown person added a commit to the Linux kernel that contained a root escalation vulnerability. This was back when Linux was using CVS, but the only real protection git has against this sort of attack is gpg-signed commits.

Unless you're using strong cryptographic signatures to protect your commits, there's no way to truly know whether or not a third party modified your repository without doing a full audit of all commits by the developer that supposedly authored them since the date of server compromise. This is the only way to truly ensure that an attacker didn't forge a commit by one of your developers.

It's up to you to determine whether or not the risk of the attacker having done this is worth the effort involved in trying to uncover it. If you're a small company making software that doesn't store, protect, or access sensitive data and this looks like a typical drive-by compromise to turn your server into a spam host, I probably wouldn't bother. If you process large quantities of money, I probably would.

Now would also be a good time to ensure that you aren't storing any credentials inside your repository. Things like database passwords, API keys to other services, TLS keys, and cryptographic secrets used for session cookie authentication should never be stored alongside your source code, and you should consider any that have been to be compromised and require rotation.

Stephen Touset
  • 5,736
  • 1
  • 23
  • 38
  • This was almost certainly my feeling. The check for authentication credentials has been made. I was interested whether commits could actually been 'hidden' though rather than showing up in developer pulls and not noticed/checked or ignored. – David Scholefield Jun 23 '15 at 20:16
  • 2
    No, the design of git does not allow that as a possibility. – Stephen Touset Jun 23 '15 at 20:46
2

Building on what has been said, reading commit logs is everything however there are ways to trick the end user and having them download files that are not obvious to them.

One way is to add files to the git object database directly instead of the repo (so using git hash-object command instead of the normal git add). That way they don't appear when you type a list command, so it won't be obvious that they are pulled down.

$ echo 'version 1' > test.txt
$ git hash-object -w test.txt
83baae61804e65cc73a7201a7252750c76066a30

Your database contains the new content:

$ find .git/objects -type f
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30

I have seen projects use this method to hide secrets and credentials which is not secure and is simply security by obscurity.

channel
  • 381
  • 3
  • 7