I live in Cozumel, MX part-time. So when one person walked off with about 150GB of Mexican government data this winter — tax records, voter rolls, civil registry files, government logins — it was not abstract news to me. It was my neighbors' data.
The headline everyone ran with was 'AI hacked the Mexican government.' That is the wrong lesson. The AI did not invent a new way in. It ran the oldest trick in the book at machine speed: SQL injection.
What Happened
On February 25, 2026, the Israeli firm Gambit Security disclosed the campaign, first reported by Bloomberg. One unidentified operator, working for about a month starting in December 2025, hit roughly ten government bodies; the federal tax authority (SAT), the electoral institute (INE), several state governments, Mexico City's civil registry, even Monterrey's water utility.
The toolkit was not a nation-state arsenal. It was a consumer AI subscription. The operator jailbroke Claude Code, which means they talked it past its safety guardrails, with Spanish-language prompts, framing every request as an authorized 'bug bounty' and role-playing the model as an 'elite hacker.' When Claude balked, they switched over to GPT-4.1 to keep moving. Total haul: about 150GB, and roughly 195 million identities exposed.
The Part Nobody Wants to Say Out Loud
Gambit found at least 20 vulnerabilities exploited across those systems. None were exotic. Just exposed admin panels. Default credentials. Unpatched web apps matching CVE-2023-era patterns. Login pages with no rate limiting. The kind of risks sitting in thousands of shops right now — maybe even one that you support.
Here is the line from the logs that should stop every DBA cold. The operator had a frontier AI model at the keyboard. What did they have it write? Python SQL injection payloads against login pages on .gov.mx, built around a string straight out of a 2006 tutorial:
' UNION SELECT username, password FROM users--
That is not a 2026 attack. That is a 2006 attack, run at machine speed by something that never gets tired of rephrasing the prompt. Gambit's CEO called it this way: "This reality is changing all the game rules we have ever known." Maybe so. But the door it walked through is one we have known how to lock for twenty years.
SQL Injection, Still Undefeated in 2026
If you concatenate user input into a query string, you are vulnerable. It does not matter how clever your firewall is. Here is the whole problem and the whole fix, end to end. Run it on any version, sp_executesql has been there since forever.
CREATE TABLE dbo.Users
(
UserId int IDENTITY(1,1) PRIMARY KEY,
Username nvarchar(128) NOT NULL,
PasswordHash nvarchar(256) NOT NULL
);
INSERT dbo.Users (Username, PasswordHash)
VALUES (N'rlewis', N'hash_aaa'),
(N'admin', N'hash_zzz');
The vulnerable pattern
Build the query by gluing the input straight into the string, and you have handed over the keys to whoever is typing.
CREATE OR ALTER PROCEDURE dbo.GetUser
@Username nvarchar(128)
AS
BEGIN
DECLARE @sql nvarchar(max);
SET @sql = N'SELECT Username, PasswordHash
FROM dbo.Users
WHERE Username = ''' + @Username + N'''';
EXEC (@sql);
END;
Call it normally and it behaves:
EXEC dbo.GetUser @Username = N'rlewis';
Now feed it the kind of input the attacker used:
EXEC dbo.GetUser @Username = N''' OR 1=1 --';
The string your server builds and then runs becomes this:
SELECT Username, PasswordHash FROM dbo.Users WHERE Username = '' OR 1=1 --'
Every row in the table comes back. Username and password hash for every account, handed over by your own stored procedure. That is the breach, in miniature.
The fix: parameterize
The query text is fixed and the input rides in as a parameter, so the engine compiles the command before it ever sees the value. The input can only ever be a username to look up, never code to run. That is the whole difference: concatenation lets the attacker write SQL, parameters only let them supply a value.
CREATE OR ALTER PROCEDURE dbo.GetUser_Safe
@Username nvarchar(128)
AS
BEGIN
DECLARE @sql nvarchar(max);
SET @sql = N'SELECT Username, PasswordHash
FROM dbo.Users
WHERE Username = @Username';
EXEC sys.sp_executesql
@sql,
N'@Username nvarchar(128)',
@Username = @Username;
END;
Same malicious input, run again:
EXEC dbo.GetUser_Safe @Username = N''' OR 1=1 --';
Zero rows. The input is read as a literal username that simply does not exist, not as a condition:
(0 rows affected)
What This Means for You
The uncomfortable part of this story is how little of it is about AI. Strip the model out and you still have unpatched servers, over-privileged accounts, and login pages that a 2006 worm could have walked through. AI did not lower your defenses. It lowered the skill and the patience required to find the gaps you already had.
So the homework has not changed. It has only become more pressing.
| Control | Why it matters now |
|---|---|
| Parameterize everything | No concatenated user input, anywhere. sp_executesql or parameters, every time. |
| Patch on a real cadence | The 20 flaws were known and old. A model can find every one of them in minutes. |
| Least privilege | A compromised login should reach almost nothing. Scope every account down. |
| Rate limit and lock out | Machine-speed credential stuffing dies fast against throttling and lockouts. |
| Watch behavior, not signatures | No human types thousands of login attempts a minute. Alert on the pattern. |
The AI is new. The way in was not. Lock the door we have known about since SQL Server 6.5.
More to Read
Security Affairs: Claude Code abused to steal 150GB in cyberattack on Mexican agencies
HawkEye: How hackers used Claude to breach the Mexican government (the full attack chain)

No comments:
Post a Comment