A couple days ago I wrote up a post on Why We Moved From Lambda to ECS. One thing I was startled by was how a "warm" Lambda can behave between invocations. I thought I'd expand on that issue briefly with a simple example:
How I Thought Lambda Worked
My (incorrect) understanding of Lambda was that each invocation of a Lambda was isolated. I figured, besides the startup code that runs once when a "cold" Lambda gets warmed, that Lambda executions were stateless and wouldn't affect one another.
How It Actually Works
In reality, two Lambdas that run in parallel are perfectly isolated. However, if a Lambda has run and is sitting around "warm", subsequent executions using that Lambda might be affected by a previous execution.
Example Overriding console.log()
Suppose, for example, you have a simple Lambda with this code in index.js
:
exports.handler = async (event) => {
console.log("Hello, world!");
global.console.log = (msg) => {
console.error("Your message has been hijacked");
};
};
The first time this Lambda is invoked, you see a happy "Hello, World!" logged out.
If you test the Lambda again while the Lambda is still warm, though, the first invocation overrode the console.log()
function, so you end up seeing an error, "Your message has been hijacked".
You can imagine how someone might exploit this issue if they can invoke their own code in a Lambda that others then use.
Top comments (3)
An attacker who can execute arbitrary code would be a big problem in any execution context - wouldn't say this is a Lambda specific problem.
That's a good point - this isn't a Lambda-specific thing and you'd see it anywhere where people are executing code in shared spaces.
I'm just highlighting why for our use case - where we built a platform specifically for people to execute what code they want - we had to be aggressive about isolating execution environments from one another. Lambda just didn't let us have the isolation we needed.
Gotcha, yeah that's true.