fix(env): fix os.getenv prefix collision bug in init_by_lua phase#13147
Open
currenjin wants to merge 1 commit intoapache:masterfrom
Open
fix(env): fix os.getenv prefix collision bug in init_by_lua phase#13147currenjin wants to merge 1 commit intoapache:masterfrom
currenjin wants to merge 1 commit intoapache:masterfrom
Conversation
In OpenResty's init_by_lua phase, os.getenv() uses nginx's internal environment mechanism which performs prefix-based matching when env NAME=VALUE directives share a common prefix. This causes os.getenv() to return the shorter-named variable's value when the longer-named one is requested (e.g., KUBERNETES_CLIENT_TOKEN_FILE returns the value of KUBERNETES_CLIENT_TOKEN). The fix overrides os.getenv in _M.init() with a wrapper that uses exact table lookup from apisix_env_vars (built correctly from ffi.C.environ). Also moves core.env.init() to be the first call in http_init() to ensure the override is applied before any other code in init_by_lua can call os.getenv. Fixes apache#13055
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In OpenResty's
init_by_luaphase,os.getenv()uses nginx's internal environment mechanism which performs prefix-based matching whenenv NAME=VALUEdirectives share a common prefix. This causesos.getenv()to return the shorter-named variable's value when the longer-named one is requested.Example: with both
KUBERNETES_CLIENT_TOKENandKUBERNETES_CLIENT_TOKEN_FILEdefined asenv NAME=VALUE;directives, callingos.getenv("KUBERNETES_CLIENT_TOKEN_FILE")returnsKUBERNETES_CLIENT_TOKEN's value when the shorter name appears first in the config.Fixes #13055
Root cause
OpenResty's
os.getenvininit_by_luadoes not perform exact-match lookup whenenv NAME=VALUE;directives have a common prefix — the shorter name is matched first. In contrast, readingffi.C.environdirectly with Lua string operations (as_M.init()already does) produces a correctly keyed table.Fix
apisix/core/env.lua: After_M.init()populatesapisix_env_varsfromffi.C.environ, overrideos.getenvwith a wrapper that does exact table lookup. Falls back to the originalos.getenvfor variables set dynamically after startup (e.g., viacore.os.setenv).apisix/init.lua: Movecore.env.init()to be the first call inhttp_init(), ensuring the override is applied before any other code ininit_by_luacan callos.getenv.Tests
os.getenvreturns correct values when shorter-prefix variable is declared first in nginx config.os.getenvcalled insideinit_by_lua(viaextra_init_by_lua) returns correct values for prefix-colliding variables.Risk / Compatibility
os.getenvis monkey-patched globally after_M.init(). Existing callers continue to work — the semantics are identical for non-colliding variable names.core.os.setenvfall back to the originalos.getenv, so those are unaffected.http_initis safe:core.env.init()has no dependencies onresolveroridinitialization.