We Pointed An Overnight Audit At Our Own Platform. It Found A Door We Left Open.
Everyone loves a security post about someone else's mess. This one is about ours.
We set an audit running against the Aiva backend overnight, told it to be rude about what it found, and read the report over coffee. It came back with a list. Most of it was housekeeping. Three of them made me put the coffee down.
The one that actually mattered
There was a controller in there called ActivityLoggingTestController. Four hundred and forty-six lines of it. Built at some point to prove the HighLevel activity logging worked, then never removed.
It had no [Authorize] attribute on it.
So the situation was: an unauthenticated endpoint, sitting on a public API, that could write activity records into any client's HighLevel CRM if you knew a location id. Location ids are not secret. They turn up in URLs.
Nobody found it. Nothing bad happened. That is luck, not architecture, and luck is not a control.
It is deleted. Along with a seed-referral-sales endpoint that generated fake sales data, which is exactly the sort of thing you write for a demo at 11pm and then forget is still wired into production.
The one that was just embarrassing
A Console.WriteLine left in from a debugging session, printing part of the admin API key to the logs. Not the whole key. Enough of it that you would not want it in a log aggregator that half a dozen people can read.
Gone.
The one that was subtly worse than it looked
Program.cs had two separate AddCors registrations and then a bare app.UseCors() with no policy named.
If you have not hit this one before: a bare UseCors() with no named policy does not fall back to your strict policy. It falls back to the default, and the default in that configuration was effectively AllowAnyOrigin. In production. Quietly. For months.
That is the kind of bug you cannot find by reading the strict policy you wrote and feeling good about it. You find it by reading what the framework does when you do not tell it which policy to use.
Consolidated into one registration, one named policy, no bare call.
The rest of the list
[Authorize(Roles = PlatformAdmin)]added to the agency admin controller, which had been relying on nobody guessing the route.- Every hardcoded
localhostURL pulled into configuration, because a hardcoded localhost in a deployed app is either broken or pointing somewhere you did not intend. - Config source ordering corrected, and secrets excluded from publish.
appsettings.Development.jsonand a local settings file had been tracked in git with keys in them. Both removed from tracking, then the keys rotated, because a key that has been in a repo is a former key. - Dependency injection registrations tidied and the SDK bumped.
Why write this up
Two reasons.
One, because we tell clients to let us audit their stuff, and it would be a bit rich to do that without eating our own cooking.
Two, because the interesting thing here is not the bugs. Every codebase has them. The interesting thing is that an agent reading the whole repo overnight found things that four humans reading diffs had walked past for months. Not because it is smarter. Because it does not get bored on file two hundred, and it does not assume the controller with "Test" in the name is harmless.
That is a genuinely new capability and it is worth pointing at your own code first.