-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Security Considerations should mention git forking and history rewrite attacks. #7
Comments
@msporny you're making a good point. I was operating under the assumption that with did:git, repos would require that every commit be signed by one or more keys stored in the repo so that the provenance on the DID docs anchors the trust in the commits. If the governance of the repo contains the rules that govern which keys can sign updates to the repo DID document which keys can sign updates to the committer DID documents, this kind of attack can be detected. Detection combined with anchoring externally should be all we need to prevent these kinds of attacks. But I could be wrong. Here's an example of how I envisioned the Linux Foundation using and defending a repo:
Can you think of any attacks against a regime like this? The did:git spec isn't meant to be an air-tight defense against forking and history rewrites but by combining meat-space protocols and explicit governance rules combined with the git history and requiring all commits to be signed by keys already in the repo, I think detection of the attacks and authentication of forks is possible. I'd love to game this out more if you've got more ideas on attacks. |
I do, but very little time, unfortunately... so my feedback is going to be sporadic, where I disappear for large periods of time... so as long as you're cool with that, some thoughts below. :)
Not an attack, (but it will become one, potentially). If you choose to do it this way, which we had considered before, then you can't bring legacy repos into a "signed by DIDs" ecosystem w/o doing a full history rewrite. That poses an on boarding problem that is going to harm adoption. Instead, you should make it so that any git repo can be converted to being protected by DID-based signatures. One way you could do that is enable your steps #2 to happen at any point in history in the git repo (where all previous hashes are signed as a part of git did init). ... aaaaand, once you do that, you're susceptible to the fork/rewrite attack, no?
How? Suggest that LD Proofs enable multiple signatures (since you already seem to be planning to use JSON-LD)... :)
Hmm, so this is a bit of a strange DID method (I make no value judgement, yet... just making an observation). It feels like two things shoved together, namely 1) DID-based digital signatures on commits, and 2) a DID and key rotation mechanism. It feels like the two things should be split apart to create the right architectural layering. It feels like what you want is a set of files that express governance rules for a .git repo -- who can commit, who is allowed to add committers, how many signatures are required for a merge to master, etc. and an extension to git that handles this. This layer should be DID Method agnostic. Then create a separate layer that is a DID Method supporting all the CRUD operations for those that don't want to use a DLT-based DID method. I will note that the forking/rewrite attacks are are applicable to both... but feels like the layering is off and how we address forking/rewrites are going to be predicated on the layering discussion.
If the goal is to trick people into thinking a repo is valid, then I'd git init w/ my own keys and create a tool that recreates the "good repo"s history while injecting my attacker keys as the maintainer of the repo. Then I'd just try to trick people into copy-pasting the wrong did:git value into their git clone command / did git validate. In other words, feels like the easiest attack would be a social engineering attack, not necessarily a crypto or protocol attack. |
I'm OK with that. There are so many subtle details and it's going to take all of us to make this happen.
This was the plan all along, sorry for not being clear about that. At some point in the history the repo will be imbued with did:git governance. That point is also when any attestations about the existing history must be made. There are several strategies but I best like the one that includes a Merkel tree of past commit hashes as a file in the initial "gensis" commit. In theory, if the commit hashes were stronger, we wouldn't need to do anything because the signature over the "genesis" commit would include the hash of the parent commit. Any change in history would ultimately change the hash of the parent commit. If a rewrite attack is in the threat model of the project then anchoring the DID string for the repo--which is the hash of the genesis commit--is necessary for authentication by others.
Precisely what I was thinking. :)
We are defining CRUD DID methods for both the repo DID (e.g. All CRUD operations go through the planned The CRUD operations on the repo DID string operates on the repo DID file. So I made a mistake earlier when I said The other governance stuff is how we take meat-space protocols and encode them so that they are enforced when git commits are made. Each project has different rules for how commits are landed and we want to be flexible to support as many options as possible. I plan on making a good default that meets the Linux Foundation's needs but there is no reason why we couldn't have other examples/templates that users can choose from. In the end, whatever form it takes, it is the functional equivalent of "smart contracts"/"transaction validation" in a DLT. I started the discussion about that over here
External anchoring is the primary defense against this. Also, project owners (i.e. DID controllers) can add a "canonical location" to the repo's DID document that is anchored via the DID string. It is important to remember that the domain of trust for did:git is the repo itself. Only the repo DID string needs to be globally unique and the DID's only mean something in the context of the repo. This is in line with the decentralized philosophy of git's design where there is no such thing as the repo; there's just lots of clones. The meat-space protocols are designed to solve that problem and I think as long as we anchor the meat-space protocols into the repo (e.g. governance.json, canonical URL, etc) and then anchor the repo somewhere public, that should be good enough. I'm always open to discussing where I/we are wrong on the current design. Right now I feel like we're just level setting with communicating all of what we discussed at IIW. I'm personally optimizing for solving the LF DCO problem which is as much a legal and human protocol as it is a technical one. I am hoping to leverage SSI and DIDs and DID proofs to enhance Git in a way that doesn't change it's design philosophy but allows the LF to strictly enforce their legal and human protocols. I think if I can solve that, it will also be useful for others. |
I may be wrong here, but I think the git:did method is going to be susceptible to rewrite attacks. That is, an attacker gets a git repository and either forks, rewrites, or appends history. Now you have two .git repositories w/ the same initial commit hash, that have subtly different histories.
I don't think you can mitigate this attack (unless you couple this DID Method w/ some sort of global append-only audit log), the best you can do is detect the attack and do something about it (like, check to make sure you're using the "official repository" for the project). Even that is susceptible to attack: https://about.gitlab.com/2019/05/03/suspicious-git-activity-security-update/
In any case, you should document this in the Security Considerations section of the DID Document.
The text was updated successfully, but these errors were encountered: