Chapter 44 / 51
Volume 5 · Extensions, Ops & Projects

Security boundaries & the trust model: the price of full power

The book's recurring "no sandbox" gets its complete definition here. Understanding where the trust boundary sits matters more than memorizing ten security tips.

Overview

Positioning: not a penetration manual — a threat-modeling chapter. The deliverable is your own deployment audit checklist. Prerequisites: ch. 03 (capability surface), ch. 40 (nested compilation).

44.1 Intro

Most runtimes' security model is "least privilege by default"; XServer is the opposite — full privilege by default: scripts can call 3,030 APIs (including the full process/file/network suites), open another compiler, and use system libraries directly on Windows. The trade buys zero boundary overhead and complete capability, at the price of placing trust in the right location. This chapter makes "where" explicit.

44.2 The full meaning of "no sandbox"

a piece of script = native code in the host's own process ├── same address space: a wild pointer pierces the whole service ├── same privileges: reads everything the host can read (private keys included) ├── can recompile: xsCreateTCC → arbitrary new code └── can reach out / spawn: xrtProcessRun / native sockets Conclusion: control of the devfile = control of the server
MisconceptionReality
"if the script crashes, the host survives"It doesn't — same process; one segfault ends the whole service
"not exporting dangerous APIs is safe"the symbol table has no signature checks; scripts can extern any host symbol
"nested compilation can be disabled"it's an exported symbol — controlling the devfile controls everything, and vice versa

This isn't a defect list — it's a design fact: xsbase.h's first screen says "zero limits: no sandbox, no permissions, no namespaces; everything is open to the application". An honest boundary declaration is safer than a false isolation promise.

44.3 Trust layers

LayerPartyTrust verdictDefense
0the deployer (whoever places the devfile)fully trusted — equivalent to server loginOS accounts and file permissions
1script authors (if different from the deployer)treated as "can write server code"code review / commit-access management
2plugin submitters (the ch. 40 scene)untrusted — unless you narrowed the capability surfaceyour own symbol whitelist (below)
3public-network clientsnever trustedprotocol-layer defenses (44.4) + application auth

Layer 2 is the only one requiring work: when a plugin system accepts external code, inject via tcc_add_symbol only your own plugin_api_* whitelist set, hand out no xsCreateTCC, no VFS headers — a quasi-sandbox that is lexically and symbolically restricted. It won't stop malicious machine code, but it stops "dangerous code written by honest people" — the true strength of this class of boundary.

44.4 The public-network defense summary

Layer 3's (client) defenses are scattered across chapters; collected into one audit checklist:

  • Transport: TLS endpoints + certificates dispatched per host (ch. 08/12); a plaintext endpoint should be a decision, not a default
  • Request limits: header/path/body_limit (431/414/413) tightened per business (ch. 09)
  • Time limits: idle_timeout against slow-loris (validated by drill's slowloris sample)
  • Static layer: the eight-vector traversal defense + deny_dotfiles (ch. 10)
  • WS: ws_message_limit (1009) + subprotocol enforcement (ch. 22)
  • Binary protocols: xtp2 limits effective at header time + bad frame = disconnect (ch. 33)
  • Management plane: auth + intranet vhost (ch. 27); deep physicals separated from the LB probe (ch. 43)
  • SQL: parameter binding with zero exceptions (ch. 32)
  • Business auth & input validation: your code — XServer neither does it for you nor stops you

44.5 Contract

  • Boundary: devfile control = server control; client trust = never.
  • Layering: external code enters the plugin layer only after the capability surface is narrowed.
  • Audit: run the 44.4 checklist before going live; re-run the relevant items whenever a route/knob/plugin is added.

Common mistakes

Compiling user input into plugins
Symptom
Some "advanced feature" lets users submit C code snippets for server-side execution.
Cause
Treating a layer-3 party as layer 0 — equivalent to handing out server shells to registered users. Expression evaluation should go through grammar-based parsing (a restricted grammar) or a strictly whitelisted mini-evaluator; even with ch. 40's compile cache, open it only to trusted sources.
A plaintext management port exposed to the public network
Symptom
/admin/* carries only a simple password and rides port 80.
Cause
The management plane is valuable enough to deserve the full treatment — TLS + dedicated vhost + intranet binding (the ch. 20/27 combo).

Exercises

BasicA deployment audit

Audit your demo deployment against 44.4's checklist; output "met / missing" columns.

Acceptance: every missing item has a remediation plan (config change / code change / accepted-risk rationale).
AdvancedA whitelist plugin boundary

Wrap ch. 40's plugin system in a plugin_api_* whitelist (no xsCreateTCC, no file APIs); document the boundary's strength.

Acceptance: plugins calling off-whitelist symbols fail to compile; the documentation doesn't overstate the boundary.
ChallengeAn attack drill

Run a drill-style attack round against your own service (slow/oversized/traversal/bad frames); record which defenses fired.

Acceptance: each attack class names the defense that stopped it; nothing penetrates to the script layer.

Summary

PointConclusion
Modelfull privilege by default; trust placed rightly rather than capabilities shrunk
Factsdevfile control = server control; no process-level isolation
Layersdeployer fully trusted / plugins narrowed first / clients never trusted
Defensesthe nine-item public checklist (44.4) as the audit baseline
xrt further reading