CodeSecDays 2024 - Join GitGuardian for a full-day exploration of cutting-edge DevSecOps solutions!

Save my spot!

CodeSecDays 2024 - Join GitGuardian for a full-day exploration of cutting-edge DevSecOps solutions!

Save my spot!

Complete guide to GitHooks - Creating your own pre-commit hooks

Learn how to automate tasks and check information using GitHooks. This video tutorial explains how to create local and global hooks that can call APIs, use grep, and other tools. Check out GgShield, pre-commit framework, and Git Hooks.com for more information.

Video Transcript

Hello friends welcome to another tech tip Tuesday where we give you Tech tips the day after Monday in this video we're going to be taking a look at get hooks by the end of this video you'll understand all about git hooks what they are and where they run you'll also be able to create some basic hooks for yourself and have an understanding of some more advanced features before we get into it I really appreciate it if you consider liking this video and subscribing to the channel it helps the Google Gods recommend us in the future and really helps us out with that out of the way let's dive straight in let's first take a look at the workflow that you go through when you're creating software and using git so if this is you here on my screen the first thing that you generally do is write some code and that gets staged and tracked by git then you make a commit and that goes into your local stash when you make that commit before it happens you can trigger a git hook and you can get it to automatically run some scripts and you can get it to block that commit if it fails conditions that you set you're then gonna push a series of commits to your remote repository before that push leaves your computer you can trigger another hook a pre-push hook and you can prevent them from leaving and entering your remote repository if that hook fails and of course then we have server side so the first two are on your local environment and these are great you have a lot of control around these and then you also have hooks that you can put on your server side right where your git server sits and for instance pre-received so before it gets into your repository but after it's less your computer you can run something when we talk about githubs three come up the most often pre-commit pre-push pre-receive if you know how to use git you probably know exactly what all of these already do there's actually a whole bunch more and there's more than even what I have on the screen right now what you need to know is that they get hooks all work in exactly the same way so after today you're gonna understand really how they work and you're going to be able to write your own ones and it doesn't matter what Hooks you're going to be using now there's one more thing I want to talk about before diving in and creating our first hook and that is understanding the difference between a local and a global hook right probably pretty self-explanatory a local hook sits inside your repository I'll show you exactly where it is in a minute and this runs just on this repository just this project right nothing else is concerned you can set up a global hook and this means that it's going to run on all of your repositories so just keep that in mind and of course there's lots of different ways to be able to do this and I'm going to run you through the one that I prefer I've so we're all caught up on what kit hooks are what they do let's create our first git hook so I've got my IDE open here I'm using visual studio whatever idea you use that's fine everything's going to work in the same way I have my terminal down here and my code will be at the top I'm navigated right now into an empty project an empty directory called githooks the first thing that I'm going to do is I'm going to initialize get with Git init obviously and what does this do this creates a folder it creates a DOT get directory dot get folder on my navigator you can see this a little bit more clearly so this is the folder we have here if you can't see it it just means that you have hidden files not showing so just make sure that you turn your hidden files on if we navigate into this folder we'll see some things here we won't worry about a lot of them but we will look in this folder here that says hooks and in here you'll see we have a lot of hooks that are named that are called dot sample I'm going to get rid of this and I'm going to navigate into using my IDE now so these are all the hooks that come standard out the box every time you initiate git so if you have old git directories so long as you haven't messed around with the template settings these will all be in those folders so we have here the pre-commit the pre-merge pre-apply patch so on and so forth to create our first git hook it's actually ridiculously easy all that we need to do is take one of these hooks go to rename and remove dot sample that's it every time git performs an action it looks inside this hooks folder and see if there is an applicable hook that is valid if it is it will run that the script that you write will be executed we don't need to update any configurations that will happen at the Box inside this pre-commit folder we can see some code now this is written in bash as you can see by the first line here right sh you can write your githubs in any scripting language so you can use Python you can use Peril in this video I'm going to be using bash and you can also get Frameworks that you can write them even in things like JavaScript but there's a little bit Advanced we'll worry about that at the end of the video so if you understand uh bash and even if you don't thanks to the helpful notes in this file you'll probably be able to understand what's actually happening in here some simple checks to make sure that we're using Asic for the file names and some different areas one of the things that this cook is doing out the box is is checking for trailing white space error and this is what this very last one is here and so this makes it actually really easy just to trigger our first git hook so what I'm going to do is I'm just going to create some files in here I'm first going to create a file called main.py and I'm also just going to create a DOT git ignore file and I'm just going to put a quick file in here so that it's not tracked by git if you want to know what a DOT get ignore file is then look at one of the other previous Tech tip Tuesday videos when we go through that all right I'm going to open up my main.py file and all I'm going to do is add some errors by putting in a bunch of white spaces so if we save this and we try and commit this file we should be blocked by the pre-commit git hook and we are you'll see here that we it's given us a trailing white spaces area and it's actually exited from that hook so if we go get status we'll see that there are no commits yet this has been blocked now this is really helpful when we're writing githooks knowing that we can actually exit out of it and prevent the action right we can write git hooks that just allow it through it doesn't always have to exit we have to write that in but it's helpful to know that that is happening because we don't need to do anything about our git history we don't need to rebase or use a soft head we can just continue on as normal and remove these trailing white spaces which if I do that and I do the exact same thing we'll see that with it's all gone through no troubles at all right that's it congratulations you've made your first kit hook that's the end of the video obviously I'm kidding uh let's go in now and actually have a look at what's going on in these git hooks so then we can actually understand a little bit more so back in our hopes file we're going to go to our pre-commit I'm going to rename this back dot sample because I just want to preempt an error that I think a lot of people tend to get the first time uh that they are using githooks so I'm just going to navigate into my hooks folder my hooks directory and in here I'm going to create a file called pre commit right so this is exactly what we have so we now have our pre-commit file right here and our last one is going back to to sample so this is what we're going to be working in from now so the first line that we need to put in for this file is letting it know what to expect that it's going to be expecting sh bash so we can move forward and what's always the first thing we learned to do in programming well we learned to say hello world so let's go ahead and do that so I've navigated back to my main directory and let's go ahead and I'm just going to make an arbitrary change into my main.py file so it's tracked by git and I can go get add main.py again and we get an error now this is just a very simple error that I wanted to preempt uh in case anyone's following along now if you're familiar with programming you probably even know what you need to do right now and we need to change the permissions of our pre-commit so the file that we created doesn't have adequate permissions to run as an executable how do we change that simple command shimod CH mod so we so let's do this now we go shimod U plus X and then we just need to type in the path of so we can here we can just put it for our pre-commit or if we have multiple commits in there we can use the wild card and do it for all of them so let's go ahead and do that and this will make a slight change on the file you'll notice here that this is now an executable by the small icon and it will also be evident in your main directory you can see here that it's now as an executable before it wouldn't have had that icon so now I'm just going to go ahead and make another commit now I've just made a completely empty commit because I don't want to keep making arbitrary changes but that has still worked you'll see here hello world my first git hook so congratulations we've ridden our first ever GitHub but now let's do something that has a little bit more substance to it something that's actually going to help us with our productivity one of the problems that we Face a lot in development is we don't commit enough but there is a solution to actually make people commit more using githubs and it's only one line of code so to do this incredible productivity booster we're going to write a quick curl command so this is just making an API call and we're making an API call to this URL here you'll find a link in the description but it's icann has dadjoke.com httpsican has dadjug.com if you know my sense of humor before you can guess what's gonna happen but let's save this and let's go ahead and make another empty commit I'm just going to go ahead with the exact same commit message we're going to go ahead and now we have our hello world first get hook but we also have did you hear about the kidnapping I'll move my head did you hear about the kidnapping at school it's okay he woke up oh man that took me a long time that took me a long time to get that what oh my God okay yeah it's terrible but you get the idea right we're gonna reward ourselves with a desk with a dad joke every time we make a commit helps us commit more that's what I'm telling myself all right let's clear this here all right so we can print some stuff off we can make a call but none of this is interacting with really any of the information that we've actually committed so what I want to do now is actually create something slightly more powerful uh actually this time that's interacting with the information inside our commit and again it's really not going to be that difficult so the first thing I'm going to do is I want to do an absolute cardinal sin and I'm going to paste some credentials inside my file so I know this isn't formatted quite correctly but you get the idea we have some AWS access ID and AWS access key hard-coding Secrets like this is never a good idea but it's one of the best use cases for git hooks because you can catch when these things have been hard-coded into your source code because remember git keeps track of everything that you do so if you've committed some secrets in the history it's going to be there forever and these secrets may be hard-coded into your files but they also could be inside debug logs or environment variables so really important that we don't commit these so let's write a hook that's going to find this secret and block the commit from going through now in this exact use case I'm just going to be looking for this specific type of credential this is an AWS credential now it has certain characteristics which makes it easy to find we're not going to write out some elaborate program to find all secrets so to do this we're going to be using a pretty cool function called git grep so if you know what grep is it's basically just a way of being able to search through information and in this case it's going to be searching through our commit and it's incredibly simple to do now if you want you can code along with me or if you don't want there's a link to my GitHub which has just a folder that that has this code in it as well if you just want to copy it so if Get Grip then we're going to put in the parameters of what we're looking for so we're telling it to look at our commit for a string A to Z 0 to 9 that's 20 characters long and then we're going to give ourselves a message if we find this and I'm just going to say hey if we find this you've hard-coded a secret you don't get a joke and then we're going to exit out of this now what this should do is it because our dad joke is running at after this we should actually exit that commit before it's finished and we should say hey we've found a secret we're not going to go any further all right let's test this all out so I've saved that credential in my main.py file now let's add it let's add an inconspicuous message like this and let's go ahead and see what happens so you see our hook has run hello world my first hook and then it's actually said Hey in your main.py file I found this AWS access key this is it here this matches parameters of the git rep that you just wrote and then it says you've hard-coded a secret no joke for you and we can see that it's actually exited because we don't get our joke and we can confirm this by going git status and we can still see that this is staged and modified so there we have it we've just written some grip that interacts with the commit data that tries and finds secrets now they're the tiniest small problem with using this in real world scenarios and that is that the grip rewrote well it's not that good we're dealing with large projects there's going to be lots of strings so they're going to match the criteria of this and we're going to create a lot of false positives the last thing that developers want is to be interrupted in their workflow by false positives luckily for us though there's lots of great tools that we can use for this type of sequence detection and we're going to use them and the advantage is that we're going to learn uh some of the other cool things that we can do with githubs so I'm just going to comment all this at going to move my dead joke up here I have a package installed onto my computer called GG shield now GG Shield can do lots of things involving Secrets detection you can scan directory scan your entire get histories for these types of Secrets and one of the things you can use it for is within githooks so if you want to follow along with me I have a video that I'll make up here about how to use GG shield and install it it's really quick you can use pip but if you don't have GG Shield installed you can still follow along in what I'm doing so right now in my GitHub I'm going to call GG Shield GG Shield has a falcon called Secret scan and it has an option for pre-commit so it knows how to handle the data and then we're going to pass it the commit data so that's literally it that's how I can kind of call a separate package and send it the commit metadata that I want all the the metadata that the Hook's using uh to do a thing right and in this case that thing is detecting secrets so because our last hook got blocked if I just do the same commit again so we get a message our first hook and then well it does stuff so let's have a look at what's happened so hello world my first hook yes and now the rest is being done by Gigi Shield so it's saying hey in main.pi we have an incident detected so that's obviously a secret and here's where it gets much more powerful it's telling us that it's AWS Keys it's correctly identified the keys it's telling us it's valid so it's checked with AWS that these keys are actually valid that's pretty cool and then it gives us exactly where the secret are is hidden some of it and it gives us some advice on how to remediate it uh and we'll see that this is still uh under modified so it hasn't gone through so that's cool but this is in the video on GG Shield what this really shows is that we can call packages and we can send it the information just like we can in any other bash script so we don't need to write everything ourselves we can interact with different packages and libraries that are on our machine so that's a pretty cool feature so I feel like now you've probably got a good idea of how git hooks uh actually work and you may have some ideas of what you can do with them you can create some hooks to send you reminders when you do certain things you can create hooks to check out certain branches you can do lots of powerful things in this video the idea isn't to go through all of them but I do want to look at another type of hook here this is going to be a pre-commit hook as well but the difference is that this is going to be a global pre-commit hook so at the start of this video I said that we can have local hooks and Global hooks right so a local is what we've been doing and this works just in this project just in the githubs project that we created at the start but we can actually set up a global git hook that will work on all repositories so just to talk about global hooks at the moment now of course there's multiple ways to be able to do everything and some people prefer it different ways one way to set up a global hook or kind of a global Hook is to actually modify the templates when you initialize your git repository so remember when we did get a net at the very beginning it came up with all these sample git hooks well we can actually set it up so that we use our own templates every time we initialize so that way the same hook can be applied to all the projects that you set up I don't necessarily like this way why because if I want to make a change I have to go back and re-initialize or copy that file across to all my different projects it's not like a real Global Center but the other way that we can set up a global GitHub which is what I will do now is to basically tell git that I don't want you to look in the standard file for githooks anymore I know when you look in the project and the dot get slash hooks I want you to look in this specific folder this specific directory in this specific location on my machine now it can be anywhere and it can be in any folder but we're going to set it up in the same way that this I have it set up on my machine so here we are in this directory and what this is is we've just navigated to the absolute root of the user on my machine right and yes we can see lots of kind of files and config files this here is where our git config file is automatically set up um that's basically stores the configurations of our git so there's lots of things in here and it's in our root directory I'm going to create a folder called dot gets I'm going to put a hooks folder in there a hooks directory in there and then I'm going to tell git to look in this specific folder for hooks from now on so let's do that so first thing let's create our folder so this symbol here in case you don't know just as telling my machine to make a directory at the root so not in the current folder and we're going to do the same thing for our hooks and then finally we're now going to create a pre-commit hook so what you'll see now is we actually have this folder that's been created the dot get folder and here we have a folder called hooks just like what we do in our local and here we have our pre-commit file that we just have now just like before we need to change the permissions of our pre-commit so it can run as an executable so again shimod U plus X and then we're going to put it now we can either again set it to just the one file or if you have multiple files in that same directory you can use the wildcard and now you can kind of see how this changes icons into an executable of course this may look different if you're on Windows or Linux but it will serve the same function right so we've changed our permissions so that we can now run this file as an executable the next thing we need to do is we need to tell git that hey I don't want you to use the standard setup anymore I want you to use this pre-commit and we can do that as well and we can do that by looking at the global git uh the global hoax path so if we go git config Global core dot hooks path it will return nothing we don't have any special paths set up so all we need to do is at the end of this put in where we want it to look and we want it to look in our DOT get slash hooks folder located at the root of the directory so if I go ahead and do that if I look for our path again now you'll see that it's navigating to users mckenzie.get hooks right now we don't have anything in our git hook so what I'm going to do is I'm going to do a split screen of my code here we'll move this across so here we have our local hook and I'm going to change this here and here we're going to do the same thing I'm just going to copy this across but we're going to make it at global so let's go ahead and commit something and see what happens all right so what's happened our Global hook has run you can see that text here but our local one has not run right it hasn't run DG shield and it hasn't said hello this is my local hook so what does this mean well this means that both don't actually run we've pointed our git config to our Global and that's what's running but this causes a problem the problem is that there are certain things that I may want to do globally I probably want to check for secrets on all my repositories all the time but maybe there's something specific in this project that I don't want to do in other projects and we can actually do that there's a little bit of a roundabout way of what we do but it makes total sense we're riding in bash we can call other functions in bash so what we should do is let's call our local Hook from our Global hook that will work right so this code here again you're going to find this in the GitHub tutorial and projects that I made the links in the description um but all this is doing is an if statement they're saying hey if we have a pre-commit hook that I want you to run it I want you to send it the data right I want you to send it that pre-commit data if that fails then then we're going to fail it at that point there okay so let's check this out at the moment what I'm going to do just quickly is I'm we've committed our secret now so I'm just going to move it down a little bit so that it triggers again and here's what should happen we should get the message hello that this is my Global git hooks I'm a good hook because it's only one and then it's going to say hello this is my local hook then it's going to run GG shield and hopefully it should fail and block that commit so let's see if we are right get add main.pui testing double hooks let's go ahead all right we've got the first message we got our first message yes we've got our second message yes so that means that we have successfully called our local Hook from our uh from our Global and GG Shield is now running fantastic it's detected our secret and it's blocked the hook the hook get status yes it's still modified all right we've come to the end of the video I hope that you've actually been able to create some hooks with me you've got something set up and you have an idea of how you might want to use this lots of different ways to use Hooks and you can actually get quite deep into it if you're looking to learn more about hooks what I would recommend is taking a look into the pre-commit framework now it's called the pre-commit framework it does a lot more than just pre-commit hooks um but I guess that's where it probably started what this framework does is creates a language agnostic environment in which you can create Hooks and what's really cool about it is that there's hundreds and probably thousands of hooks that other people have created that can serve specific functions and using this framework it's really easy to chain them together using a simple configuration file for it if you want to up your gaming git hooks now that you understand the fundamentals and how they work then start by checking out the pre-commit framework and if you would like me to create a video on the pre-commit framework then let me know I'll be happy to do that I hope you enjoyed this video remember to like And subscribe to the channel it really helps us out