Safeguard
Application Security

Anyone With the Link Is Not an Access Control

It is the absence of one, with a long identifier standing in for a decision about who should see the thing. Products ship it because customers need it, and then nobody can list what has been shared.

Aman Khan
AppSec Engineer
6 min read

"Anyone with the link can view" is the most used sharing control in software, and it is not an access control. It is the absence of one, with a long identifier standing in for a decision about who should see the thing.

Products ship it because customers ask for it, it removes the friction of adding people one at a time, and it works. Then the link is pasted into a ticket, forwarded in an email chain, indexed because someone posted it publicly, and it keeps working for years.

This post is what to build around that feature so it stays defensible. For whoever owns sharing.

The properties a link actually has

A share link is a bearer capability: whoever presents it gets the access, with no identity involved. That is the same category as a presigned URL or an invitation token, and it inherits the same consequences.

It is copied by design. It travels through channels you do not control. It cannot be attributed, so your audit log shows an access with no actor. And it is usually permanent, because expiry was not part of the original story.

None of this makes the feature wrong. It makes the defaults and the surrounding controls the whole of the security.

Defaults decide what most customers get

Almost nobody changes a sharing default, so whatever you ship is the effective policy for the majority of your users.

Default to the narrowest useful scope, which is usually people already in the workspace rather than anyone with the link. Make the wider option a deliberate selection with a plain description of what it means: not "public", which people read as "on the internet somewhere", but "anyone who has this address can open it without signing in".

Offer an expiry, and default it to on. Thirty or ninety days covers the overwhelming majority of legitimate sharing, and it converts an indefinite grant into a bounded one without anyone managing it.

Let administrators set the ceiling. An enterprise customer will want to disable link sharing entirely, or restrict it to their own domain. If that control does not exist, their security review will ask for it, and the answer "you can ask users not to" does not survive the conversation.

Make it visible, because that is what fails

The recurring failure is not that sharing exists. It is that nobody can see what has been shared.

Three views are worth building:

Per item: who has access, including links, shown wherever the item is. If a document is publicly linked, the person opening it should be able to tell at a glance.

Per workspace: every active share link, with the item, who created it, when, and last access. This is the report an administrator needs and most products do not have. Without it, an access review of sharing is impossible in principle.

Per person, on departure: what this user shared, so it can be reviewed when they leave. Links created by someone who left keep working, and nothing in your offboarding touches them.

Log the accesses, even anonymous ones

An unauthenticated access is still an event worth recording: when, from where, which link. It will not tell you who, and it will tell you that a link created two years ago is being opened from an unexpected place, which is the signal that matters.

Show the last-accessed time in the interface. It is the cheapest way for a user to notice that something they shared once is still being read.

The link in the address bar leaks

If the capability is in the URL, it travels wherever URLs travel: browser history, the referrer header when the page links outward, corporate proxy logs, screen shares, and anything that unfurls links for a preview in a chat application.

That last one is worth knowing about: pasting a link into a chat tool often causes a server somewhere to fetch it, which for a bearer capability means the content has been retrieved by a third party before any human clicked.

You cannot prevent most of this, and you can reduce the window by defaulting to expiry, and reduce the damage by requiring a second factor for the most sensitive items rather than treating all shares alike.

Revocation has to be real and reachable

Two properties. Revoking a link must invalidate it immediately, including for anyone currently viewing, rather than leaving an open session working. And a user must be able to find and revoke their own links without asking support, or they will not do it.

Rotating the link identifier rather than deleting the record is worth doing, so the item stays reachable to people who should have it while the old address stops working.

Check yours

# Does a revoked link actually stop working?
curl -s -o /dev/null -w "%{http_code}\n" "$SHARE_URL"     # before: 200
# revoke in the UI, then immediately:
curl -s -o /dev/null -w "%{http_code}\n" "$SHARE_URL"     # want 404 or 410

# Is the identifier guessable? Create several and compare.
# Is the item reachable through the normal API with only the link token?
# Does the link grant more than it claims (view link that permits comment or download)?

That last one finds real bugs. A "view only" link that exposes an API the viewer can call with the same token frequently grants more than the interface suggests.

The concession

Requiring sign-in for every share would remove the whole class and would also remove the reason the feature exists. Sending a document to an external reviewer who has no account, and will never have one, is an entirely legitimate thing customers need to do, and a product that cannot do it loses to one that can.

So the position is not to restrict the capability but to bound it: narrow default, expiry on by default, an administrator ceiling, and a workspace-wide view of what is currently shared. Those four make the feature defensible in a security review without taking anything away from the person who just needs to send a file to their accountant.

The implication

Every share link is an access grant made by a user, usually in a hurry, with no expiry and no review, and collectively they are often the largest set of permissions in your product.

The question that reveals where you stand is whether an administrator can list them. If the answer is no, nobody can review what has been shared, and that is a gap in the product rather than in the customer's process.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.