Lua Academy · Lesson

The _ENV Model in Lua 5.2+

Understand how _ENV replaced setfenv and enables environment control.

Lesson 1 of 413 steps

The _ENV Model in Lua 5.2+ is a free Lua Academy lesson on CoddyKit. This is lesson 1 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, and your progress syncs across the web and the CoddyKit app. The Lua Academy course includes 4 lessons in total.

What Is _ENV?

In Lua 5.2+, every chunk has an implicit upvalue called _ENV. All global variable accesses are rewritten as field accesses on _ENV. So print(x) becomes _ENV.print(_ENV.x).

_ENV Replaces setfenv

In Lua 5.1, setfenv(fn, env) changed a function's global environment. In 5.2+, this is gone. Instead, set _ENV as a local to change the environment of a chunk or block.

Changing _ENV in a Chunk

Set _ENV at the top of a chunk to redirect all global accesses.

-- Everything in this chunk uses myEnv as globals
local _ENV = myEnv
print("hello")  -- calls myEnv.print("hello")

Local _ENV for a Block

Scope _ENV changes to a do...end block to limit the effect.

do
  local _ENV = {print = print, x = 42}
  print(x)  -- 42 from local _ENV
end
print(x)  -- original _ENV.x (global x)

Using load with _ENV

load(chunk, chunkname, mode, env) executes a string as a chunk with a custom environment. This is the primary sandboxing mechanism in 5.2+.

local env = {print = print, math = math}
local fn, err = load("print(math.sqrt(16))", "sandbox", "t", env)
if fn then fn() end  -- 4.0

Reading the Current _ENV

The current chunk's globals are _ENV. To get a reference: local myEnv = _ENV.

Modifying _ENV at Runtime

Setting a global variable is _ENV.varName = value. Since _ENV is an upvalue, you can swap it for a different table at any point in the code.

Inheritance with __index

Give the sandbox environment a metatable with __index = _G to fall back to the real global table for functions you haven't explicitly blocked.

local sandboxEnv = setmetatable({}, {__index = _G})
-- then block dangerous ones:
sandboxEnv.os = nil
sandboxEnv.io = nil
sandboxEnv.load = nil

Detecting _ENV Access Attempts

Replace dangerous globals with a sentinel that logs access attempts for security auditing.

sandboxEnv.os = setmetatable({}, {
  __index = function(_, k)
    ngx.log(ngx.WARN, "Blocked access: os." .. k)
    return nil
  end
})

Compatibility Note

Libraries using Lua 5.1's setfenv/getfenv need to be rewritten for 5.2+. Some use a compatibility shim in init code.

Practical Impact

The _ENV model makes sandboxing cleaner and more consistent. There is one clear mechanism for environments rather than two (setfenv for functions vs globals for top-level).

_ENV Question

How does Lua 5.2+ rewrite the global access print(x)?

Recap: _ENV Model

Lua 5.2+ makes all global access go through the _ENV upvalue. Use load(code, name, "t", env) to execute code in a custom environment. This is the standard sandboxing mechanism replacing setfenv.

Free to start

Learn Lua with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
40
Lessons
159

Frequently Asked Questions

Is the “The _ENV Model in Lua 5.2+” lesson free?

Yes — any 3 lessons of the Lua Academy learning path, including “The _ENV Model in Lua 5.2+”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Lua Academy course includes 4 lessons in total.

What will I learn in “The _ENV Model in Lua 5.2+”?

Understand how _ENV replaced setfenv and enables environment control. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Lua Academy?

No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 1 of 4.

How long does the “The _ENV Model in Lua 5.2+” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Lua Academy lesson?

Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. The _ENV Model in Lua 5.2+
  2. Building a Restricted Sandbox
  3. Preventing Sandbox Escapes
  4. Resource Limits and Instrumentation
← Back to Lua Academy