Let's talk
security

The audit log was empty, so nobody knew who changed what

A hire business relied on its audit trail. It held nothing for ID, bank and odometer changes, and no row for 1,231 vehicle documents. Two quiet faults.

·

A hire-office desk with car keys beside a laptop showing the vehicles list in Sazinga Rentals.

Someone changes the expiry date on a car’s insurance record. Or a customer’s bank details, which decide where a refund goes. You open the audit trail to see who, and there is nothing there. Not an old entry missing: no entry at all.

That was the state of the audit trail for a self-drive and taxi hire business in Goa, when we looked. Saves to a customer’s ID details, bank details, rating, damage record and odometer left no log line. The vehicle-document audit table had recorded zero changes against 1,231 vehicle documents. The cost is a risk rather than a figure: for any of those changes the question “who did this, and what was it before?” had no answer.

What was actually going on

Two unrelated faults with the same shape: the logging failed, and nothing said so.

The booking logger is meant to record the difference between a record before and after a save. It took its “before” copy after the save had already happened to the same object, so before and after were identical and the difference was always empty. Every save of ID, bank, rating, damage and fuel looked like no change.

The vehicle-document logger was worse. It asked for a model by a name with one extra letter. The call failed with “cannot read properties of undefined”, and the handler around it only printed the error to a console nobody reads. That happened 226 times without a sound.

We checked it was the only fault of its kind by cross-checking all 100 model names used in the code against the 72 registered. The other unregistered names were leftovers from code belonging to a different product.

What we changed

The “before” copy is now taken before the save, and two more fields (licence number and identity proof) are tracked. The misspelt name was corrected and the handler upgraded so a failure is recorded as a real error. On the test system we changed a customer’s rating and confirmed a log row now appeared.

What it did not fix

There is no history from before the fix. The 226 silent failures are gone for good, and the booking changes made while the logger was empty cannot be reconstructed from it.

One more reference to a model that does not exist was found in code from a different product and left alone, flagged for a decision on cleaning it up. The live server’s own error log also still had no timestamps and no rotation.

The pattern, for anyone who relies on an audit trail

An audit trail that has never been read is an assumption. Make one change, such as a rating or a phone number, then look for the line. If there is none, the trail is decorative.

The same test works on any record you rely on later: an empty table next to a busy one is a finding, not an absence of problems.

Where this ends up

Change history the office can trust, recorded where the change happens, is part of what Sazinga Rentals keeps for each booking.

This came out of building Sazinga Rentals

Bookings, availability and the fleet standing behind them. The problem above is one we met while building it, and what we did about it is in the product.

If you run something like this, there is one thing you can do without a call: send one week's booking sheet.