Enhancing vulnerability detectors with LLM
EthPrague 2024 · 31 May 2024 · 19:35
Jan Kalivoda shows how large language models can make static analysis of Solidity smart contracts more precise. Traditional detectors miss code semantics and produce many false positives, so he combines detector algorithms built on the Wake framework with targeted prompts to models such as GPT-4. A case study on a keccak256 hash-mismatch detector illustrates the approach, and he argues that LLMs work best on specific security tasks rather than whole codebases.
Speakers
Topics
From EthPrague 2024, hosted by ETHPrague.
Transcript
[Music] okay so hello everyone uh I really appreciate that you come uh into my talk enhancing vulnerability detectors with large language models since there is currently collision with vitalic fireside chat so I really appreciate it so my name isan and I'm secretary at a key blockchain we are doing blockchain security audits uh and also developing some open source to link uh where about one of the two we will be speaking today also we
are on boarding developers to blockchain at the local University or we are occasionally doing some online curses we work in past with clients such as 1 in Lio safe or excelr so that's just the interaction about myself and the company and uh we need to start with static analysis then we dive into its interconnection with the AI so uh I would just like to ask uh please raise your hand who knows something about static analysis awesome and who's actively using that during the development yeah maybe we will we will
get to the reasons why it is uh in this way so static analysis is basically about extracting some informations from the code and we can do it in two ways uh and first one is detectors where we are basically searching for some patterns that can lead to vulnerability or some code quality issue and the second way is just about printing some useful informations about the code such as uh you want a printer which will print you all only owner modifiers in your codebase and you can see all the invocations and the respective functions of these modifiers so it can be uh handy when you are trying to understand some
codebase uh and so on uh yeah so there is uh example of some detector uh if you know SL uh or other static analysis tools are entrance detector is usually the first one which is implemented and this is example of the output where you can see that uh at some position in the code uh there there can be some possible Rance and you see there that uh uh sub detections uh which uh uh could be the attack vectors uh then uh example of a printer is for example for storage layout where if you are doing uh contract
upgrade upgrades then uh you can print your storage before and after upgrade and you can see if there are some clashes in the storage and uh this brings us to the tool link so uh the static analysis to link uh is mostly based on some sort of intermediate representation model that is built on top of the as which is produced by the solidity compiler so when you want to have some static analysis to link you will probably need some IR model and uh there are currently two leading Frameworks uh and that's the W and slitter which built open API over their intermediate representation model
so example this is just a big picture we don't need to dive into uh much but uh this is how the iron not iron noes and the Vol three of the model looks like uh so if you will just uh stay at the top we have there uh contract definition in the in the uh green square and after that is function definition so we can check it on the example where we have some contract for example that contract has two functions get token storage and write token storage and we want to write a printer so if we will be using wake we can just simply add this one function which is uh called which is a special
function called visitor function and this visitor function is uh just jumping over all the nodes uh in the intermediate representation model and this exactly this visit function is jumping over the function definition nodes so uh in the body of the function we have two prints where we print uh like the name of the node and then the parent uh here you can see that if we will run the printer over the contract which is above we will get printed uh the function names and uh the contract where they are placed so uh this brings us to P Falls
of static analysis where the biggest problem is that the full algorithmic approach is not always sufficient because the traditional static analysis does not understand uh code semantics so it means that you can have in one code base there can be some valid detection and uh for one specific detector and in the other one where it is uh like almost the same it will not be uh an issue because uh let's imagine that in one code base you are working always with one token and in the second one you can have uh any token uh uh to interact and so in the first case it won't be a valid
detection because uh the token will be always the same and for the one case uh it is safe but for the multiple cases it won't be uh and uh we can recognize this uh easily uh with deter static analysis uh when uh uh even to when we are using some heris techniques and so on so if we want to do a safe approach where we will uh like uh report all the possib detections uh instead of just don't report it we will get to high false positives numbers and that's probably the reason why a lot of developers are not using it because it will just uh
pollute the uh output of your terminal and so on and you don't want just to dive into the all the false positives and check it so we need some sort of human check and this is where the AI steps in and we want do it this way like you can use it generally for some uh recommendations what can be for example some attack vectors and just discuss the contract uh with uh GPT in general but uh we want to be smarter we want to combine the techniques of the static
analysis and uh the power of these large language models so the human check can be performed by these language models by combining some specific prompts with algorithms in static analysis uh we were testing that uh on GPT 3.54 and CLA uh and uh basically on some specific cases gp4 was just enough uh to be like very successful so uh to explain it better we have a case study and uh it will be about a detector that is called kak 256 differentes which
can be kind of confusing name but uh what it what it is doing is pretty simple uh the detector can recognize difference between expected hash and the hash that is used in the code so there is a like a developer convention when you are using some magic numbers in your codebase then uh you have there uh code command which explains the magic constant to not confuse uh any code revie other developers and so uh just do not uh add some issues in a future development so exactly when you are using for example hashes for storage locations then uh usually there is a
code command which which has uh some sort of string that explains the preimage of the hash uh and the detector is already implemented so on the screenshot you can see uh the output uh of uh nvs code where is uh where can be seen that there is a mismatch in the last symbol so how to implement it so some knife implementation could be like a detect code command near the variable declaration then extract the expected HH per image and calculate the hash from the preimage and compare with the hashes in the
code so but there is an issue that uh you can use some rxes heris techniques and so on but uh you won't probably catch all the cases uh so uh there can be like a wallet codee there can be uh like some redundant symbols uh there can be like wall of text in which will there will be hidden uh some text explaining what's the pre-image or uh and so on so if the human will be reading the code he will probably find out uh what was uh the idea how was chosen the specific hash but uh uh it's hard to catch all
the Ed Edge cases is without some like more personal check so this is what we are going to address uh we want to extract this uh this uh pre-image from the code command with the uh language model so the implementation will be uh pretty straightforward we just want to start with some pre-processing part where we will use static analysis to find byes 32 constants in the code base there is just uh a snippet uh uh down which uh does the all uh the logic for that and it's very similar as we shown uh at the beginning how we can iterate
through the function so uh we just need to find uh not the functions but that bytes for the2 declarations when we have that we can extract uh the nearby code command uh find the so find the relevant text and uh send it uh uh to language model then we get some output uh and that's the thing uh we need to somehow parse it uh so if you have a constant expression evaluation engine then you are probably happy or you can insert the output to solidated template which you can just
imagine like a contract where you will you will get some wallets solidity code and you will place it into the function in the contract so then you are able to compile it and get the value uh and the third option probably most straightforward is just to interpret the output as a python code and use safe EV all where the third option is implemented in the snippet on the right so uh it's not so complicated so uh but it is possible that some of these approaches fail that you will uh get for example long sentence uh from the uh from the GPT or some invalid
output uh so you you want to send the error back uh explain it to the language model so uh the language model will attempt to fix it and process is repeated when the evaluation succeeds the HH calculated from the code command is compared with the value in the code so just high level the architecture is that we will start with compilation which will generates intermediate presentation model for us then we will do the detector pre-processing so we don't want to send all the source codes uh to the language model just uh some small strings which are enough and uh
this will be sent to the language model that will try to extract the pre-image and uh then we then there is the postprocessing part where we are trying to evaluate it if we fail we will send a fix request which is another prompt so they are figuring two prompts for uh for the language model and then it will try to extract the pr image again and uh in the end we will compare the ases so uh deting uh like when you start uh deel developing with d language models and get more into it it can be pretty hard just to force to uh language model to answer with a code it's still
doing things like I apologize for the confusion and uh pollute the output with some sentences and so on uh so you need uh the best way what we found that uh you can place some special sentence in the end of The Prompt which is the basically the last thing that uh the language mod model read so uh he will keep it in bite and can you send the output what you need and other thing is to get the stable and consistent outputs so you will send 100 times the same pre-image or the same text and he will always extract uh it in the same way this can be done uh when you change the attribute
called temperature to zero which is uh you can imagine it as a as emotions of GPT so so uh uh the output won't be so emotional and so human and then there is some uh also important thing is to cach their responses so for example when you are developing the detectors are rerun with all the code change and you don't want to send the request all the time so uh for example if you will be working in the team you can have some cash for the team or uh uh it depends on the level of what you you need but Cushing is uh important and I have there the special
sentence for you like this one is exactly what we are using in decode and it starts with a take a d breath uh it's might sound funny but these words are uh really working take a deep breath calm down or from the other side uh you can say you are paid for that uh do it or will be fired and uh sentences like that really works uh and then we get to some other use cases uh for example uncheck return value detector it is also one of uh the detectors that are like polluting the
output with a lot of false positives so uh developers sometimes don't want to check for the return Val values intentionally and and uh this can just help to somehow filter these false positive cases so uh May the rate lower and this second case can be for example for underflow overflow detector which can help you to discover some more complicated scenarios for example when you are combining uh assembly with solidity and you are getting some very complicated statements which can for example go wrong in in the places where you will would expect to then uh uh the
language model can again help you this time to bring the bigger through positive rate so the summary is that uh uh in our opinion language model can help you definitely to make more precise detectors and also it opens like a doors to the word of the detectors that we won't be able uh to create uh with the traditional itic analysis so uh it can be definitely effective for a specific task rather than running it over the Vol code base as we shown on the one slide uh which uh without any fine tuning or at least for
now uh uh it uh won't be usable but maybe uh after a few years we can just run it over the code base and we don't need a job and that's it so if you will be more interested in tooling then after this there is a session about uh vs code extensions uh otherwise uh in the end of the day we have their fuzzing workshop and in the Sunday there is a talk about a vake which is the tool what uh uh we were using for developing of these detectors and uh that's it do it talk so thank you
[Applause] [Music] [Applause] any questions okay uh okay just please wait for a mic have you tried to use something except GPT for maybe I don't know some custom yeah uh we've tried uh and we've tried it I think like like a year ago and it doesn't have so good outputs like uh GPT but maybe uh if you will try it today
it's rapidly evolving maybe it will be better but yeah sorry did you try did you try to train your own model on your example data not yet mhm I got it okay thanks okay that's it thank you [Applause]