[00:00.000 --> 00:04.160] Hey, everybody, and thanks for coming to this talk. This is The Ballot is Busted Before the [00:04.160 --> 00:07.940] Blockchain, a security analysis of votes, the first internet application used in U.S. federal [00:07.940 --> 00:12.580] elections. My name is Mike Spector, and this is joint work with Jimmy Koppel and Danny Weitzner, [00:12.580 --> 00:17.500] and all three of us are from MIT's Computer Science and Artificial Intelligence Laboratory. [00:18.420 --> 00:22.580] All right, so let's talk a bit about voting. In February, the state of West Virginia abruptly [00:22.580 --> 00:26.920] abandoned plans to adopt an internet voting phone app called Votes, and this research is actually [00:26.920 --> 00:32.140] why. I also think this serves as a great case study for explaining why we should be careful [00:32.140 --> 00:36.420] before advocating for new technologies and civic processes, and it really highlights [00:36.420 --> 00:42.560] the need for transparency and accountability in election systems in particular. So our story [00:42.560 --> 00:46.920] starts in late 2019, when it became clear that West Virginia was going to pass a bill directing [00:46.920 --> 00:51.160] their Secretary of State to allow disabled voters to cast their ballots over the internet. [00:51.380 --> 00:55.520] This is really important in the context of West Virginia, because the state has a higher than [00:55.520 --> 01:01.600] average number of disabled voters. For example, according to the CDC, 22% of adults in West [01:01.600 --> 01:07.520] Virginia have some serious difficulty walking or climbing stairs. Another 7.7% have some [01:07.520 --> 01:12.460] sort of vision impairment. Interestingly, West Virginia had already been using Votes [01:12.460 --> 01:16.420] for overseas military voters, and we expected that they were going to be used for this expansion as [01:16.420 --> 01:23.480] well. So given the potential impact, we really wanted to know how Votes provided what are often [01:23.480 --> 01:28.640] considered to be the essential security requirements of voting. In the crypto literature, [01:28.640 --> 01:35.580] these are defined as correctness, privacy, receipt freeness, and coercion resistance. These bottom [01:35.580 --> 01:39.620] three properties are there to ensure that the voter isn't unduly pressured to vote in any [01:39.620 --> 01:46.520] particular way and can't sell their vote. Really interestingly, Votes advertised heavily on the use [01:46.520 --> 01:51.060] of cryptography and cryptographic tools. In particular, they said they used hardware-backed [01:51.060 --> 01:56.440] storage, mixed nets, and of course, because every app has to do this now, the blockchain. [01:57.200 --> 02:02.920] The question that we had was, you know, is this app meant to be N10 verifiable, right? And N10 [02:02.920 --> 02:08.780] verifiability is a guarantee that allows a voter to tell if their ballot was counted correctly in [02:08.780 --> 02:14.200] the final tally. And given the use of the tools that were purported to be used here, the expected [02:14.200 --> 02:19.740] guarantee of the system. What was really interesting about Votes to me is that if you took a look at [02:19.740 --> 02:25.080] them from sort of a large distance, they look really good. For instance, they had this bug bounty [02:25.080 --> 02:31.000] by HackerOne. They had undergone a couple of security odds from people outside of the company. [02:31.120 --> 02:34.740] There's even some documentation of how their system worked. But the more you looked at them, [02:34.740 --> 02:39.720] the more red flags you saw. For instance, let's look a little bit at their documentation. [02:40.520 --> 02:46.420] Their documentation consisted mostly of this FAQ, and here's a link to the version that we saw in [02:46.420 --> 02:50.880] the beginner analysis. Importantly, there was no formal description of how their system actually [02:50.880 --> 02:55.740] worked. And this was a bit odd, given the fact that the use of the crypto would really imply [02:55.740 --> 03:00.520] something novel that might require further explanation. There was a number of security [03:00.520 --> 03:05.420] reviews that were claimed to have occurred, but none were actually made public. And in fact, [03:05.420 --> 03:09.340] there was no public list of fixed vulnerabilities at all, which led us to believe that either the [03:09.340 --> 03:13.740] security reviews were just being kept secret, or the security reviews themselves hadn't found [03:13.740 --> 03:18.180] anything, in which case it's sort of unclear if they were any good. These reviews were done by [03:18.180 --> 03:23.240] the National Cyber Security Center and Shift State Security, two entities I'd never heard of before. [03:23.820 --> 03:28.720] The NCC was sort of interesting to look into as well. Their name originally gave me the impression [03:28.720 --> 03:31.920] that they were somehow associated with the government, and I was really surprised to learn [03:31.920 --> 03:37.160] that they weren't. They also appeared to me more of a trade association, and I couldn't find a [03:37.160 --> 03:41.520] staff cryptographer or security researcher there that I could reach out to and ask further questions. [03:43.740 --> 03:49.300] So, you know, at a first glance, many of the cryptographic guarantees that they tried to [03:49.300 --> 03:55.760] claim in the FAQ were sort of interesting, and they look like they're real hard things [03:55.760 --> 04:00.540] to achieve. But in reality, there's really no formal definition for any of these things. [04:00.540 --> 04:05.780] For example, N10 vote encryption really doesn't mean anything, but if you squint at it, it sort [04:05.780 --> 04:12.260] of looks like N10 verifiability. So we really weren't clear on what to make of this whole thing. [04:12.800 --> 04:17.740] All right, so let's look a little bit at their bug bounty. The FAQ bragged quite a bit about [04:17.740 --> 04:22.280] having a bug bounty, and don't get me wrong, having a bug bounty at all is fantastic, except [04:22.280 --> 04:25.980] when we took a deeper look, we found it to be sort of less than encouraging. [04:26.920 --> 04:32.140] You were required to use this special version of the Votes app, which connected to a bunch of [04:32.140 --> 04:36.980] different servers from the live version, and there was no documentation of the differences between [04:36.980 --> 04:40.500] the bug bounty and production, right? And as a researcher, this is sort of dangerous, because [04:40.500 --> 04:44.580] I really would like to know what the actual version of the app is doing versus what's [04:44.580 --> 04:50.180] happening in the special environment. It also had really limited scope. For instance, we weren't [04:50.180 --> 04:54.940] allowed to look into man-in-the-middle attacks, and there was nothing allowed that required [04:54.940 --> 04:59.400] physical access. But they never really defined what physical access meant. So if I used a jail [04:59.400 --> 05:04.160] break to simulate a root exploit and then found a bunch of things that I could do with a piece of [05:04.160 --> 05:08.860] malware that happened to have root on the system, it was unclear if that actually was in or out of [05:08.860 --> 05:15.060] bounds. And the test infrastructure provided was also sort of wonky. There was no binary source [05:15.060 --> 05:21.000] for the servers or the server infrastructure to set up yourself, so you had to rely on their [05:21.000 --> 05:29.510] systems. And when we first tried the app, it actually wouldn't connect at all. To make things [05:29.510 --> 05:35.930] even worse, both the live and bug bounty version of the apps were obfuscated. For context, with [05:35.930 --> 05:43.750] Android reverse engineering, everything is really an APK. And APKs themselves are made up of a bunch [05:43.750 --> 05:50.330] of Java classes and metadata in the form of XML. And what's really cool about APKs is that they, [05:50.330 --> 05:55.690] for the most part, will decompile to source, with the exception of C compiled libraries or [05:55.690 --> 05:59.890] something like that that are attached in there. But the Java stuff will almost always decompile [05:59.890 --> 06:04.630] to source. So we popped those into a decompiler, and the first thing that we noticed is that [06:04.630 --> 06:09.430] all function names, class names, and variable names had been changed into these random Unicode [06:09.430 --> 06:15.530] strings. This really isn't normal and is the kind of thing that's done as an additional step by some [06:15.530 --> 06:21.050] automated obfuscation tool to make static analysis more difficult. Maybe this was done on accident, [06:21.050 --> 06:25.250] but there was other things that led us to believe that it wasn't, right? So, for instance, [06:25.250 --> 06:29.070] later on in our reverse engineering process, we noticed that there was a bunch of string [06:29.070 --> 06:36.930] obfuscation going on. So, for instance, in normal cryptographic code, in Android, you'll see strings [06:36.930 --> 06:42.950] like ASGCM used. And instead, we would see this weird function call with a series of numbers after [06:42.950 --> 06:47.170] the fact. And if we actually looked into the function, what you'll see is this. And this is a [06:47.170 --> 06:54.750] really common runtime string deobfuscation technique. And I rarely have seen this in the [06:54.750 --> 07:01.150] context of consumer software, except out of things like game kits and DRM kits. I've mostly seen this [07:01.150 --> 07:06.310] in cases of, say, hiding malware command and control. So, this is sort of out of the ordinary [07:06.810 --> 07:11.210] and interesting. And as a reminder, this is the bug bounty version of the app. And this is the [07:11.210 --> 07:14.450] version of the app that they're trying to get us to do analysis on. And there's all these sort of [07:14.450 --> 07:19.930] dodges to make it more difficult. Things also got a little interesting if you look at their safe [07:19.930 --> 07:25.070] harbor provisions. These are the conditions that they put on researchers before the company agrees [07:25.070 --> 07:32.170] not to pursue legal action after you report a bug. The restrictions I'm reporting seem to be [07:32.170 --> 07:38.330] the following. First, you must give votes reasonable time to patch bugs. And the second is that votes [07:38.330 --> 07:43.250] retains the authority to decide what reasonable time means. Taken together, this means that votes [07:43.250 --> 07:48.410] could just hold on to bugs indefinitely. And to me, this sort of misses the point of using a bug [07:48.410 --> 07:53.270] bounty as a transparency tool altogether. If the point is to let us security researchers hold the [07:53.270 --> 07:58.310] company accountable to actually fix the bugs we discover, then there needs to be some sort of [07:58.310 --> 08:05.510] time limit here. To make matters worse, a previous attempt at security analysis appears to have [08:05.510 --> 08:12.430] resulted in a University of Michigan researcher being investigated by the FBI. In fact, votes' CEO [08:12.430 --> 08:17.230] was quoted by CNN taking credit for reporting the researchers to the authorities. And we never [08:17.230 --> 08:22.150] found any indication that the company was bothered that it turned out to be a researcher rather than [08:22.290 --> 08:29.410] a malicious entity. To be fair to votes, though, there was this quote in the bug bounty that [08:29.410 --> 08:36.570] explicitly banned examination of the non-bug bounty version of the app. However, the bug bounty's edit [08:36.570 --> 08:41.110] history tells us that this restriction was added after the University of Michigan researcher was [08:41.110 --> 08:48.030] reported to law enforcement. So I can't believe I have to say this, but the first unwritten rule [08:48.030 --> 08:53.770] of bug bounties is do not send the law after well-meaning security researchers. Flashing a bit [08:53.770 --> 08:58.450] forward in the talk, this combined with the rhetoric afterward really complicated our ability to [08:58.450 --> 09:03.550] disclose the results of our work. All right, so overall we found a bunch of issues, right? There's [09:03.550 --> 09:08.390] no formal documentation of the system, there was these weird security claims, there were no public [09:08.390 --> 09:13.830] security audits, the code itself was really obfuscated, and the bug bounty as a whole seemed [09:13.830 --> 09:19.510] kind of dubious. But really we needed to do this analysis, the impact was too great, so we did it [09:19.510 --> 09:26.030] anyway. All right, so a key challenge here was that we really didn't want to touch anything that could [09:26.030 --> 09:30.810] possibly cause harm to an election, and therefore we had to make a number of assumptions about the [09:30.810 --> 09:35.870] back end. Our solution was to manually reverse engineer the app and iteratively re-implement the [09:35.870 --> 09:41.690] server to better understand the protocol and app functionality. For analysis, we always assume the [09:41.690 --> 09:46.710] best possible situation for the back end, and whenever we deviated from this assumption, we [09:46.710 --> 09:52.550] explicitly discussed why in the paper. All right, so let's take a very quick tour of the app from [09:52.550 --> 09:59.710] the voter's point of view. Initialization is very similar to any other app. You're asked to use the [09:59.710 --> 10:05.010] sort of standard one-time password, you're asked to provide an eight-digit PIN, then you're asked to [10:05.010 --> 10:12.590] log in via fingerprint, and finally you are officially part of the system. At this point, however, you're [10:12.590 --> 10:18.350] still not verified as a real voter, so the way that Votes allows you to become sort of identified in [10:18.350 --> 10:25.470] the system is you provide some sort of physical ID. And how they do this is that they ask you to [10:25.470 --> 10:31.190] take a picture of your ID, and they ask you to take a picture of your face, and then they upload it [10:31.190 --> 10:37.330] somewhere and do some matching, and eventually the user is told that they have successfully been [10:37.330 --> 10:43.010] verified. Now, at this point, the voter can actually participate in elections, which looks something [10:43.010 --> 10:48.550] like this. Here's an actual ballot. Finally, they can review and submit their ballot. They're asked [10:48.550 --> 10:56.430] to verify and log in again using their biometrics, and finally they have voted. From their FAQ and [10:56.430 --> 11:01.390] reports from the pilots, we found out that the users emailed an encrypted receipt of their vote, [11:01.390 --> 11:06.330] which appears to actually contain their real selections. It's really not clear how this receipt [11:06.330 --> 11:10.590] ends up working in practice, but we did find this screen in the app which provided a password [11:10.590 --> 11:16.810] for decryption. From what we could find in the literature, really there's no intent-verifiable [11:16.810 --> 11:23.210] voting system that really works this way. All right, so let's talk about what happens behind [11:23.210 --> 11:29.350] the scenes. In reality, Votes is for the most part just a REST app, which means it's a bunch of [11:29.970 --> 11:36.070] HTTPS GET and PUT requests to a centralized API server. In addition, there's two other entities [11:36.070 --> 11:41.670] that you should be aware of. The first is Imperium, which is a third-party antivirus which Votes uses [11:41.670 --> 11:47.890] to detect all sorts of stuff going on in the system, and a third-party ID verification service [11:47.890 --> 11:52.350] called Jumeo. So if you look at the network itself, it looks something like this. [11:52.390 --> 11:58.330] Solid lines here delineate a connection that we were able to actually observe or find in the [11:58.330 --> 12:05.990] documentation. Dotted lines are things that we sort of suspect exist. All right, so let's talk [12:06.110 --> 12:12.610] a little bit about attacks. Let's consider this scenario where an attacker has gotten control over [12:12.710 --> 12:17.410] a user's device and loaded some malware. The first thing that this malware would have to do is [12:17.410 --> 12:23.790] actually defeat Imperium's malware detection. Imperium is initialized on app creation. So when [12:23.790 --> 12:28.610] the app first loads, it begins scanning, and then after every app resumes, so if you were to leave [12:28.610 --> 12:32.830] the app and go to your web browser and come back, it'll then do another scan. It looks for a bunch [12:32.830 --> 12:38.110] of things like known exploits slash malware, any indicators of jailbreak, debugging, or modding, [12:38.110 --> 12:43.390] and it's a bit of a snitch, right? If you're caught, it will alert both the Votes API server [12:43.390 --> 12:49.070] and its Imperium servers, and if we had to guess, this is probably what caused the University of [12:49.070 --> 12:53.690] Michigan researcher to be caught. The thing about Imperium is that it's really not meant to stand [12:53.690 --> 12:58.410] up against targeted attacks, right? Defeating this is really easy, it turns out, if you have [12:58.410 --> 13:04.090] root on device. In particular, we can inject code into Java runtime and modify it to stop Imperium [13:04.090 --> 13:09.870] from ever really being initialized. This might sound super complicated, but this is almost all [13:09.870 --> 13:13.910] the code that's actually required. This sort of thing is really common and well supported by the [13:13.910 --> 13:19.890] tools in the modding community. And without Imperium, right, the attacker has complete control [13:19.890 --> 13:25.070] over the user's device, and any receipt that you would receive over email is also likely compromised [13:25.070 --> 13:31.870] as well. And there's really not much that can be done to prevent this. Again, Votes does not appear [13:31.870 --> 13:39.390] to be end-to-end verifiable. All right, so maybe you don't buy this attack, maybe you think that [13:39.390 --> 13:44.010] it's a little difficult to get malware on the system a priori. You know, what happens if we only [13:44.010 --> 13:50.850] get access to the device after a vote has been cast? All right, so what's really interesting is that [13:50.850 --> 13:56.150] there's an encrypted database that contains all of the user's vote history and everything that [13:56.150 --> 14:02.270] is needed to authenticate as the user to their server. This database is encrypted using a secret [14:02.270 --> 14:08.770] key, which is derived from the user's PIN and the salt. The salt is a random value that's stored on [14:08.770 --> 14:14.830] disk unencrypted. The PIN, however, is also stored on disk, but it is encrypted using the Android [14:14.830 --> 14:19.030] Keystore, which means the keys are stored in this hardware enclave and never accessible to the app [14:19.030 --> 14:24.130] itself. And it requires a user's fingerprint or biometric to decrypt, and this is actually kind [14:24.130 --> 14:30.770] of okay, right? So it looks great. Except that the PINs themselves are only eight digits and numeral [14:30.770 --> 14:36.570] only. And of course, you know where this is going. 10 to the 8 combinations means that there's roughly [14:36.570 --> 14:42.790] 100 million PINs. And if we copy the database from the device onto our laptop and create a very [14:42.790 --> 14:48.830] short Python script to try to brute force it, we found that it takes roughly 0.05 milliseconds per [14:48.830 --> 14:55.390] attempt so that you can try all these PINs in roughly 1.6 hours. Indeed, we were able to get [14:55.390 --> 15:01.850] complete access to the voter's entire vote history and their authentication data, meaning that anyone [15:01.850 --> 15:07.050] with forensic access can brute force the PIN, control the voter, and see how they voted. [15:08.350 --> 15:10.250] All right, let's talk about the server. [15:12.070 --> 15:16.150] Now, on device, you can really just get access to one particular user, of course. [15:16.230 --> 15:20.570] The server has access to far, far more. And what's really interesting is that Votes use this [15:20.570 --> 15:25.190] custom crypto protocol between the device and the server. It looks something like this. [15:25.530 --> 15:30.710] First, the device will establish a standard HTTPS connection to Votes' API server. [15:31.270 --> 15:36.750] Then, on top of HTTPS, it'll perform the following non-standard homeworld crypto algorithm. [15:37.070 --> 15:43.930] First, the device generates 100 ECDSA key pairs. It'll then immediately discard all [15:43.930 --> 15:49.950] but the 57th secret key. Then, the device sends all 100 public keys to Votes' server. [15:50.070 --> 15:54.630] The server will generate its own 100 keys and perform a key agreement with the center's 57th [15:54.630 --> 16:00.150] public key and generate a random value that will later be used as an AES-GCM shared key. [16:01.070 --> 16:07.050] It'll then encrypt this AES-GCM key with the ECDSA shared key, this 57th [16:07.050 --> 16:11.930] key, and sends the client, the server's 100 public keys. [16:12.070 --> 16:16.630] Finally, the phone performs its own key agreement and decrypts the AES-GCM key. [16:17.570 --> 16:23.790] So, from this point forward, all communication is additionally encrypted using AES-GCM. [16:24.630 --> 16:29.930] The thing is that was actually 100% of the crypto in the protocol used between the device and the [16:29.930 --> 16:36.590] server. The app actually never sees anything from any blockchain. And this includes what we would [16:36.590 --> 16:41.750] expect to exist in an ecosystem like this, which would be a proof of inclusion. The app actually [16:41.750 --> 16:48.270] never even verifies the server's public key outside of the standard HTTPS connection. So, [16:48.270 --> 16:52.950] active man-in-the-middle attacks are still possible if HTTPS is broken. There's also no [16:52.950 --> 16:58.090] non-ephemeral public keys sent from the device, and nothing is ever even signed. And the summary [16:58.090 --> 17:03.970] here is that the API server can really do anything that it wants, which sort of begs the question, [17:03.970 --> 17:09.770] what's the point of having this blockchain? All right, you know, maybe you think that it's [17:09.770 --> 17:14.790] impossible for someone to even get access to votes as servers. We're not worried about nation-states [17:14.790 --> 17:20.030] here. Let's talk about the least powered possible adversary, a passive network adversary. [17:20.810 --> 17:25.190] Now, that protocol that I mentioned, that I explained before, was non-standard and has [17:25.190 --> 17:30.670] unclear security benefits, but it isn't inherently insecure on its own. But it does make this other [17:30.670 --> 17:35.570] attack way worse. But first, I have to explain how votes are cast. On the left is what a ballot [17:35.570 --> 17:40.610] looks like in-app when the user is selecting their preferred candidate and example election. [17:41.490 --> 17:46.050] This is generated from JSON strings sent by the server, which are variable length, [17:46.050 --> 17:51.090] depending on the description of the candidate, various URLs, and other metadata. For example, [17:51.090 --> 17:58.010] you can see the corresponding JSON sent from the server on the right. When a vote is submitted, [17:58.010 --> 18:02.750] you might expect that it just sends some ID numbers, but instead what it does is it sends [18:02.750 --> 18:09.110] all metadata for the voter's choice, but only that candidate's metadata. The result is a textbook [18:09.110 --> 18:14.670] side-channel attack, which again is made far worse by votes' custom crypto. In normal HTTPS, [18:14.670 --> 18:19.290] the plaintext is somewhat obfuscated by gzip compression. In votes' protocol, however, [18:19.290 --> 18:24.210] the plaintext is encrypted before gzip even gets a chance. The result is that if you know the [18:24.210 --> 18:28.530] lengths of the ballot options, you can very obviously tell which of the options the voter [18:28.530 --> 18:38.090] selected because you cannot effectively compress encrypted data. This image graphs the size of [18:38.090 --> 18:41.870] packets sent from the device to the server immediately after a submission for the candidate [18:41.870 --> 18:47.730] with the short description and the candidate with the long description. Note that you can clearly [18:47.730 --> 18:53.090] tell which packet is the vote submission and which run is for the long candidate and or short [18:53.090 --> 18:58.470] candidate. The end result is that a passive network adversary like, say, the user's ISP [18:58.470 --> 19:05.410] or the insecure coffee shop Wi-Fi that they're voting from can easily determine ballot selections. [19:06.610 --> 19:11.170] All right, scenario four. Let's talk a little bit about privacy and informed consent. [19:13.690 --> 19:19.750] Jumeo is this third party that actually does a series of things for votes in this ecosystem, [19:19.750 --> 19:25.370] including liveness detection, some machine learning to match the selfie and the voter's ID, [19:25.370 --> 19:29.830] and performs OCR on the ID. What's really interesting here is that none of this is [19:29.830 --> 19:34.930] actually done on device. In fact, Jumeo's servers actually gets both of these images, [19:34.930 --> 19:40.830] which include all of the voters' personal information, like their driver's license ID, [19:40.830 --> 19:49.030] as well as their location via GPS. And the only place that we could find either in their [19:49.030 --> 19:55.670] votes as documentation at the time, or in the app itself, were these very small translucent logos [19:56.190 --> 20:02.110] at the bottom of these two particular screens. And I'm not normally a privacy nut, but in this [20:02.110 --> 20:07.630] case, you got to remember that this app was being used for soldiers in war zones. So at this point, [20:07.630 --> 20:14.710] it's actually somewhat of a national security issue. All right. So in sum, we found five high [20:14.710 --> 20:20.150] severity vulnerabilities and a really serious privacy issue. Interestingly, many of the issues [20:20.150 --> 20:26.770] we found were really basic implementation failures. This included a mandated use of weak passwords, [20:26.770 --> 20:31.430] their anti-tamper slash AB solution was really easily circumventable, the side channel attack [20:31.430 --> 20:37.110] that we described earlier, right? And again, like the API server had complete control over [20:37.110 --> 20:43.070] all users in the election. It's also really unlikely that any of this is N10 verifiable or, [20:43.070 --> 20:47.530] and it's unclear from what we saw that this could possibly be receipt-free or coercion-resistant. [20:48.150 --> 20:52.590] Below is a summary of the powers of a given adversary, and I won't dwell too much on this [20:53.050 --> 20:56.790] here, but if you read the paper, we go into much further detail. [20:57.450 --> 21:02.010] What's really frustrating about all this is that none of the attacks we found were really novel. [21:02.210 --> 21:06.450] I really started this research hoping to find some crazy new crypto, and instead I basically [21:06.450 --> 21:14.810] found the standard CRUD app. So at this point, we really needed to talk to somebody, and I'm a huge [21:14.810 --> 21:19.150] believer in responsible disclosure, and we really didn't want to hurt an ongoing election, but there [21:19.150 --> 21:24.790] was a real sense of urgency. And remember, for context, the DNC had just announced that it was [21:24.790 --> 21:30.470] going to use a voting app to count ballots for Iowa's primary, and as far as we knew, votes was [21:30.470 --> 21:35.530] what they were using. We actually really didn't think that the DNC would be crazy enough to try [21:35.530 --> 21:40.790] to launch an app right before an election. So the first thing that we did is we contacted the [21:40.790 --> 21:46.990] MIT BU Law Clinic, who were fantastic, and we sort of ran immediately into this very pernicious [21:46.990 --> 21:56.110] problem. And again, this is why Rule 0 of bug bounties exists. Both law enforcement and votes [21:56.110 --> 22:02.630] seem to have used this rationale for reporting the researcher that it was somehow required due [22:02.630 --> 22:08.810] to this designation as critical infrastructure. And, you know, we actually kind of agree that [22:08.810 --> 22:13.570] voting infrastructure is critical infrastructure and really should be treated this way. So rather [22:13.570 --> 22:19.450] than reporting to votes, we reported to CISA, the part of DHS that is responsible for digital [22:19.450 --> 22:25.470] critical infrastructure. CISA here was fantastic, professional, and wonderful. They allowed us to [22:25.470 --> 22:30.770] report the vulnerabilities to both the vendor and those affected without putting ourselves at risk. [22:30.770 --> 22:34.970] Once we had confirmation that there were no active users of the app, we then released a [22:34.970 --> 22:42.150] preview of this paper. The media attention was immediate and effusive. We got a number [22:42.150 --> 22:48.390] of responses from both civil society and other researchers that were all very, very positive. [22:48.390 --> 22:54.210] Senator Ron Wyden spoke in support of our findings and sent a letter to SHIFT State [22:54.210 --> 22:59.070] Security asking for further information about why, for instance, they hadn't found the same [22:59.070 --> 23:03.510] bugs that we had. And I think that the reason everyone was immediately so sure of our results [23:03.510 --> 23:08.150] actually has a lot more to do with votes' response to us, which, to put it frankly, wasn't very [23:08.150 --> 23:12.770] encouraging. They appeared to have two main concerns with our work. First, that we somehow [23:12.770 --> 23:16.710] used an older version of the app, which, by the way, wasn't true. I literally have no idea where [23:16.710 --> 23:21.630] this 27 version thing came from. We used the most recent version of the app at the time of analysis. [23:22.130 --> 23:28.950] And the second was that somehow our methodology was flawed. Interestingly, votes never really [23:28.950 --> 23:33.350] denied the vulnerabilities themselves. And attacking the methodology without denying the [23:33.350 --> 23:39.590] results is a really classic dodge. For example, Diebold did the exact same thing when Princeton's [23:39.590 --> 23:44.190] research on the Acuvo TSX came out. And it's worth noting that third parties were able to [23:44.190 --> 23:52.150] independently verify Princeton's findings after the fact. Speaking of which, about a month after [23:52.150 --> 23:56.590] we released our report, Trail of Bits, a really well-known security firm, revealed that it had [23:56.590 --> 24:02.790] been contracted to do a full source code review of votes. And Trail of Bits' report couldn't have [24:02.790 --> 24:08.870] been worse for votes, right? Not only validated our methodology, but also quoted votes as objections [24:08.870 --> 24:15.030] to our work and explicitly rejected all of them. It also confirmed all of our bugs and revealed [24:15.030 --> 24:21.590] that the company had been alerted to their veracity before they spoke to the press. They [24:21.590 --> 24:25.550] also revealed that Zemperium wasn't running during the pilots, also that it was a blacklist. [24:25.550 --> 24:30.690] They also found no evidence of a mixed net and confirmed the system was not end-to-end verifiable. [24:31.490 --> 24:37.130] They also found roughly 40 other bugs and vulnerabilities. So this is all sort of a [24:37.130 --> 24:41.450] mess. It's sort of important to do a little bit of retrospective and figure out how we got here. [24:41.450 --> 24:46.050] I think that there's a tension here that can be summarized pretty well in this quote by Bradley [24:46.050 --> 24:50.130] Tusk, who was the philanthropist that funded Votes is Use and seems to be really focused [24:50.130 --> 24:55.250] on expanding internet voting. He says that it's not that cybersecurity people are bad people, [24:55.250 --> 25:01.430] per se. I think that it's that they are solving for one situation and I am solving for another. [25:01.710 --> 25:07.890] They want zero technology risk in any way, shape, or form. I am solving for the problem of turnout. [25:09.130 --> 25:12.510] And while I really do agree with the overall goal of solving this particular problem, [25:12.990 --> 25:20.670] the issue is that introducing new technology tends to introduce new and unexamined risks. [25:21.230 --> 25:26.270] And in this case, this is all really compounded by asymmetric information. And here's what I mean [25:26.270 --> 25:31.150] by that. Election systems in the US are fractured and purchasing decisions are made locally, right? [25:31.150 --> 25:36.690] Each jurisdiction here shouldn't have to be stuck trying to vet the security of the systems they're [25:36.690 --> 25:41.510] purchasing. And unfortunately, the vendor is always going to know more about the systems they create [25:41.510 --> 25:48.110] than those purchasing them. So what can we do? The first thing that we should do is try to fight [25:48.110 --> 25:52.790] efforts to increase information asymmetry. Put another way, we should advocate for transparency [25:52.790 --> 25:56.970] in this ecosystem. This can be done through better public analyses of election systems, [25:56.970 --> 26:02.610] including reverse engineering like this work. We must also start demanding software independence [26:02.610 --> 26:08.570] in our voting systems. We don't really know how to do this very well with electronic-only voting, [26:08.570 --> 26:13.450] and anything where the voter gets to physically verify their paper ballot before it's sent in [26:13.450 --> 26:17.790] is really a better situation here. For instance, like mail-in ballots, in-person drop-off, [26:17.790 --> 26:23.990] and in-person voting are all great. Electronic-only return or other electronic-only systems like DREs [26:23.990 --> 26:28.870] are really, really hard to make and verifiable, and really, really hard to make software-independent, [26:28.870 --> 26:32.770] and we're still trying to figure out how to do this at the research level. [26:33.530 --> 26:36.550] And everything that isn't transparent or software-independent, we should examine [26:36.550 --> 26:43.450] and really try to develop some replacements. Finally, it's an election year. Go vote! [26:43.850 --> 26:45.950] Thanks for watching, and feel free to reach out.