Conf42 DevSecOps 2022 - Online

Kick Your Security Up a Notch with Custom Queries

Video size:

Abstract

Static analysis is a great tool that enable developers to create rules for their code base but the native rules, sometime just make extra noise and false alarms. We will demo how to create custom queries this with the open source tool KICS, but it is also applicable to other excellent SA tools.

Summary

  • Gabriel: I admire us as DevOps. We've taken our shoulders all the things that developers hate to do. When everything became complex, we add another layer on top of it. This layer is infrastructure as code. Today I'm going to show you one of my favorite methods to make those easier.
  • We love infrastructure as code because we can have all our protocol in one repository. Kix is a tool that checks your infrastructure for misconfiguration. It gives you control on the continuous operation process.
  • Kix is based in a very powerful framework called open policy agent. Open policy agent is a way to define policy as code. You can write your own query, your own policy rules and implement it on Kubernetes.
  • Kics allows you to create custom queries for your API. You can test your queries like a unit test. You need to make sure that every API endpoint has a route inspection header. Kics also gives you some test framework to run your queries.
  • You can create rules almost in every tool that you run automatically. Almost every security tools that you will hear of today. Think about look at your organization and think what rules you can create to make your team run much faster.

Transcript

This transcript was autogenerated. To make changes, submit a PR.
Our name. Hello everyone, thank you for joining me today to my talk about kics. Kics up your security app notch with custom query. So I want to first say that I really admire us as DevOps. And I tell why, because we've taken our shoulders all the things that developers hate to do, right? Developers hate to do operation and we took that on our shoulder. And lately it's not only operation, it's also security, observability, githubs, ML ops, all this operation stuff became on our shoulders. And now I know that developers usually do not understand how do we agree to took all those operation responsibilities. But we know the trick, right? So what we do to make this operation easy, we automate everything, right? This is the key to have DevOps efficiency, to do automations, right? This is the way DevOps started. This is why it's called DevOps, because we started to do the manual operation deploying the server. I remember that I manually used upload files to an FTP server and then people automate that. You remember the tools like chef and puppet, et cetera. And then when everything became complex, we add also another layer on top of it. This layer is infrastructure as code, right? So a couple of years ago, after we do have a lot of scripts that does everything and script that rules script, we started to say, hey, maybe we can write those infrastructure as code. So we started to describe infrastructure like resources, machines, APIs, connections, policies, everything configured as code. And that makes our life easier and make our job much, much exclusive to developers, right? Anyway, we do that layer, but you know, Mark Knappler, telegraph road, then come the laws, then come the lawyers, then come the schools, and then came all the mess on top of that. So this infrastructure as code layer became complex too. So we create another layer. Now we have tools that automate what we do on infrastructure as code, that automate what we used to do with script, right? This is a new layer that we see now, many, many tools that take care for infrastructure as code and do some operations, automate operations on top of it. And now if you don't mind, let's think what will happen in two years from now. We will have another layer, and then another layer. And this slide in the world that we have today, this slide in couple of years from today will have n layers as the number of the complexity we will add to our system. And that's a big problem. And my name is Gabriel and today I'm going to talk about one of my methods. There are many methods how to deal with this layer, model, to orchestrate stuff and making it less complex even. We automate everything, all the complex system. Today I'm going to show you one of my favorite methods to make those easier. But I will not do it alone. I want you to welcome our guest to our talk. Today we have a very special guest. This guest is born in Guatemala. He became a very big businessman there. Guy there. And then he moved to Mexico. In Mexico, he opened some businesses, but the security and all the operations became very complex because Mexico, you know, there are trouble there. So he decided to move to the country where everything worked smoothly. He moved to America, to the US. And then he find that not always things in America works like in America. Let's welcome gas. Freeing a good businesswoman with two main business, Los Puerto C? Romanos and La Vendrea brilliante, but also some business that we don't want to know about. And let's see how he went to infrastructure as code. So, as we said, he get to America. He started his businesses, but then he find that he need protocols, right? He have a very complex business model. He do things below the table and above the table. And he needs time to hide stuff and sometimes to show stuff. And he wants to see that outside everything will look great. But inside sometime became dirty. And this is why he came in love with infrastructure as code. Why? Because infrastructure as code get you control on the continuous operation process. If you just have scripts, if there is something new, some resource, some protocol that you need to create, nothing documented that. And this is the point. Gas. And we love infrastructure as code because we can have all our protocol in one repository, right? And this is how gas actually built his business to do everything as code. The code started in the terraform that define everything happened. Every store has a terraform resource. Every bucket that get into that store is a resource in his terraform. All the API, all the connection between the businesses now documented as code in open API files. And then the containers, all the containers shipped on trucks is on Docker. And this orchestration and drivers use kubernetes. And also even it does some serverless framework for all the small stuff in the middle. Now Gus has a very nice repository with all his infrastructure documented and protocol. That's code we can find. Gus, look at the evening at this repo and smile to itself to see how he got his businesses to do everything work efficiently. And he can inspect everything. But that happiness didn't keep longer. Someday an unattended guest came into one of his businesses and treat the customers and the team there. And that was a very, very bad event. And Gus of course after that tried to relax the employees. But then he got that something got wrong with the infrastructure as code. He got to his repo and ask himself, how do I configure infrastructure that could make this stuff happen? And he looked at the code again and again and tried to look at Google. And then he find a very small asterisks. You can see here in line seven. Okay, the actions, you see the asterisks that said all the actions permitted in this resource, but that's supposed to be prohibited. And then Gas asks himself, how could I know that all those nice stuff that I'm adding as code and protocol is something that I know about. And gas as you know has domain expertise. But sometime this protocol came from outside. And now gas came to a question that every developers engineer asked himself, especially in developers term. How could I know that all my infrastructure as code do what it aims to do? And gas says look at the Internet and find a tool called Kix. Kix is a very popular open source tool. There's some alternative but we will focus on Kix today. And Kix is actually checking your infrastructure as code for misconfiguration. It check if there is security problem. It check if there is any misconfiguration that can lead you to trouble. Kix actually used to find what happened to gas. If someone has this terraform file, Kix will tell you this is a misconfiguration. You should never put wildcard in the actions portion. You should put something else right. So gas started to use Kix. Kix is actually very easy to use. You can edit as a GitHub action, you can run it locally, you can run it on every circle CI or CI system. Just a simple docker image and one command that you run and it gives you everything happen in your repository. But not only that, Kics actually has 1600, more than 1600 misconfiguration and security test on all the tools that listed here. So you can check your ansible code, you can check flag cloud formation and azure resource manager, you can check your Kubernetes config file, you can check APIs, you can check terraform, terraform can do everything, which is a very good check in Kix, that it can check all your terraform for misconfiguration. And actually gas was really happy. And why he was that happy because even in the first time that he ran cakes. And I promise you that if you didn't run any misconfiguration tool yet when you will run it, you will find some findings, so gas finds some finding. And then he understood that this tool will work for him. So he started to use Kix, put it in a continuous way for every new commit came to the infrastructure as code repository. He used to run Kics and find if there are any misconfiguration problem there. But this happiness did not continue longer. Why? One of the checks on kics, called privilege escalation allowed. This check actually verify that you don't have containers in Kubernetes clusters that run with privilege escalation allowed. Which means you should always have some privilege permission on your container. But for gas that wasn't good, because some of the containers got to trouble. And when it got to trouble, gas don't want to know what happened there. He wants to have custom rules that say if something, then something. So what is the first thing to do, right. So you find like one finding that have severity high, but you don't need it in your organization. So right, gas is a very good thing for that, it just can exclude that. We know that gas, when he don't like something, he excludes it from the system. This is exactly the same what Gaz does with this particular query. But then gas understands that he should not always exclude it. He regrets on the way that he excludes totally the way of this query, this test from his kics run. And he needs to find a way now not only to exclude that, but maybe create it, maybe modify it a bit. So the test will check for privilege escalation, but only in particular cases. And right, this is something that can happen in your organization. You started to run Kix, you started to run some automation tools, and then you find that one of the finding, one of the test, one of the checks is something that you want to run, but not always, or you want to run, but you want to customize that. So let's see how you can customize your kix queries. So let's take a bit a broader view on Kix, how it works. So Kix is based in a very powerful framework called open policy agent. What is open policy agent? I'm pretty sure some of you already familiar with that. Open policy agent is a project funded and maintained by the Cloud Native foundation and Linux foundation. And it's actually a way to define policy as code. What does that mean? So think about code. Code is actually something, in the end static. It's something that computer understand. And when you translate code, it usually can translate it, especially infrastructure as code can translate it into some tree three mean JSon, right? Json, you must know Json. JSON is always a tree structure and then you can define a policy that check if this tree structure is standing in the condition that you define in the policy, right. And open policy agent is actually work on many many endpoints of your product lifecycle. KICs actually takes queries that written in open policy agent and we will soon see how you can write your own query, your own policy rules in open policy agent and implement it on your infrastructure as code. So how actually open policy agent define a policy. So OPA, I'll call it opower. OPA from now has a query or policy language that's called rigo. And this is a very simple policy that you can define. So first in line one you define the package, the package called play every policy agent, every policy must have be part of a package. And then you can import some tools. These tools will help you to ask the right question about what you define right now. And then we say hello equal to base. Now this policy agent, this policy rule, this policy rigo will have input. Input is what we want to check. Input can be API call. Input can be infrastructure as code. Input can be Kubernetes data, whatever it is. The input message equals world will do hello to true. And then we can check if this hello equal world. We can say that true and say the policy fail, all the policy succeed. This language can of course be very rich. And this is the way every query in kics work. Let's look on a real time, right? So every query on kix has two building blocks. The first one is the metadata. This is actually the simplest one. So think about it like the description of the particular KICS test. So we already talk about the KICS test. Call privilege escalation allowed, right? This is the one I opened here and we here declare here a json that say what is here in this query. We'll go later further to see every part of this json. What does that mean? But let's say in short now we need a query name, we need the severity and we also need an id. We'll see later how we generate all that. We can have also description URL so the finding will have some details. So we created the first one. Kix created actually the first one. And then we have the rigo. As we said, every kics text is actually Rigo query rigo policy. So let's see how Rigo policy looks like. For example, for the privilege escalation allowed. So let's dive into this one, as I said, we have a package, we're importing some tools and we'll go to those tools later. And then we have policy. Every policy check only one thing in the infrastructure as code file. It started with the document here we know it's Kubernetes. This document will be yaml that defines kubernetes. Then we can take the metadata, check the spec for the container, check if there are containers and then check for each container. If allow privilege escalation is true, if allow privilege escalation is true, we want to return the result. So remember, if allow privilege escalation was false, we didn't have the result. And that's a nice way to see how query in Rigo in open policy agent work. So if we return the result, we know that the policy failed. If we not return the result because the code did not reach this way, we know the policy passed. So when kics run it actually go all over your kubernetes file, run this portion of policy and if allow privilege escalation is true, we will return this one. Now let's back to the example that we did have in gas, right? So gas want only particular cases to run the privilege escalation policy. So we modify the policy to say gas. Know that container that started with the name Regalo shouldn't allow privilege escalation because this is like a kamikaza container. If something happened to them, you should burn all the truck. So he said, if the container name starts with Regalo, only in this case get into the failure of the policy. And that's a nice thing how we can customize and we can take it to ourselves. Let's say for example, we want to limit something on s three buckets, but we do want particular buckets to have public or this exactly example that we want for example some model of escalations or some model of privilege on particular sets of container we can set on our organization that only containers that started their name in some particular name will get a bit different policy requirement on that, right? So now we copied the original query from kix repository, as I show you is on GitHub and we are mounted in a local folder. And when we run kicks instead of run kicks without anything, only with our code. As you can see here in the latest second mount we have the test code. In the first row we are mounting actually the custom query into the original query in the kics container. If we will run kics this way, it will take the query from our local customized query and then everything will work smoothly, right? Only if container name starts with Regalo we'll get the finding. But for all other container we'll not get the relevant finding. I'll show you later how to do this. Mounting more efficient for all your custom queries. But this is the way it works. So now we have gas happy, right? So he can now look at their queries and if something fail which are not supposed to fail, he can exclude that and he can also customize that. But then some security incident happened again and gas also expand his businesses. He decides to not only trust things that happened in Mexico and also do stuff inside. So he gets to his business. One of the biggest name in the security industry in America. This is let's welcome Mike Armantrout. Now Mike came into the business, right? And Mike have some very, very specific requests. One of them was that anything happened between the businesses will be under his inspection. Think about it like you have an API and all your API should have some header. This header is not something that Kix will check, but you want to verify that every developer that deliver open API configuration to your code base has this header configured there. So we need now to create new query. Now kics don't know what happened in our internal API configuration. And when we need to think about queries on kics, we need to think on every particular case. Now think about it like a unit test. When you write unitest, when you do TDD, you are thinking on every corner case that your test can fail. And this is the same way you should think. But custom queries that we are going to create in kics, we are not going to create every edge case. But this is something that important to remember for later. So what we need to do, what we need, our basic request is very base is very small. So we want every path, every endpoint in our API has this header called route inspection. Now let's think about it as a query. Okay. We need to check there is header portion for every API we need to check one of those header is ermine route inspection. We need to check this ermine route inspection as the right schema and this is not number right. So I can count lot of things we need to check. We will need to write just a query, one query but with lot of policy portions. With lot of policy policies configured inside this query. In order to make sure every API endpoint came with airman's route inspection portion header, right. So how we can do that. So first thing, kics came to help with us. If you will clone kix repositories or just get into kics. On GitHub you'll find a folder called template query, right? What is template query is actually an empty query that you have and you can write your metadata, your rigo based on that. But this template has another thing which is important for you. If you want to create a new query, it has test folder. This test folder should include all the test cases. You need to verify that your rules works well. Okay let's look for example on the very basic difference between positive and negative. So in the left side we have positive the positive missing the header, right we have here the path slash which is get method and we don't find any header on it. But in the right side we find the parameter has header. So now we know we have test base. The first test case should not expose the finding and the second should show us a finding. So this is point to start. Of course our case has some more positive and negative flows but we need to start with something, right? Then we need to define our metadata JSoN. Now this metadata JSON has some thing we need to declare. We must to declare all those things. Query name which is the name of this query. The severity can be high, medium and info the category of that which is access control. There are a list of categories can be found on kix repository description text which is the text that describe what this finding do. Which is very important because when people run it you want to be informative to know what they need to solve. Description Id and Id. Now that's interesting because you need to use some kix CLI to generate those id. It's very easy to use. You can find it. I already created it myself here and the platform. Now what is the platform? So Kix actually if you remember we say that open policy agent is actually run on JSON in code to process trees like a JSON tree tree structure and then see the policy on that. But for example Yaml is not a JSON. Pulumi is not a JSON. Terraform is not a JSON. So Kix already support libraries like all of that and allow us to write queries and Kics will convert those structures into JSON and do the checks there. So you can look here on the libraries that Kics support and see what is the platform that KiCs supported and you can write today in your creating custom queries. Good point to know is that KiCs also give you some test framework. So if you don't want to run kix in order to check your new query, you have some CLI tools, you can find it and also instruction how to install it on kix documentation. And also do test for your queries before I'll show you later. I'll not get into it too much because it's something you know you need configuration, your environment, et cetera. But that's good thing to know. So remember you can test it also in more detailed and informative way using go run commands that KiCs include already. And then we got to the most important part, right? So we already have our test for the new query, we already have the metadata Json. And now let's write the first policy. Now you remember we need policy for every edge case. This is only the policy for the very basic thing we want to check every endpoint that we have configured in open API has parameters. Parameter is actually the place where we put the headers for every endpoint. So as you can see we have here the documentation in row six, right, which is the document which will be the open API. Nothing from our side. And then we want to check is tree which is important for us because we don't want to allow user to use open API two. And then we collect all the passes. Now all this thing is some syntax you have to learn in Rigo. This is not something hard to learn, but it's also similar to go in some ways. And here we actually collect all the passes from the Rigo and we check for each one of them if there is a valid key call parameters. Now remember if we will pass after row nine, mean if open policy agent will run on this rule and will go after row nine, the result will return and then we check if there is no valid key parameter. We want to go to row eleven. Row eleven will retain the result and that's our first policy. This policy want to check if there is parameter and then we say we miss attribute, right? So every result has some keys. You can find kics documentation on that. But we go quickly, we have the document id which is actually the file. We already ran the infrastructure as code check on it. We have the search key which is what we want to search. And you can see here a formatted dynamic attribute from the particular name. What is the name? Name is actually the name of the endpoint missing attribute, Mike's header, right. And if we have write result, this is how we already write our new query. If we'll take those query and mount it to Kics, every open API, that missing parameter portion in the configuration will throw this result. Nice. We created our first rigo and I encourage you if you didn't succeed to read noise by excluding or by customizing. Think about new rules. Think about look at your organization and think what rules you can create to make your team run much faster. You can also combine some git apps with that, et cetera, to see how you can create code owners for portion. I'm not diving in too much, but creating rules. It's also not only for Kics. We'll talk about it soon. You can create rules almost in every tool that you run automatically. And that's a good way in one action you do to get rid of the noise that your developer complaining on. Now if you want to mount those into your kics, run. So if you remember we did it in the docker command, but we can also do it in the docker image. So we have here the docker image of a kix which is actually the take from Checkmarkix and I just copied the assets folder, which assets is actually my custom rules into the app bin assets which is the assets that kix has. Now all my queries will override the queries that Kics has and also add the queries that I added and then run kics. Easy as that. We get all our configuration, custom configuration run together with Kics. Now you must ask how I get this assets folder. So let's say for example you run in circuit CI run in GitHub action. You should have some pre step that clone the repository of your custom queries custom and created queries and put it in two kics in a runtime. Supposed to be easy if you're familiar with all those API actions. So we created a query and now we have custom run. Now we really have gas happy. And when gas happy like protocol. So now let's see what is gas protocol for happy life. When you do devsecops and you hate the noise that all those security tools bring to you, what is the protocol? First exclude. Look at the tools, look at why developer complaints and see what you can exclude. You maybe not need anything. Then if you didn't succeed with that, look what you can customize. This customization can make sure that developers know exactly what they need to do without letting you as a DevOps to mess too much with permissions and stuff like that. And also you can let them the responsibility for the thing they need to create. And then you can also create rules that the third stage, look at your tools, think how you can make them better by creating rules. And that thing is not only for kics. Almost every security automation tools that you will hear of it today or it may be run. Should have some infrastructure to create your own. Your own thing that needs to be done and need to be assessed in your organization. And in this way, I'll wish you all to get rid of noise to get better devsecops implementation in your organization and make sure you have happy smile as well as gossip. Thank you for joining me today. I was Gabriel and I'll be happy to connect each one of you on Twitter. I'm available on Twitter on LinkedIn. I'm trying to do developers. I'm trying to do developers. I'm trying to help developers make their life easier. See you around. Thank you for joining.
...

Gabriel Manor-Liechtman

Technical Leader @ Jit.io

Gabriel Manor-Liechtman's LinkedIn account Gabriel Manor-Liechtman's twitter account



Awesome tech events for

Priority access to all content

Video hallway track

Community chat

Exclusive promotions and giveaways