 Up now we have Alex and Konark with Anonymous Rate Limiting with Direct Anonymous Attestation. Thank you and welcome everybody to our talk. My name is Konark and this is Alex. And we both work for a company called Klicks based out of Munich, Germany. For those of you who have not heard about Klicks, we are basically a privacy-friendly search engine which can be accessed through our browser and through our Firefox add-on. And apart from being a search engine, we also package the browser and an add-on among various privacy features like anti-tracking and ad-blocking. And we're also the parent company for CoStreet. Today we're going to talk about a system that we developed and use at Klicks which basically helps us prevent attacks on our data collection system. Although the examples that we will take here will be based on the events that we receive in our data streams, but we believe the system is generic enough that wherever rate limiting applies, the system can be used. Before Alex will talk about the system in detail, I would just like to explain why at first place we needed to build an anonymous rate limiting system and how it has evolved since 2016. Now, it's important to understand that data is important to build services and Klicks is no exception. To power our search engine, anti-tracking, anti-fishing, data is of the most importance. And yes, it might sound a bit controversial talking about data collection at a privacy village, but it's important to understand that when you talk about data and privacy, how that data is being collected is of the utmost importance. If you look at this table here, this is what most of the data streams in the industry would look like. Most of the data collection happens with an identifier that is sent back home with the events. The identifier could be a long-term identifier, an explicit identifier, like a cookie, which you see on the extreme right, or it could be an implicit identifier based on multiple parameters like IP and the user agent. The whole notion of sending back identifier is so that use cases like analytics could be solved on the back end. So for example, based on this data stream, we can easily solve the question, how many unique visitors visited facebook.com in a given hour, right? But also because of the presence of the identifier, you can link multiple events on the back end, which means not only can you solve the use case of finding out unique visits on facebook, you can also see that the same user also visited booking.com, twitter dashboard, and maybe because of some capability URLs, you can potentially de-anonymize the user itself, right? So when we started to design our data collection streams, we wanted to ensure that any data point that can link multiple messages on the back end needs to be dropped on the client side itself. What that means is in our data streams, there is no way you can link multiple messages together. That could be implicitly or explicitly. And in order for us to even prevent ourselves from linking messages based on network fingerprinting, we also want to route the data through a set of proxies. So that means the data collection streams are clean and cannot be linked with multiple events. That said, we still can solve the use cases that is needed to collect identifiers for. But for this purpose, for this talk, we will not dig deeper into how we do it. If you want more details, we can offline or you can read this paper and our approach how we do data collection anonymously and yet solve the use cases. Coming back to the motivation of doing this talk, now the problem is all the data collection systems suffer from the same problem that an attacker can spam you with multiple messages which are fake, which are not actually happening on the user's machine. And we are no exception. But because our, so if you take, let's take an example here. So for example, one of the most important data points for us is query logs. What that means is what is the query that user did and what result did the user select from our search results. And the query log powers how we rank our search engine and how we promote the content because that detects what's the popularity of a query and landing page, right? Now an attacker knowing that we do not have identifiers in our data streams can spam us with multiple messages, right? And once the spammer starts to send us multiple messages, it could be used for altering or promoting their own content at a different rank or maybe disrupt our services by promoting a bad result for a good query, right? To give you a more concrete example, just based on these two messages, these are two sample query logs, query booking, the landing page booking dot com, query booking, the landing page booking holidays dot com. Just based on the message content, we cannot detect whether it's a fabricated data or a genuine data, right? And because unlike other search engines, we do not track users, there is no way we can know what is the source of the message and what is the history of the source itself to use it for server-side rate limiting or for server-side rate limiting solutions, right? And this is a big, big concern for us because now at one point, we are doing anonymous data collection, but because it's anonymous, it can negatively impact our services itself, right? So one solution could be let's stop anonymous data collection and let's start tracking users, but that is not what we want to do. So we want to build a service wherein we can detect without de-anonymizing the user whether it's the same user sending us multiple messages or these are different users. You can think about this as a voting system where a trusted user can vote but can only vote once for a given period, right? Now think about this problem as the user needs to vote for popularity of a query but can only vote once in a given timeframe. In the context of this query log, we only want to receive one query per user, one normalized query per user in one hour, right? And if we talk about a general implementation of the system based on the message type and the content of the message, we want to rate limit the users, rate limit per user per timeframe, right? And that's kind of important for us and that's why the problem that we try to solve is without knowing the user, how do we enforce these rate limiting users or these rate limiting rules, right? So in 2016, we pushed a version to production which we call anonymous rate limiting version one and the idea was because we are already using proxies to transport data, we can actually empower the proxies without learning the content of the message but still perform deduplication for us. But what that meant was these proxies needed to run custom software which perform these deduplication tasks. Now this protocol was based on blind signatures and other standard crypto primitives but yet for this solution to work, we needed multiple trusted third party providers to run proxies for us. The reason we needed multiple third party proxy providers first was because they needed to run the custom application and second, we did not want that the users could collide with the proxies or the proxies could collide among themselves or clicks itself could collude among the proxies, right? But what happened was we tried finding these multiple third party vendors to run proxies for us and sadly in about two years we could not find any, right? What that meant was clicks had to run their own proxies which kind of defeated the whole purpose and because these proxies had to run a custom software to perform deduplication we cannot rely on the off shelf solutions like Tor or other trusted vendors. So based on these challenges that we faced in the first version earlier this year we started testing a new version which we call anonymous rate limiting version two and which Alex will explain in detail. So as Conor said I'll talk about our new anonymous rate limiting system which is based on the rate anonymous attestation. He already mentioned some of the benefits but just as a quick review this system has several benefits over the previous one. The first one is that now we don't need we remove the need for trusted third parties. Second, there are less interactions between the client and the server because in the previous system we required one blind signature per message so the client had to first get message blind sign then actually send the message so there was two interactions. The third one is now that we can use known solutions for network anonymity like Tor which in the previous system was a bit more complicated because of this custom third party proxies. So what is actually direct anonymous attestation? Direct anonymous attestation is a cryptographic primitive which is implemented in processors that follow the trusted platform module standard as well as other chips which follow the Intel enhanced private CID specification. But rather than focusing on the hardware that runs this cryptographic protocol we'd rather like to focus on the cryptographic primitive itself. So for our purposes, direct anonymous attestation has two key features. First, it allows for anonymous authentication. This means that you can prove that a trusted platform is signing a message but not which concrete platform is doing so. So in other words, the signatures can prove membership of the device in a group but not which concrete device is signing the message. The second feature that is important for us is the control linkability. So given, sorry, for this control linkability a device signs a message with respect to a base name string. In a way that two signatures from the same member are linkable if and only if they are done with respect to the same base name string. So for example, if a device always signs a message with the same base name then all the signatures will be linkable. So we'll be able to link all his messages together. On the other extreme, if a device would randomize this base name and sign every message with respect to a different base name then all the messages will be completely unlinkable. So we see later that we can use this linkability properties to achieve our rate limiting needs. But before that, we have to talk about the main four operations that are involved in direct anonymization because we'll need to refer to them later. The first one is called join and this is where a device gets credentials from an issuer. Typically a device is the client and the issuer is a server. And we can see this as the device becoming a member of the issuer group. Then once this device obtains credentials it can sign messages with respect to this base name string in a way that the linkability properties are fulfilled. The linkability properties that we talked in the previous slide are fulfilled. So then the verify operation essentially means that you can check whether a signature is valid for a given message and base name and finally the link operation which is especially important for us is it allows to check whether two signatures have been known by the same member and the same base name. Now since this signature linkability is essential for our purposes we actually need these link algorithms to be efficient. So let's take a look at how this linkability looks in practice. To achieve this linkability, signatures contain pseudonym which can be seen as a linkability tag and this pseudonym is computed as a one-way function of the base name and the user private key. Of course the user private key is unknown to the server so it's unknown both to the issuer and the verifier. The way this pseudonym works is like if you see two equal pseudonyms then it means for sure that the corresponding signatures were done by the same member and with respect to the same base name. So this means that the link algorithm is efficient because the server just needs to store all the previously seen pseudonyms and then whenever a new message comes just extract its pseudonym and see if it has already been seen before. Now that we have explained how the Red Anonymous Attestation works let's see how to use it actually in practice to achieve the real limiting our real limiting needs. So the idea is quite simple it's basically enforce these base names to be computed in a very specific way so that the concretely limiting rules for the system can be enforced. So this means that the client will compute the base name according to these rules and will never send two messages with the same base name pseudonym because of course they could be detected very easily at the server side. Then the verifier which is a server will drop messages either if this base name has computed incorrectly according to the rules or if the pseudonym is repeated. So this would be the structure to achieve our rate limiting purposes. So it looks like a couple of four components the first one is a message type which can be used to have different rules for different kind of messages the second one is a time period which is actually a time stamp truncated to an hour or a day depending on the need the third one is a message digest which is an arbitrary function on the message and is used to introduce some message content into these rules and the last is a count which is an integer between unit E1 and N and can be seen as a multiplier so given a fixed message type time period message digest then you can send up to N messages so we found this base name structure to be expressive enough for our needs but it doesn't mean that this is the only possible structure to do this kind of rate limiting now revisiting the previous example that Konark show the query logs we could have a message that would look like this first the search query and this case booking the landing URL and the timestamp and we would like to enforce the following rule we only want one message per user per hour per normalized search query to be accepted by the server to achieve this rule and following the previous base name structure the base name would look like this first we will have the message type which is constant in this case query log type the second one would be a truncated timestamp to the hour so instead of 6.56 just 6 the third one normalized query and the last one just 1 because in this case that's the only option so essentially the strategy is to not let the user choose more than one base name for a normalized search query and for a given hour another example that we might want to enforce is let's say we have a different kind of message which we only want to accept three messages per user per day so for this kind of message we could call three daily type the base name would look like this first the message type then the date and then the message digest which in this case would be empty because the rule is independent of the message content and then account which in this case could be chosen so a client at the start of the day would like to send the message then it would see that it can choose out of three base names and it would choose one at random it would mark this base name as used and then in the next message that would want to send it would pick from the two remaining base names etc and essentially when it runs out of base names there is no way that the message is detected and there is no way that the user can send an additional message without being detected at the server side now if TPM was available like in all the devices 100% of devices we could basically end the talk here and say ok we leverage on the TPM because it runs this direct anonymous attestation protocol and we showed how to use it to rate limit but in practice this is not the case first TPM is not available in all the devices like it might be available in this laptop but in general it's not and then even if it's available for example in our execution environment we want to run this real limiting service in the client which is a browser extension so even if the TPM might be available physically in the device we might not be able to access it so at the end it's not realistic to assume that the TPM is available so what we did is we implemented the direct anonymous attestation protocol but without the TPM, so software only now this opens the possibility for a new problem which is basically ok in the system we showed we protect against a single user from sending too many messages so we kind of ok for a given user this user has only a limited set of boats let's say to contribute in the system but if we remove the TPM then it could be quite easy for an attacker to create many identities and then obtain credentials for all of them and then essentially bypass the whole system so not that this would not happen with the TPM because if we would enforce the TPM then actually get hold of many TPMs devices which is not so easy so at the end if we cannot limit the number of credentials given to attackers then the whole system will be useless now this has a name it's called Civil Attacks and we actually need to prevent them so the good thing is that we can pretty much focus on one operation of the system which is the join operations this is the operation where the clients get credentials and the good thing is that it does not need to be anonymous so this is because according thanks to the protocol properties there is no way to link this join to any other of the user interactions with the server so essentially the join is decoupled from all the other interactions so since the joins do not need to be anonymized we can leverage standard techniques but just on this join operation for example the simple one would be just to rate limit on the user IP we believe that would already add some protection then depending on the use case of this rate limiting system we might have email user accounts paid user accounts subscriptions so we might be able to use this for the join operations to give the credentials now as an extra measure we also rotate the issuer public keys this means that every time the issuer public keys are rotated all the credentials that the issuer has given are invalidated so the clients need to join again this is to avoid an attacker to potentially accumulating many credentials over time and using them with any extra effort so at the end as a summary of this part we believe there are ways to mitigate these civil attacks and that the rate limiting is useful even without TPMs so as a summary for the key parts of our system first we rate limit joins using all available information that we have user IP email if it's available etc then rotate issuer keys periodically and last use the direct anonymous attestation linkability for doing the actual rate limiting on the messages now we have to mention some possible the anonymization attacks that we might be able to do given that we control the servers so given that we control both the issuer and the verifiers the first attack would be trying to make each user join a group where they are alone so essentially each user would join a group which is unique for them and then essentially each signature if this was the case would contain like a user ID so this would pretty much make it very easy for us to build user sessions this is quite easy to detect because the user fetch the issuer public keys periodically and then the user would detect that the issuer is changing this issuer public keys when it should not and then basically could decide to ban the issuer and not send any message anymore or to report it or depending on the system the second attack is a little bit more tricky and we call it denial of join is that the issuer has the power of deciding who gives credentials to them so in an extreme case the issuer could only give credentials to a single user and then since since only this user would be able to send messages it would be trivial to track this user so this is a bit more tricky to detect from the client side because the clients would need to cooperate with each other in order to know that a single part of the population is not receiving credentials and then react upon it but in practice this is not so easy to implement but in our concrete use case since we have the incentive of receiving data to run our services we have more incentive on receiving data than on trying to track users and since to track users we have to drop messages proportionally to the granularity that we want to track so it's not reasonable for us to try to do this attack okay so we thought it would be a good idea to compare similar systems that are used in production one is called privacy pass and it's used in cloudflare and the way this work is basically a user solves a token, sorry a user solves a captcha and then receives end tokens that can redeem later to avoid solving more captchas right so these tokens skip the captcha the captcha pass and these tokens redeem anonymously so we couldn't use this even though we could use this in some specific use cases of our system we cannot use it as a general solution for our needs because the main reason that these tokens can be redeemed at any point of time in the future and we cannot frame it to redeem it at specific time periods as we require then the second one is called anonymize and is implemented in a brief browser it essentially consists in the server being able to set up anonymous surveys for a subset of users in a way that only one user can vote once per sorry in a way that users can only vote once per survey as far as I know this is used for payments to decide the popularity of websites we couldn't find a way to use it directly if our needs because our trade limiting rules needed a little bit more of complexity it needed a time period for some matches to the query logs to include part of the content to do the remit so we couldn't find a way of using this but still the systems are similar to our in some way so for the implementation part we implemented a paying based cryptographic protocol which is used which is defined in a FIDO elliptic curve data anonymous attestation and since it's users paying based cryptography it's not so easy to find well at least the choices for libraries are a bit reduced eventually we decided to use a library called Apache Milagro Crypto Library which is in C so we implemented the protocol in C using this library and since our client runs in a web browser we compared it to WebAssembly and built road bindings to JavaScript for that and then for the server side we used the same C implementation but road native bindings for Node.js as our server now the benchmarks especially the most important operation is the server verify because these actually influences how many messages per second can the server process so right now it's 4 milliseconds per CPU core so this means we can process 250 messages per second per CPU core even though this is not surprisingly fast we believe that it's fast enough to be used in practice to be used in production so this system not the whole system is open source yet the server side is not open source but the crypto implementation of the direct and normal of the station it is as well as the client part in this repository so thanks for watching see you next time bye