Searching Outside the Streetlight: Capture-Recapture Estimators for DeFi Security Issues

DeFi Security Summit 2022 · 27 Aug 2022 · 14:38

Yuchen Lin, lead security engineer at TrustToken, describes how a lending protocol team measures how well its audits and code reviews work. He explains injecting known bugs, tracked by salted hashes, to see whether auditors find them, benchmarking different bug-finding strategies, and using capture-recapture estimators to judge how many bugs remain before deciding to launch. At DeFi Security Summit 2022.

Speakers

Topics

From DeFi Security Summit 2022, hosted by DeFi Security Summit.

Transcript

hi everyone my name is ichan can you hear me okay cool I'm an engineer on the security team at trust token uh how do you move to the next slide is it scroll yeah it worked okay cool so trust token is actively developing trufi which is an uncollateralized lending protocol and we've originated uh just over 1.7 billion dollars in loans so far this will be a talk from the perspective of a relatively newer protocol not as established as maker or compound or some of the previous ones and so you'll see some of these

practices as things you might do when you're experiencing Growing Pains going from that doesn't exist to to the first or second iteration I'll start this talk with a parable so this one is often known as the streetlight effect an officer sees a drunk man searching for his keys under street lights and he asks did you lose your keys here to which the drunk man responds no but this is where the light is there's a fairly obvious lesson here but I think it's worth making it explicit namely we only search where it's easy to look even when what we want to heart when we want to um

what we want is hard to find so with this in mind uh I think there are two core questions that drive our security team which are how do we search where the bugs actually are before they get exploited and for those who care about velocity and budget when do we know when we searched enough and we can actually ship this foreign so before we can answer these uh I want to go over some lessons that trust tooken learned from my experiences in 2021 when we were just getting started with uh with this protocol about a year ago this was uh what we thought was the standard practice for releasing new contracts uh

I think this is what uh Kurtz earlier mentioned as audit driven development you write some code you submit it to an auditor fix whatever they say went wrong and then deploy it and hope for the best foreign and the results were promising at first um our team's audit reports mostly looked like this uh we you know have a couple low severity issues nothing major uh so it seems great but every couple months we would scramble to respond to an incident caused by a bug that made it past a code review on our audit this would be things like miscalculated user Rewards

or avoidable gas fees or upgrades that's almost corrupted storage that we caught ahead of time but just before you know just before it actually affected anything so very fortunately we never lost user funds due to a critical bug but it's very clear that our code review and audits clearly weren't catching what they should have so how do we actually search for where the bugs actually are and I think our perspective here is that the first step is to find better street lights and to do that we need a way to measure the quality of a light so we started injecting bugs to see

whether Auditors would find them actually a lot easier than you might think uh you write bugs that have you write code that has bugs in it um they're just unavoidable and then during code review if you notice the bug you don't fix it you don't comment on it you just you just leave it there um but what's really important is that you have to have a process to make sure that you don't forget about the bug as well so every time you um want to inject a bug you privately record a description of the bug we put this in a private repo and hash it and salt it

um and the reason we do this is so that we can send a list of hashes to our Auditors within the audit scope if we send them a list of hashes they can't come back to us and say hey like we found these bugs that you you know you'd included your code is pretty awful we can reply reply and say actually we know about these bugs before the audit started I'll actually jump back to the previous slide a bit one of the other tricks that we have is um we might give them 10 hashes and then only seven or eight of them are actually injected bugs um this is so that there's no incentive for an auditor to say oh we found you know we found all seven or eight of your

bugs we're gonna stop paying attention um so we also inject fake bugs with placeholder names um and this is just to make sure that we keep them on their toes um and so if an auditor finds most or all of the bugs we know that they're scrutinizing at least as closely as our own code reviews um I want I wanted this to be clear it's at least as closely as our own code reviews it's not saying they're doing a particularly good job if we're not doing a good job ourselves um but if they find few or no bugs then we know that they're missing a lot we can't trust that their reports is

saying our code is secure and this is the point at which we should start looking for a new auditor for the next cycle uh one thing here is that it doesn't have to go in Only One Direction uh it really shouldn't go into One Direction once we have Auditors that we can trust the next step to realize is that you can flip the Benchmark around and figure out what kinds of bugs what's uh classes of vulnerabilities the code reviews are missing that the Auditors are catching um or among the other programs that we've started we can start benchmarking things like our bug Bounty program against our formal verification efforts um

and so here we can make realizations of actually maybe we should be increasing the Bounty amounts because uh clearly the um the talent pool that's that's willing to go after the current Bounty Awards we're offering isn't uh isn't High Enough of equality and so with benchmarking uh we can have an impartial way to determine each strategy's relative effectiveness at detecting bugs and so given finite time and energy we can Target our efforts to the most effective ones so it's always possible to be more paranoid we could keep on delaying

