I've been toying around an architecture that sets things up such that the data for each user is actually stored with each user and only materialized on demand, such that many data leaks would yield little since the server doesn't actually store most of the user data. I mention this since this sorts of leaks are inevitable as long as people are fallible. I feel the correct solution is to not store user data to begin with.
some problems I've identified:
1. suppose you have x users and y groups, of which require some subset of x. joining the data on demand can become expensive, O(x*y).
2. the main usefulness of such an architecture is if the data itself is stored with the user, but as group sizes y increase, a single user's data being offline makes aggregate usecases more difficult. this would lend itself to replicating the data server side, but that would defeat the purpose
3. assuming the previous two are solved, which is very difficult to say the least, how do you secure the data for the user such that someone who knows about this architecture can't just go to the clients and trivially scrape all of the data (per user)?
4. how do you allow for these features without allowing people to modify their data in ways you don't want to allow? encryption?
a concrete example of this would be if HN had it so that each user had a sqlite database that stored all of the posts made per user. then, HN server would actually go and fetch the data for each of the posters to then show the regular page. presumably here if a data of a given user is inaccessible then their data would be omitted.
Disclosure: I work at Anytype. This is the architectural bet we took, so I'll answer your four problems directly.
Premise: treat it as certain that the server will eventually be compromised, subpoenaed, or misconfigured. So the server must hold nothing that can be decrypted or linked to a specific user's content. Users hold their own encryption keys, the server stores ciphertext, and there is no UUID→identity mapping at the sync layer. Sync runs over any-sync, which is peer-to-peer-capable; intermediate nodes see ciphertext.
On your four problems:
1. O(x*y) joins - pushed to the client, because the server can't decrypt enough to do them.
2. Offline members - eventual-consistency sync and CRDT.
3. Client-side theft - if an attacker has the user's keys, they have the data. Intentional: no server-side gate to break means no server-side gate to exfiltrate at scale. We're considering optional 2FA at the infrastructure layer as an additional barrier to data retrieval.
4. Unwanted modifications - content is signed with user keys and validated on read.
Real cost is on the product side: no server-side AI over your notes, no server-side full-text search, slower cold-start, and harder to build product analytics (no access to user data). Granular ACLs are also harder — permissions are enforced by key possession, so revoking access often requires key rotation rather than a permission-flag change.
But the exact bug this post is about (a server endpoint that maps a public UUID to an email) is structurally impossible in this model, because there's no such mapping on our servers to misuse.
any-sync and our data format (any-block) are MIT, if you want to poke at how it works: https://github.com/anyproto
> When you publish a Notion page to the web, the webpage’s metadata may include the names, profile photos, and email addresses associated with any Notion users that have contributed to the page.
Recently I checked back on Notion after a year or so of not seeing it. I was going to recommend it to someone as an example of hypertext, but I see now it calls itself an "AI workplace that works for you" and "Your AI everything app". This company means nothing now, seriously what happened.
After making one of the least worst rich editors out there on the web, they needed to keep their developers and designers busy (while not having time to fix privacy bugs).
Like every other AI tool it mainly seems to exist to produce productivity porn. Summarize the meetings nobody could be bothered to summarize. Write the docs nobody can be bothered to read or write. Communicate as an end, not a means, because the company your work for has transitioned into the dead-weight phase.
Very timely. I literally ran a Claude prompt "compare and contrast Notion vs Obsidian" and flipped over to HN while it was thinking, and this comes up. Thanks HN!
First: This is documented and we also warn users when they publish a page. But, that’s not good enough!
Second: We don’t like this and are looking at ways to fix this either by removing the PII from the public endpoints or by replacing it with an email proxy similar to GitHub’s equivalent functionality for public commits.
P.S: Some folks here have speculated that this should be a 1 minute fix. Unfortunately that is not the case. :(
You should explain WHY that is not the case, or else accept that everyone's takeaway about this is that you've KNOWN you've been leaking your users' data for FOUR YEARS and have done nothing about it by CHOICE.
For a PII leak like this, why do you think it's OK to wait for "looking at ways to fix this"? It you can't do anything better you shut those endpoints (or whole servers) down IMMEDIATELY and then deal with the fallout afterwards. Your attitude towards this is beyond unacceptable.
I love Notion and use it extremely heavily. I've also built a few integrations with Notion. I think it's a great app that uses AI very well, and they continue improving. Hopefully they fix this though! Also, their API has recently been upgraded quite a bit and now supports database views as a first class object. I have a few other small requests regarding their public API.
I really dislike Notion. Its public API is full of bizarre arbitrary limitations, like a rich text database field can only contain max 100 “child blocks”, where each change in formatting consumes one child block-but its web UI doesn’t have this issue. Yes, I realise the undocumented private API that the web UI uses doesn’t have this issue either-but I shouldn’t have to, and I haven’t.
I don’t love Confluence, but at least it doesn’t do this to me.
I reported this and several other issues with public pages almost six years ago. Some of them were fixed after many years - but they're very slow to handle it. I never received any bug bounty or anything.
Two things. One, surely I'm not the only one who knew this data was being stored? Two, calling it a "leak" feels like a stretch when the data was publicly accessible by design from the start.
Yes, some users probably didn't realize their edits to public pages were saved publicly, and that's a legitimate UX complaint. But some of the responsibility has to sit with the user. Otherwise we'd be running daily headlines about Meta "leaking" user data to every advertiser with a checkbook.
27 comments
[ 0.23 ms ] story [ 39.6 ms ] threadsome problems I've identified:
1. suppose you have x users and y groups, of which require some subset of x. joining the data on demand can become expensive, O(x*y).
2. the main usefulness of such an architecture is if the data itself is stored with the user, but as group sizes y increase, a single user's data being offline makes aggregate usecases more difficult. this would lend itself to replicating the data server side, but that would defeat the purpose
3. assuming the previous two are solved, which is very difficult to say the least, how do you secure the data for the user such that someone who knows about this architecture can't just go to the clients and trivially scrape all of the data (per user)?
4. how do you allow for these features without allowing people to modify their data in ways you don't want to allow? encryption?
a concrete example of this would be if HN had it so that each user had a sqlite database that stored all of the posts made per user. then, HN server would actually go and fetch the data for each of the posters to then show the regular page. presumably here if a data of a given user is inaccessible then their data would be omitted.
Premise: treat it as certain that the server will eventually be compromised, subpoenaed, or misconfigured. So the server must hold nothing that can be decrypted or linked to a specific user's content. Users hold their own encryption keys, the server stores ciphertext, and there is no UUID→identity mapping at the sync layer. Sync runs over any-sync, which is peer-to-peer-capable; intermediate nodes see ciphertext.
On your four problems:
1. O(x*y) joins - pushed to the client, because the server can't decrypt enough to do them.
2. Offline members - eventual-consistency sync and CRDT.
3. Client-side theft - if an attacker has the user's keys, they have the data. Intentional: no server-side gate to break means no server-side gate to exfiltrate at scale. We're considering optional 2FA at the infrastructure layer as an additional barrier to data retrieval.
4. Unwanted modifications - content is signed with user keys and validated on read.
Real cost is on the product side: no server-side AI over your notes, no server-side full-text search, slower cold-start, and harder to build product analytics (no access to user data). Granular ACLs are also harder — permissions are enforced by key possession, so revoking access often requires key rotation rather than a permission-flag change.
But the exact bug this post is about (a server endpoint that maps a public UUID to an email) is structurally impossible in this model, because there's no such mapping on our servers to misuse.
any-sync and our data format (any-block) are MIT, if you want to poke at how it works: https://github.com/anyproto
> When you publish a Notion page to the web, the webpage’s metadata may include the names, profile photos, and email addresses associated with any Notion users that have contributed to the page.
Like every other AI tool it mainly seems to exist to produce productivity porn. Summarize the meetings nobody could be bothered to summarize. Write the docs nobody can be bothered to read or write. Communicate as an end, not a means, because the company your work for has transitioned into the dead-weight phase.
First: This is documented and we also warn users when they publish a page. But, that’s not good enough!
Second: We don’t like this and are looking at ways to fix this either by removing the PII from the public endpoints or by replacing it with an email proxy similar to GitHub’s equivalent functionality for public commits.
P.S: Some folks here have speculated that this should be a 1 minute fix. Unfortunately that is not the case. :(
Tells me everything I need to know about this industry. No regard or seriousness to security at all.
I don’t love Confluence, but at least it doesn’t do this to me.
Here's a Reddit post just as confirmation: https://www.reddit.com/r/Notion/comments/hqyxid/possible_sec.... I also reported it privately two months prior, of course.
Yes, some users probably didn't realize their edits to public pages were saved publicly, and that's a legitimate UX complaint. But some of the responsibility has to sit with the user. Otherwise we'd be running daily headlines about Meta "leaking" user data to every advertiser with a checkbook.