Someone on your team pushed a Cloud Run function last sprint, and nobody remembers whether it takes user input. It probably does. That is the class of surface Mandiant took a swing at this week.
In a Google Cloud Threat Intelligence post dated 2026-07-15, Corné de Jong wrote up what Mandiant keeps finding in security assessments: publicly exposed serverless applications with no authentication in front, running custom code that pulls in third-party packages, and doing shell-adjacent things with user input. The two attack classes the post names are Local and Remote File Inclusion (LFI/RFI) and Command Injection. The old ones, on the new hosting model.
Why "just add auth" is not the answer
Mandiant is careful about the reason authentication is often absent. It is not always negligence. Sometimes the endpoint is public because the business requirement makes it public: a webhook receiver, a partner integration, a public API with no login concept. The auth question ducks out of the room, and the code behind the URL has to hold the line by itself.
So the guidance is not "put a login screen on it". The advice is: assume the endpoint stays public and go layer by layer.
What the post recommends, from network in
Segregate first. Mandiant asks teams to host public-facing Cloud Run services in a dedicated, isolated Google Cloud project, in what it calls a Service Project model. If the function is compromised, the blast radius stops at a project that has nothing else in it.
Above the function goes a Layer 7 Application Load Balancer, with the function's own ingress restricted to internal only. That flips the internet-facing surface up to the load balancer, which brings Cloud Armor as its WAF. The post gives Cloud Armor policy snippets aimed at the two attack classes it opens with: evaluatePreconfiguredWaf('lfi-v33-stable', {'sensitivity': 3}) for LFI and evaluatePreconfiguredWaf('rce-v33-stable', {'sensitivity': 3}) for RCE. Same shape, different signature set.
Below the function goes IAM. The post pushes teams off the default Compute Engine service account and onto a custom service account per function, scoped to only what that function needs. The concrete examples in the write-up: Storage Object Viewer restricted to a single bucket, Secret Manager Secret Accessor restricted to individual secrets. If the function only reads one bucket and one secret, those are the two grants.
For traffic leaving the function, Mandiant recommends VPC Service Controls wherever the function uses direct VPC egress or a VPC Access connector. If the function gets popped, the exfiltration path terminates at a controlled service boundary.
The line that belongs in the pipeline
Buried a few paragraphs in is the item CI/CD teams should read twice. Mandiant recommends integrating security scanning, code review, and least-privilege IAM into the pipeline before deployment, plus continuous security testing after. The runtime controls Mandiant lists are the safety net. The pipeline is where a call to system() with a user-controlled string is supposed to get caught while a human still owns it.
The same section carries a newer twist Mandiant labels Vibe Coding Security. The recommendation: isolate AI-generated code in dedicated sandbox environments with strict data-egress controls, so an agent writing shell-adjacent Python does not brush against production data on the way to being reviewed. If your inner loop now includes an LLM emitting deploy targets, this is the row it belongs on.
Detection, once the request has already landed
For the case where prevention did not hold, the post points at Google Cloud Security Command Center's Cloud Run Threat Detection, which flags credential access, reconnaissance, and execution of scripts or reverse shells against Cloud Run resources. The post notes the service is available on the Premium and Enterprise tiers. Worth reading twice: the detection layer is a paid product.
One separate line, the one people still get wrong: never store secrets or credentials in source code or local container files. Use Secret Manager, or an equivalent store on whatever cloud you are on.
Verdict
Nothing in the post is a surprise to anyone who has done a serverless review. What is useful is that Mandiant, which sees the incidents, put its recommendations in one place, in a shape a platform team can copy into a checklist. Load balancer in front. Custom service account per function. WAF policy blocking the two classes that keep landing. Secrets in a secret manager, never in source. Security scanning in the pipeline before the deploy, not after.
The Cloud Armor snippets and IAM role names are Google-specific. The pattern reads the same on any cloud that offers a function, a WAF and a secret store in one account. If someone on your team still treats a public function URL as private because it does not look like a server, this is the post to hand them on Monday.
Top comments (0)