Back to evidenceelgarsabolins.com

E-02 · POST-MORTEM

zippp.eu, an honest post-mortem

I built and ran a URL shortener with click analytics on AWS. It worked. But if someone had asked "were you breached?", I couldn't have answered. Here's what I got wrong, what I got right, and what I'd do now.

stack
Laravel on AWS
live
~6 months
status
retired, domain kept
written
Oct 2026

6 findings from my own review

2high1medium1to review2done right

Then and now

HOW IT RAN
Me
Root userMFA on, used for everything
Every resource in the accountservers, storage, database, billing
no audit logexposure never checked
HOW I'D RUN IT NOW
Me
IAM Identity Centersign-in with MFA
Least-privilege rolesadmin for me, a narrow role for the app
Root userlocked away, billing and recovery only
CloudTrail, all regionsGuardDutyCIS checks in Security Hub

What I got wrong

F-01HIGH

Root account used for daily work

WHAT HAPPENED

MFA was on, but everything ran through the root user. Root can't be limited by any policy, so one stolen session would have meant losing the whole account.

WHAT I'D DO NOW

Root locked away with MFA and no access keys, used only for billing and recovery. Daily work through IAM Identity Center, and the app on a narrowly scoped role.

F-02HIGH

No audit logging

WHAT HAPPENED

CloudTrail was never turned on. There was no record of who did what in the account, so a breach would have been invisible.

WHAT I'D DO NOW

CloudTrail in every region and GuardDuty from day one, before the first deploy.

F-03MEDIUM

Public exposure never checked

WHAT HAPPENED

I never checked whether security groups, storage buckets or the database were reachable from the internet.

WHAT I'D DO NOW

AWS Config or Security Hub checked against the CIS AWS Foundations Benchmark, plus an external exposure scan. That scan is exactly what my thesis scanner does.

F-04TO REVIEW

Abuse handling

WHAT HAPPENED

Shorteners are a favourite tool for phishing because they hide the destination. And, I didn't have a way to handle abuse reports, so I could have been used to host phishing pages.

WHAT I'D DO NOW

Check every submitted link against Safe Browsing and blocklists, rate-limit link creation, and publish a takedown contact.

What I got right

Shutting it down safely

Switching a service off is a security task too. Leftover resources cost money, and an expired domain lets anyone take over every link you ever issued.

  • DONEClosed the AWS account, so no servers, buckets, snapshots or bills are left behind.
  • DONEDomain kept, so nobody can re-register it and redirect old short links to phishing pages.
  • DONEAuto-renew, registrar lock and MFA on the registrar account.
  • PLANNEDEvery old short link returns 410 Gone so a dead link fails safely.
  • PLANNEDDMARC on the domain, now used for email, so nobody can send mail pretending to be it.

What I took from it

  1. Without logs, you can't answer the one question that matters after an incident.
  2. Use root only for billing and emergencies.
  3. Decommissioning needs a checklist as much as launching does.