Skip to main content

Detect Git secrets leakage with CaptainHookPHP

· 2 min read
Stephan Hochdörfer

If you have seen me speak at events in recent years, most likely you have heard me mentioning CaptainHookPHP as being my favorite git hook manager. I really like its flexibility and have covered some of our project setups in some blog posts.

In 2019, I stumbled upon a paper describing how to detect secret leakage in public GitHub repositories. Since the paper contained examples of regular expressions on how to detect different kinds of passwords, I opened an issue to see if that could be an interesting feature for CaptainHookPHP. We discussed how this could be implemented and somehow, me and Sebastian got sidetracked for the last 4 years and completely forgot about this.

And then - entirely out of the blue - I received a GitHub notification last week that Sebastian is working on the issue. End of last week, Sebastian released version 5.19.0 of CaptainHookPHP. The release includes the new BlockSecrets action which helps to detect if you are about to commit or push passwords that you shouldn't push.

The JSON configuration for the BlockSecrets action looks like this:

{
"action": "\\CaptainHook\\App\\Hook\\Diff\\Action\\BlockSecrets",
"options": {
"entropyThreshold": 3.7,
"providers": [
"\\CaptainHook\\Secrets\\Regex\\Supplier\\Aws",
"\\CaptainHook\\Secrets\\Regex\\Supplier\\Github",
"\\CaptainHook\\Secrets\\Regex\\Supplier\\Stripe",
"\\CaptainHook\\Secrets\\Regex\\Supplier\\Google",
"\\CaptainHook\\Secrets\\Regex\\Supplier\\Password"
],
"blocked": [
"#password", "[\\S]+\"#i"
],
"allowed": [
"#my-dummy-token#", "#root#"
]
}
}

The logic is only run for the change set you want to commit, which should be much faster than checking all the files in the repository for every commit. It detects secrets in .php, .yml, .json, and .ini files because the action tries to identify variables and their assignments. However, if you provide the entropyThreshold setting, it will do a brute force check for every word in the change set.

You can either rely on some default implementations to detect passwords for service providers like Aws, GitHub, or Stripe. Or, as an alternative, define your own regexes for passwords if none of the default ones match your use case.

Sebastian decided to extract the secrets detection logic in an own Composer package. That means, if you need a similar functionality in your own application, you can rely on this package without the need to come up with your own logic.

Personally, I think this is a pretty cool new feature and makes CaptainHookPHP even more unique in the large landscape of Git Hook Managers.