Supex is designed for local development use. This document describes the security features and recommendations.
Supex exposes Ruby code execution capabilities over TCP sockets. The primary threats are:
- Unauthorized access: Other local processes connecting to the server
- Path traversal: Accessing files outside intended directories
- State pollution: Interference between eval calls
By default, both Bridge and REPL servers bind only to loopback addresses (127.0.0.1, localhost, ::1). This prevents network access from other machines.
To allow binding to non-loopback addresses (not recommended):
export SUPEX_ALLOW_REMOTE=1When binding to non-loopback addresses without authentication, a security warning is logged.
Set a shared token to require authentication for all connections:
# On the machine running SketchUp
export SUPEX_AUTH_TOKEN=your-secret-token
# When using the driver/CLI
export SUPEX_AUTH_TOKEN=your-secret-token
./supex statusWith authentication enabled:
- Clients must provide the token in the
hellohandshake - Invalid or missing tokens result in error code
-32001 - The connection is rejected immediately
Recommendations:
- Always use authentication when binding to non-loopback addresses
- Use a strong, random token (e.g.,
openssl rand -hex 32) - Do not commit tokens to version control
File operations (eval_ruby_file, open_model, save_model, take_screenshot) are restricted to specific directories.
Default allowed paths:
- repository
.tmp/directory
Configure allowed paths:
# Set project root (recommended for most use cases)
export SUPEX_PROJECT_ROOT=/path/to/your/project
# Add additional allowed paths (colon-separated)
export SUPEX_ALLOWED_ROOTS=/path/one:/path/twoThe path policy:
- Resolves symlinks to prevent symlink escape attacks
- Checks that the resolved path starts with an allowed root
- Rejects paths containing
..traversal attempts
Error handling: Attempts to access paths outside allowed roots result in error code -32002.
To disable path restrictions entirely (not recommended):
export SUPEX_ALLOWED_ROOTS=*This is useful for debugging but should not be used in shared environments.
Each eval_ruby call executes in a fresh binding context. This means:
- Local variables from one eval do not persist to the next
- Instance variables on the binding object are not shared
- Global variables and constants do persist (Ruby limitation)
- Global variables (
$foo) - Constants defined at top level
- Modifications to existing classes/modules
- SketchUp model state
- File system changes
- Avoid relying on state between eval calls
- Clean up after operations that create global state
- Use
Sketchup.undoto revert model changes during development
Supex is designed for development, not production deployment. If you must run it in a shared environment:
- Always enable authentication (
SUPEX_AUTH_TOKEN) - Keep binding to localhost only
- Configure minimal path allowlists
- Monitor the SketchUp process for unusual activity
Even with localhost binding, consider:
- Blocking ports 9876 and 4433 from external access
- Using application-level firewalls to restrict which processes can connect
Enable verbose logging to track all operations:
export SUPEX_VERBOSE=1 # Runtime verbose logging
export SUPEX_LOG_DIR=/var/log/supex # Driver log directoryLogs include:
- Connection attempts (with agent identifier)
- All method calls with request IDs
- Error conditions and authentication failures
For local development (default):
- Using localhost binding (default)
- Path restrictions configured via
SUPEX_PROJECT_ROOT
For shared environments:
-
SUPEX_AUTH_TOKENset with a strong random value -
SUPEX_PROJECT_ROOTandSUPEX_ALLOWED_ROOTSconfigured - Firewall rules in place
- Logging enabled
- Configuration - All environment variables
- Protocol - Authentication in the hello handshake
- Troubleshooting - Authentication error handling