by Serguey Shinder
It arrived through a request that was entirely reasonable. Marketing wanted to understand where people dropped out of the signup flow, a vendor offered to tell them, and the integration was one line of markup pasted into the shared template. I looked at it for about a minute, decided it was not my decision to make, and went back to what I was doing.
That one line loaded a script from someone else's server. Not a copy of a script. A live fetch, on every page load, of whatever that server chose to send us that day. Which meant that from the moment we shipped it, a company we had a purchase order with and no technical relationship to could execute code in the browser of every logged-in customer we had, on every page, including the ones with account details on them.
Nobody had lied to us. The vendor was legitimate and remains so. But the shape of what we had agreed to was not the shape anyone in the room believed we had agreed to. We thought we had bought analytics. What we had actually granted was standing permission to run arbitrary code inside our own front end, revocable only by us noticing.
I found this out properly during an unrelated investigation, tracing a request I did not recognise and following it back to the template. What unsettled me was not the vendor. It was the count. There were four such tags by then, added over two years by four different well-intentioned people, none of whom had gone through anything resembling a review, because pasting a line into a template does not feel like installing software. It feels like configuration.
The dependency in the build gets a version number, a lockfile, a scanner, and a conversation when it changes. The dependency loaded at runtime from a third party gets none of that, and it has strictly more power, because it is not pinned to anything. Whatever is on that server when the page loads is what runs.
We did not remove them, in the end, which I think was the right call and was certainly the practical one. We pinned what could be pinned, moved the rest behind a policy that limited what the browser would let them reach, and wrote down which page each one was actually needed on, which turned out to be far fewer than all of them.
The habit I kept is a question rather than a rule. Before anything goes into a shared template, I ask who can change what this does, and how would we find out. Most of the time the answer is fine. The times it is not, the answer is that a company we have never spoken to can change it whenever they like, and we would learn about it from a customer.
– Serguey Asael Shinder
Leave a Reply