Article 12: Security & Abuse Prevention
The Dark Side of URL Shorteners
Building the system is half the battle. Protecting it is the other half. URL Shorteners are a favorite tool for attackers. Why?
- Phishing:
short.app/loginlooks safer thanattacker.com/steal-creds. - Malware:
short.app/updatehidesvirus.exe. - Spam: Sending 100k SMS messages with a short link is cheap.
If we don’t handle this, our domain will be blacklisted by Gmail, Outlook, and Twitter within a week.
1. Malicious Content Detection
We cannot blindly redirect users. We are responsible for where we send them.
Step 1: Sync Filtering (The “No-Fly List”)
Before creating a link, we check the domain against a local blacklist.
baddomain.com-> 403 Forbidden.virus-site.net-> 403 Forbidden.
Step 2: Async Scanning (Google Safe Browsing)
We can’t scan every URL in real-time (it adds 500ms latency). Instead, we use our Async Architecture (from Article 9).
- User Create: Return 201 OK immediately.
- Worker: Pick up the URL.
- Scan: API call to Google Safe Browsing or VirusTotal.
- Action: If malicious, ban the link (mark
is_active=false).
The Lag: There is a 2-second window where the link is live. This is an acceptable trade-off for performance.
2. Iteration Attacks (Enumeration)
The Attack: A competitor writes a script to request /aaaa, /aaab, /aaac… effectively scraping our entire database.
They can find private links, analyze our growth, or clone our data.
Defense 1: High Entropy
We chose Base62, but if we use a counter (1, 2, 3…), the IDs are predictable.
This is why Snowflake IDs or Randomized Hashing (Article 7) are superior. Calculating the “Next ID” from aZb9 is much harder than 1001.
Defense 2: Honey Pots
We inject “fake” short codes into the potential ID space. If an IP hits 10 non-existent links in 1 minute, they are scanning. Ban the IP.
3. Rate Limiting (Abuse)
We need multiple layers of Rate Limiting (Token Buckets).
| Layer | Limit | Purpose |
|---|---|---|
| IP Address | 100 Creates / hour | Stop Spam Bots. |
| User Account | 10,000 Creates / day | Stop Account Takeovers. |
| Global | 10,000 Redirs / sec | Stop DDoS hitting the origin. |
The 429 Strategy: When a limit is hit, return HTTP 429. Do not burn CPU cycles rendering a “Sorry” page. Just drop the connection or send the header.
4. The 302 Redirect Trap
The Vulnerability: Open Redirects.
If we allow parameters like short.app/login?redirect=evil.com, we are vulnerable.
In our design, strict validation of the long_url is mandatory.
We only redirect to the URL stored in the DB, never to a URL passed in the query string.
Summary
Security in a URL shortener isn’t just about SSL (which is mandatory). It’s about Reputation Management. If we allow 1% of links to be malware, valid users will stop clicking. By implementing Async Scanning and Rate Limiting, we protect both our infrastructure and our users.