launches and keep on saying uh you know we're not ready yet there's more and more things that we should test and check out uh but when you've got uh the CEO breathing down your neck um eventually you need to ship so how can we tell when our efforts are good enough well we can borrow some methods from population estimates uh in ecology so I'm going to gloss over a lot of critical assumptions here if there's time at the end uh and I guess this will be uh oh during the Q a session I'm happy to discuss how violating these assumptions can be very very dangerous and uh you should think carefully about I think twice before you trust the next

several slides but the basic intuition is that if you have some unknown number of bugs to catch you can measure the overlaps in your samples to estimate the total number of bugs what do I mean here's an example suppose you injected nine bugs and an auditor finds ten and of those ten eight of them overlapped with the injected bugs which is to say eighty percent of the bugs that this auditor finds are injected so if we assume that the 80 injected rate can generalize to the whole population then the total number of bugs would be approximately

the nine that were injected divided by eighty percent so just over 11 bucks in this estimate we would say we probably caught all the bugs um I'm putting fine print at the bottom uh please do ask me about the fine print because you should not trust this blindly uh and here's another example we take the same nine injected bugs and the auditor is still finding ten of them but this time there's only one in the overlap I want you to stop for a moment and reflect on what this means this should raise some red flags for your intuition because only 10 of the found bugs are injected so how many must be out there

90. we end up with an estimate of 90 bucks we're missing the vast majority of them this is an audit report that's this exact same number of found bugs and the exact same number rejected bugs but we're getting an order of magnitude higher estimate for the number of bugs that exist out there in our code so in the capture recapture literature this is something that's known as the Lincoln Peterson estimator um it's a simple and hopefully intuitive method to estimate populations uh although I will note that it gives some biased estimates for the small numbers that we typically encounter I introduced it here because I think it's the easiest to explain for

intuition but if you want more accurate estimates I would recommend that you check out um other kind of estimators in the literature this is um statistics from the 1980s or so um so things to look out at first are the Chapman estimator or the jackknife estimators uh depends on your situation so I want to bring this all back together uh for a release earlier this year we recorded all of the medium high and critical severity bugs and also which strategies found which of these bugs so in this Venn diagram uh the numbers tell you how many bugs are in each particular overlap

we used a Chapman estimator for for pairs um sorry Chapman estimator for pairs of strategies and with that we guess that there's approximately 23 bugs total so if we found 21 then that means we're estimating there's about two more that we haven't found seven of these bugs were injected during code review auditor a found eight of the bugs and these eights overlapped with all of our other strategies although only three of them overlapped with the uh with the injected bugs so we decided that they're doing an okay job and we would continue with them in the next release

auditor B only found one bug that we actually cared about and none of the injected bugs so this didn't make our cut and we had to go and search for a new auditor and replace them for the next release our bug Bounty performed pretty poorly um so we took that as a sign that we should make some changes to its format and test if that would improve the findings and we gave feedback to our engineering teams about their blind spots I think in this case a lot of it was related to verifying off-chain ecdsa signatures or updating all of the Right Storage variables when a user modifies a loan and lastly

um I think one of the the big takeaways for this for us is that we can put a lot more confidence in our formal verification team because they found 17 out of the 21 bugs so here's a recap of the 2021 audit driven developments release cycle uh and this is what it looks more like now we inject bugs by not fixing the issues that come up during code review we run audits formal verification and a bug Bounty All In Parallel on the same audit scope and commit hash this is to make sure that they're all off of the same population you're not having bugs

enter and exit and after all the reports come back we use capture recapture models to estimate how many bugs remain and this helps us decide whether the code is okay to Launch we've um we've decided to pause and actually say we're not launching things um because our audits have come back and we weren't comfortable with the level of security and after a launch we we take take the lessons we've learned and bench from benchmarking each of the bug finding strategies to decide what to change in the next cycle so some takeaways we want to see that uh

we want to see these techniques adopted as best practices across the entire industry and why is that um I think the more energy the more engineering teams inject bugs or Benchmark their audits or estimate how much they're missing the stronger the industry as a whole will become uh we think Auditors should welcome this as well they get feedback about what their audit process might be missing and this feedback doesn't come with um you know front page news reports and a bunch of bad publicity it comes from just the day-to-day practices of of doing your work and reviewing it um and uh lastly it's a it is a chance for the good Auditors to set themselves apart uh

from the ones that give rubber stamps all right that's it for me I'll leave questions for uh the discussion at the end [Applause]