fix(server): refuse open-in-editor when not bound to loopback - #2
Draft
jscheid wants to merge 3 commits into
Draft
fix(server): refuse open-in-editor when not bound to loopback#2jscheid wants to merge 3 commits into
jscheid wants to merge 3 commits into
Conversation
Classifies a bound address as loopback-only using node:net isIP and BlockList, so IPv4-mapped and long-form IPv6 loopback are recognised and malformed values are not.
DIFIT_EDITOR takes precedence over EDITOR, and blank values count as unset. Returning the source alongside the value keeps the guard and the request resolution from encoding that order separately.
The handler spawns a command taken from the request body, so anything reaching the port ran code as our uid. The guards consult the address the socket actually bound to, and honour the environment ahead of the caller-supplied editor id.
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.
POST /api/open-in-editorreadscommandandargsTemplatefrom the request body and passes them tospawn, so anything able to reach the port executes code as the server's uid.DIFIT_EDITOR=nonedid not close it, because the check consulted the caller's owneditor.idbefore the environment.This matters now because the branch above this one requires binding
0.0.0.0so a reverse proxy can reach the server, which puts that endpoint in front of every neighbour on a flat container network.What this adds
node:net'sisIPandBlockListrather than string matching.DIFIT_EDITOR=none/EDITOR=nonefrom the environment regardless of what the caller claims.This is the narrow fix, not an authentication system. Resolving the spawn spec from server-side configuration instead of the request body remains the real fix and is tracked separately.
Notes for the reviewer
--hoststring. Node'slistenexpands abbreviated forms throughgetaddrinfothatisIPrejects, so--host 127.1binds loopback while classifying as external — over-blocking, and a warning that lies.isLoopbackHostreturningtruemeans the guard does not fire. Over-classifying widens what is permitted; under-classifying merely over-blocks. An indeterminate bound address is treated as not loopback.DIFIT_EDITORcounts as unset, otherwise it maskedEDITOR=noneand silently re-enabled the spawn.Verification
pnpm test929 passed / 2 skipped ·pnpm checkclean ·pnpm buildclean. Run under the pinned toolchain (mise exec -- pnpm …); Node 26 produces ~70 spuriouslocalStoragefailures against this repo's happy-dom/vitest pairing.