When you send somebody a file, you want to know one thing: did it arrive? The person on the other end wants something too, which is not to be followed around the internet because they opened a link. Both can be true at once, and this post is about how a Nemi share link manages it.
What does Nemi record when somebody opens a shared link?
Less than you might expect, and the same for everybody who opens it. Every open and every download records a time, which file it was and whether it was a preview or a download. It records a hash of the address the request came from, salted and shortened, so that ten opens from one person count as one visitor. And the file's download count goes up by one. That is the list. No browser, no device, no location, no referrer.
A sender can choose to know more about one particular link, by switching on Trace for it. That changes the list, considerably, and the toggle below shows exactly how.
What one visit leaves behind
4 things kept per visit
Recorded
When
The time of each open and each download.
Which file, and how
Whether it was previewed in the browser or downloaded.
A salted, shortened hash of the address
So two opens from one place count as one visitor. Never the address itself.
A download count
On the file, and a download record with no address and no browser in it.
Never recorded
- The IP address itself
- Browser, device or system
- Location
- Where they came from
- How long they read
This is every share link unless the sender chose otherwise. The sender sees counts and times, never who. Either way it is deleted with the link.
How do you count visitors without storing their address?
To say "three people opened this" rather than "this was opened eleven times", you need some way to tell one visitor from another. The obvious handle is the IP address, and the obvious mistake is to store it. An address is personal data: it can point at a household, and stored next to a time and a file it says who looked at what.
So Nemi no longer stores the address for an open or a download. The moment a request arrives, the server puts a secret salt in front of the address, runs the two through SHA-256, keeps the first 40 hexadecimal characters and drops the rest. Two opens from the same address produce the same hash, so they can be counted as one visitor, and nothing Nemi writes today says what the address was.
From an address to a hash, on every open
1/4A request arrives
Try it. Type an address, change the salt, and then play the attacker.
Hash an address, then try to get it back
SHA-256 of salt, a bar, and the address
The first 40 characters are kept, 160 of the 256 bits. The rest is thrown away, and so is the address.
Now try to reverse it
A hash cannot be run backwards, but an attacker can run it forwards on every likely input and look for a match. This tries the 65,536 addresses that start with the same two numbers.
Does shortening the hash make it anonymous?
No, and it is worth being exact about why, because this is where descriptions of hashed analytics usually go soft. Cutting a SHA-256 hash to 40 characters keeps 160 bits. There are about 4.3 billion IPv4 addresses, which is 232. Spread over 2160 possible values, the chance that any two of them share a stored hash is about one in 297, a number with 30 digits. In practice every address still gets a hash of its own. The shortening keeps the column small. It protects nobody.
What protects the address is the salt. As the search above shows, an attacker who knows the salt can hash every possible address and look the stored value up: 4.3 billion is a large number for a person and a modest one for a computer. Without the salt there is nothing to try, because every guess at the address has to be paired with a guess at a secret that is not written anywhere they can read. So the salt is configuration held outside the code and outside the database, and is never published.
The honest word for the result is pseudonymous, not anonymous. On one link, we can still tell that the same visitor came back, which is the whole point of counting visitors. What a stored hash cannot do, without the secret, is tell anybody who that visitor was.
0
raw IP addresses stored today for an open or a download
160 bits
of the hash kept, of 256
4.3 billion
IPv4 addresses: few enough to try them all, if the salt were known
How do I see who downloaded my file?
On an ordinary link you see how often it was opened and downloaded, when, and by roughly how many visitors, but not who they were. To know more about one delivery, you switch on Trace. It is for the delivery where knowing matters: a contract, a pitch, a proposal you need to follow up on. It is off unless the sender chooses it, it is set per link rather than per account, and the sender sees in plain words what it will record before they create the link. With it on, a visit also records the country and city the address resolves to, the kind of device, the browser and operating system, the site that sent the visitor, how long the browser reports they spent on each page, a short code on every download so a leaked copy can be traced to it, and the visitor's email address if the sender typed it for that link.
Even then, a few things keep it from becoming tracking across the web:
- The raw address is still not stored. The same salted hash is used, and location comes from the network, never from the browser's location prompt.
- Repeat visits are grouped per link. The key that ties one viewer's visits together includes the link itself, so the same browser opening two of your links produces two unrelated keys. The only way a sender sees one person across several links is by an email address they typed themselves, and never across senders.
- Facts and estimates are kept apart. Opens and downloads are recorded by our server and are exact. Reading time is measured in the visitor's browser, counted only while the file is in front of them, and shown to the sender as an estimate.
A share link should tell you the file arrived, not who the person is.
How long is any of this kept?
Exactly as long as the link. Share statistics, including everything Trace records, live with the share they belong to and are deleted with it, and revoking a link erases its trace at the same moment. Nothing about the people who opened it outlives the link.
The full detail, written for the person who opened a link rather than the person who sent it, is in the privacy policy. How to switch Trace on and read what it shows is in the help centre and on the Trace page, and everything else a share link can do is on the Files page. If the link is for a large delivery, the guide to sending large files securely covers the settings worth choosing, and a link sent from your own domain records exactly the same as any other.
Questions people ask
Can I see who downloaded my shared file?
On an ordinary Nemi share link you see how many times it was opened and downloaded, when, and roughly how many different visitors there were, but not who they were. If you need to know more for one particular link, you can switch on Trace for it, which adds location, device, browser, reading time and a code on each download. A person is only named when you typed their email address for that link yourself.
Is a hashed IP address anonymous?
No. A hashed address is pseudonymous: the same address always gives the same hash, which is what lets visits be counted, and anybody who knows the salt can try every possible IPv4 address and find the match. What protects it is keeping the salt secret. Nemi keeps the salt out of the code and the database and never publishes it.
Is an IP address personal data?
In the EU it is generally treated as personal data, because it can point to a household or a person, especially next to a time and a file. That is why Nemi no longer stores the address for an open or a download, only a salted and shortened hash of it. Our privacy policy sets out exactly what is recorded about people who open a link.
What does Trace record about the people who open my link?
With Trace on, a visit to that one link also records the country and city the address resolves to, the kind of device, the browser and operating system, the referring site, how long the browser reports was spent on each page, a code on every download, and the email address if you typed it for that link. The raw IP address is still not stored, and visits are grouped by a key that only works on that link.
Does the person who opened my link know about Trace?
Nemi's privacy policy tells everybody who opens a link exactly what Trace can record. Switching it on is the sender's decision about somebody else's data, so our Terms make the sender responsible for having a lawful basis and for telling the people they send it to, and forbid using it covertly where the law requires telling them.
How long are download statistics kept?
As long as the link. In Nemi, share statistics, including everything Trace records, are deleted together with the share they belong to, and revoking a link deletes its trace at the same moment.
Will I be told when somebody opens my link?
Yes. Nemi notifies you in the app the first time each of your links is opened. That notification says only that the link was opened, never who opened it.
Where the numbers come from
- The salted hash, cut to 40 hex characters:
lib/share-open-tracking.ts (hashViewerIpForShareAnalytics, recordShareContentOpen) - What a download records without Trace:
app/api/download/file/[fileId]/route.ts - What Trace adds, and the per link viewer key:
lib/share-trace.ts (traceViewerKey, traceCoarseLocation, traceReferrer) - What recipients are told: /privacy, sections 3.6 and 3.10
- Share statistics, not tracking: /security