The further into the future we are, the more I start to believe inverse to be true in general, not only in security world. For some reason in security world a neat extra breaking security is treated as possible intentional backdoor.
Without treating mistakes, incompetencies, outright stupidities as malicious, we grow a new generation of technologists (including me, sadly), who do not bother to become adept in problem domain, consult with experts, perform strict analysis, cause tons of technical debt for the sake of moving fast. Good enough is the norm. We still see plain text, hashed without salt, hashed with the same salt password databases leaked. Maybe it was incompetence. Maybe it was stupidity. Maybe it was FIXME. Maybe the loaded gun was left on dinner table near a toddler because "I'm only going to bathroom". This is rhetoric question: can this stupidity be seen as malicious?
From the FAQ: "Is Sarahah a hacker?!
Sarahah doesn't steal data but websites and apps impersonating Sarahah could do that". Just weird. Why would a 'personal suggestion box' app need your contacts anyway apart from the developer's own dastardly plans? It seems they are sent in the clear as well. I think this upsets me the most. How did she expect to get away with it?
Access and hijacks are two different terms, one implies to use and the other implies to sell customer data. What the article says that the app accesses contacts for a future 'find your friend' feature.
What really bothers me is when the author says ' it’s possible Sarahah has harvested hundreds of millions of names, phone numbers, and email addresses ". I believe I remember Snapchat and other social media apps done before.
What Sarahah should have done is to communicate with their users about what their data and how they plan their security (being an anonymous messaging platform). But, let's not forget how Snapchat dealt with their security and data at its rise.
Signal uses the same process. When you first install, it uploads all your contacts to 'see' which of your contacts are Signal users. It then defaults to Signal messages to that contact. Any new Signal user on your contact list alerts you to the fact they are now using Signal and helpfully defaults to Signal messaging. When you uninstall, you have to remove your number from their central DB using their web-app to prevent your friends from sending you Signal messages you won't be able to open.
An implied "find my friend" feature that I assume Sarahah uses.
Does it really? I suggested that exact scheme months ago, but moxie rejected it as "not meaningfully privacy-preserving" (probably not his exact words), IIRC.
Yes, it really does. Signal takes the first 10 bytes of a SHA1 hash of the e164 number, base64s it. An array of these "tokens" are sent to the server at registration time and every 12 hours thereafter. You can confirm this on both client and server code on Github.
The problem, which no one denies, is that the small number of possible valid e164 values leaves the scheme vulnerable. Also, last time I checked you could submit like 10k tokens at once, so using a modest amount of IP addresses and phone numbers to bypass the rate limiting it is feasible to determine every registered number in a city. Restricting this is hard because some people have huge address books.
The Silent Circle method is slightly better in my opinion, but not by much so I understand why Moxie doesn't want to bother changing it.
Back when Redphone was a separate app it used a bloom filter scheme.
There are really no good solutions to this problem. The safer ones currently know just don't scale.
As someone who is going to implement "find-my-friends" in this way, and wants to do it conscientiously, may I ask why only the first 10 bytes of the SHA1? Isn't that just an incomplete hash that could collide with other valid numbers?
The point of the person you are responding to essentially comes down to pidgeon hole principle (the best principle), and absolutely applies to a cryptographically random function, and is agnostic to the input distribution: it is a relative measure of information/entropy between two sets.
Git defaults to using 7 hex characters for short hashs and doesn't see collisions for 95+% of repos. Even the Linux kernel repo with all its objects only needs 12 characters to ensure uniqueness.
Yes, but if (it seems more like when) a collision happens in a situation like this, aren't we essentially saying someone is connected with someone they don't even know? I feel like detecting the collision takes more computation then just sending the whole hash right? I mean in consideration of the scale that Signal/WhatsApp/etc are with millions of phone numbers
With a couple GPUs you could find out if there is a collision on phone numbers with truncated hashes pretty quickly. If the phone numbers are normalized, except for a few edge cases, the space is twelve digits which can be naively brute forced. A trillion SHA-1 hashes isn't that hard to do these days.
That's the point. You hash the number, and keep the hash. Send the first few digits of the hash to the server, it sends you a bunch of full hashes back. If your hash is in that list, then you know the server knows that person.
But that sounds like un-necessary round trips. I feel like the point in an API or backend service doing this, is because it knows better and has more computing power. I'd rather have my service take an incoming list and return with whether it's a member or not. In fact returning full hashes seems even worse, since now the server has not only replied with the correct match, but potentially more strangers. You could milk an API of it's users much quicker that way.
Right, but I'm thinking the server still needs to be able to say "This person who ever they are is definitely the number you have". Like, I wouldn't check my password hashes with only the first 10 bytes, I guess that's why I'm still stuck on the truncated idea.
No, the server just says "I know these email addresses starting with 'foo': foo@example.com, foo2@gmail.com, foo3@hotmail.com". If your friend's email address is in there, you know they have Signal.
The hashing is so people can't easily get a list of all the phone numbers, which is easy to work around, but, then again, they could just hammer the endpoint querying for all the various numbers anyway.
I've never heard of a way to do this without giving all your contacts to the app. Hashing is pretty useless if an attacker steals the DB as the parent pointed out because you can pretty easily build a dictionary of all possible 10-digit US phone number hashes (especially since area codes aren't anywhere close to randomly distributed). One slight advantage of hashing is non-malicious but curious employees/engineers at the company could be tempted to look at contact info whereas reversing hashes is much more clearly over the line and not everyone will know how to do it, but that's more a matter of training employees not to do it either way.
It doesn't matter if the attacker steals the database of hashes because the database of registered users is also stored there in plaintext. The attacker/insiders would need to start logging the contact intersection requests, including the authenticated user making them, in order to see a social graph and how that changes over time. Cracking the hashes is only necessary to unmask the phone numbers.
Standard OTT messaging architecture guarantees the service will see message envelopes anyway, so it's not worth the trade off of deploying PIR schemes of the differential or computational variety. Look for stuff by Ian Goldberg. Percy++ is a practical example you can run yourself.
For OTT contact sync the reasonable thing to do is just send the phone numbers. Blinding them by truncated hash is a nice gesture. What's not cool is sending all the other fields of the address book along with it.
We know and can easily verify that Signal is being good. But what can we do about less trustworthy services? The phone would need to apply permissions. Like, allow/deny filters of which fields of contacts or contact categories each app may have access to. An address book firewall, essentially. Considering how important messaging apps are in our lives and the amount of time we spend with them I think such granularity is warranted.
Signal way: Server keeps tokens of registered users cached. Client makes tokens of all the numbers it has, remembering the token -> number map for them. Client sends tokens to server, server returns the subset that matched. Client knows which numbers match. Making the token 10 bytes rather than 20 just saves bandwidth.
Silent Circle way: Server keeps hashes of registered users cached. Client hashes all the numbers it has, remembering the hash -> number map for them. Client sends a small number of the most significant bits of its hashes. Server treats this like a mask or wildcard search, returns all matches. Client knows which match, also gets hashes for other users they don't know. Sure, the client can reverse them, but the client could have probed for them anyway. The server maybe/probably doesn't learn enough to preimage what the client sent because of too many collisions. The downside is that the number of bits the client sends needs to be appropriate given the size of the database, though that can be mitigated by sharding by country code/area code/whatever.
FWIW, it isn't just not meaningfully privacy-preserving: it offers essentially no privacy preservation at all. There are 10 billion possible US phone numbers, and we know from Bitcoin that you can search that space in something like ten seconds on a typical PC. You also only have to do this once to construct a lookup table that would only take a terabyte to store and index, and then you could offer anyone instantaneous reverse lookup from truncated hash to phone number. It is essentially meaningless "privacy theater".
You wouldn’t even need a terabyte if you didn’t mind comparing against every hash to find the right one. 16 bytes/number at 10 billion numbers is only 160 billion bytes (160 GB). Store the hashes one after another in a flat binary file, then `i` in `file[16*i]` is your number.
If you included the 10 byte phone number, that only adds 100 GB. Then just store each entry as a 26 byte hash/number struct sorted by hash.
First time I looked at the framework, I expected to be able to read existing contacts, and create new contacts. I was a little surprised at editing existing contacts.
Nothing is really stopping an app with permission switching all of your contact numbers so they point to someone else, whether by accident, or on purpose. It seems like something waiting to go wrong...
Yes! Its high time. Need read-only, specific groups only, read only a public profile. Of course that will be the end of these find your friends feature.
I'm working on an app that makes use of this in a good way (to add new contacts and remove duplicates with explicit action by the user).
While doing some research on similar apps, I didn't find a single app that does not give the user an option to not upload the contacts to the app's servers. Basically if use doesn't give this permission, app is useless.
I'm hoping the app I build will get a sustainable revenue without needing to uploading all contacts.
But in the long run, for contact management apps, there's exponentially more value in handling the contacts data in the cloud, so that its users get the max benefit. But imo any app that's not for contact management (e.g., Facebook etc) should have limited read only access to the contacts data.
Doesn't work. We've had research on this for a long time. For a small percentage of the population maybe they can make judgements on a fine grained model but for the majority of people it becomes confusing and often worse than nothing.
I simply assume they are going to upload my contact data whenever they prompt me for the permission. Not sure how iOS does permissions these days - do they also have runtime permissions like Android? I know that a lot of companies here in India skip the runtime permissions system entirely and ask for them all at install time to handle fewer edge cases in the code, and make the user less likely to be suspicious.
iOS has had runtime permissions for far longer than android :)
Some apps will even explain what they (claim to) need the permission for before triggering the permission authorisation pop up.
One of the ios App I built needed contacts permission, but it's only within the app and never sent to my server. When I submitted it for review to Apple, they didn't approve the app asking the reason why I was accessing the contacts and if sending them to the server. Only if they are happy with the answer they will approve your app.
So in a way, iOS apps are much secure than Android.
This is why you should always read the terms and conditions of an app. I'm always shocked at how many people do not take this seriously. In this age of "data sharing" it is super important to take extra caution.
That's not a solution. T&Cs are written as vaguely as possible to permit as much flexibility as possible, and nothing stops a malicious actor from violating their public privacy claims.
I often meet people that has a secret identity because a former boyfriend/girlfriend threatens them. They never know about apps harvesting their contacts and connecting them to common friends until their ex suddenly shows up again.
This mindset of "If you havent done anything bad you dont have to worry" is so sad and ignorant of others situation.
This is the problem with an app assuming it understands your web of trust. There's no way to signal a toxic, unwanted or compartmentalized connection.
It's also why I use multiple profiles in Android to force that compartmentalization since the snoopy apps have no context it's better to just deny them the data entirely.
Facebook messenger does this as well, yet most people aren't aware of it, nor do they consent. There definitely should be much finer grain controls over this type of thing. Imagine how violated people would feel if they had to have someone take pictures of their address book (back when they were physical) just to enter the mall, yet this occurs every day and most are unaware.
Since no relationship is expected to last more than a few years these modern days, perhaps people should be educated to choose better their boy/girlfriends in view of what will happen after the breakup.
This is a really good example of cruel unjustified victim blaming and "sad and ignorant of others situation". We are all in awe of your high horse of hindsight.
Kind of a r/ShowerThoughts, we should maybe make an app & voluntarily fill our Contacts app with specific human like crap values & then sync all major apps with it thus peppering their gold-pots with waste contacts & by the time they catch up, the damage is already done. Rinse & repeat with slightly different values.
The problem is that the big companies are not interested in phone numbers and names. The real gold are the connections - who you talk to more frequently, who are your real friends vs. random people you added, etc.
One thing I hate is when apps do this to get information about your contacts, not only because they get who you personally know (and their phone number, email, other info in the contact) but also contacts for businesses you regularly might interact with, meaning they can potentially create a pretty detailed web of your life.
For example, it's a dark pattern when you use Messenger, at least on iOS, for the first time and it says "Upload your contacts to find friends" with an "OK" button or "Learn More" button, and only after you click "Learn More" can you ignore it. WhatsApp does something worse; you can't initialize a message with anyone without allowing contacts, and the only way to add a contact is thru the phone app (the web app definitely doesn't, and I'm pretty certain the desktop app doesn't have the functionality to add a contact). I have to go thru great pains to prevent WhatsApp from getting my contact info, just to be able to add a new friend (turn off iCloud contacts, enable WhatsApp to see my contacts, then add the contact). Maybe I am paranoid, but I really, really want Facebook to only have the information I give it, and I don't trust WhatsApp at all. At least WhatsApp encrypts the messages.
I really hate this pattern in apps, and I wish there was some way to give it some kind of "blank canvas" without any real contacts in it. Thankfully apps don't lock you completely out if you don't provide contact info, yet, but I fear it may happen soon.
It's really sad that the ios/android model COULD be more secure than the traditional desktop software model, but at the same time it has normalized all sorts of creepy snooping behavior on the part of apps.
63 comments
[ 2.7 ms ] story [ 109 ms ] threadWithout treating mistakes, incompetencies, outright stupidities as malicious, we grow a new generation of technologists (including me, sadly), who do not bother to become adept in problem domain, consult with experts, perform strict analysis, cause tons of technical debt for the sake of moving fast. Good enough is the norm. We still see plain text, hashed without salt, hashed with the same salt password databases leaked. Maybe it was incompetence. Maybe it was stupidity. Maybe it was FIXME. Maybe the loaded gun was left on dinner table near a toddler because "I'm only going to bathroom". This is rhetoric question: can this stupidity be seen as malicious?
What really bothers me is when the author says ' it’s possible Sarahah has harvested hundreds of millions of names, phone numbers, and email addresses ". I believe I remember Snapchat and other social media apps done before.
What Sarahah should have done is to communicate with their users about what their data and how they plan their security (being an anonymous messaging platform). But, let's not forget how Snapchat dealt with their security and data at its rise.
An implied "find my friend" feature that I assume Sarahah uses.
Edit: Here: https://github.com/WhisperSystems/Signal-Android/issues/4726
„[..] Signal has always done contact intersection with an ephemeral query of truncated hashes of phone numbers.„
See also https://news.ycombinator.com/item?id=11979748
The problem, which no one denies, is that the small number of possible valid e164 values leaves the scheme vulnerable. Also, last time I checked you could submit like 10k tokens at once, so using a modest amount of IP addresses and phone numbers to bypass the rate limiting it is feasible to determine every registered number in a city. Restricting this is hard because some people have huge address books.
The Silent Circle method is slightly better in my opinion, but not by much so I understand why Moxie doesn't want to bother changing it.
Back when Redphone was a separate app it used a bloom filter scheme.
There are really no good solutions to this problem. The safer ones currently know just don't scale.
The hashing is so people can't easily get a list of all the phone numbers, which is easy to work around, but, then again, they could just hammer the endpoint querying for all the various numbers anyway.
Standard OTT messaging architecture guarantees the service will see message envelopes anyway, so it's not worth the trade off of deploying PIR schemes of the differential or computational variety. Look for stuff by Ian Goldberg. Percy++ is a practical example you can run yourself.
For OTT contact sync the reasonable thing to do is just send the phone numbers. Blinding them by truncated hash is a nice gesture. What's not cool is sending all the other fields of the address book along with it.
We know and can easily verify that Signal is being good. But what can we do about less trustworthy services? The phone would need to apply permissions. Like, allow/deny filters of which fields of contacts or contact categories each app may have access to. An address book firewall, essentially. Considering how important messaging apps are in our lives and the amount of time we spend with them I think such granularity is warranted.
Silent Circle way: Server keeps hashes of registered users cached. Client hashes all the numbers it has, remembering the hash -> number map for them. Client sends a small number of the most significant bits of its hashes. Server treats this like a mask or wildcard search, returns all matches. Client knows which match, also gets hashes for other users they don't know. Sure, the client can reverse them, but the client could have probed for them anyway. The server maybe/probably doesn't learn enough to preimage what the client sent because of too many collisions. The downside is that the number of bits the client sends needs to be appropriate given the size of the database, though that can be mitigated by sharding by country code/area code/whatever.
What's the full number?
If you included the 10 byte phone number, that only adds 100 GB. Then just store each entry as a 26 byte hash/number struct sorted by hash.
Here's what an app on iOS can read and modify (!) when you allow it to access your contacts: https://developer.apple.com/documentation/contacts/contacts_...
Nothing is really stopping an app with permission switching all of your contact numbers so they point to someone else, whether by accident, or on purpose. It seems like something waiting to go wrong...
While doing some research on similar apps, I didn't find a single app that does not give the user an option to not upload the contacts to the app's servers. Basically if use doesn't give this permission, app is useless.
I'm hoping the app I build will get a sustainable revenue without needing to uploading all contacts.
But in the long run, for contact management apps, there's exponentially more value in handling the contacts data in the cloud, so that its users get the max benefit. But imo any app that's not for contact management (e.g., Facebook etc) should have limited read only access to the contacts data.
It's kinda like bringing a bazooka to a knife fight, but this will get the job done nonetheless.
So in a way, iOS apps are much secure than Android.
This mindset of "If you havent done anything bad you dont have to worry" is so sad and ignorant of others situation.
It's also why I use multiple profiles in Android to force that compartmentalization since the snoopy apps have no context it's better to just deny them the data entirely.
And then Facebook acquired it and was able to complete its database of world's relationships.
For example, it's a dark pattern when you use Messenger, at least on iOS, for the first time and it says "Upload your contacts to find friends" with an "OK" button or "Learn More" button, and only after you click "Learn More" can you ignore it. WhatsApp does something worse; you can't initialize a message with anyone without allowing contacts, and the only way to add a contact is thru the phone app (the web app definitely doesn't, and I'm pretty certain the desktop app doesn't have the functionality to add a contact). I have to go thru great pains to prevent WhatsApp from getting my contact info, just to be able to add a new friend (turn off iCloud contacts, enable WhatsApp to see my contacts, then add the contact). Maybe I am paranoid, but I really, really want Facebook to only have the information I give it, and I don't trust WhatsApp at all. At least WhatsApp encrypts the messages.
I really hate this pattern in apps, and I wish there was some way to give it some kind of "blank canvas" without any real contacts in it. Thankfully apps don't lock you completely out if you don't provide contact info, yet, but I fear it may happen soon.