( proposed only )
BASIC++ implements a six-level security system that controls access to operating system resources, file operations, network connections, and system commands. The security system is enforced at the virtual device layer — security checks occur in the VFS, VNet, and VDev subsystems before operations reach the platform layer. This means individual statement handlers do not need security logic; the device layer handles enforcement uniformly.
The security system is implemented in engine/src/security/security.c and is part of the libkernel library.
| Level | Name | Description |
|---|---|---|
| 0 | OPEN | No restrictions. All operations permitted. |
| 1 | SAFE | Minor restrictions. File deletion limited to current directory. |
| 2 | STANDARD | File write/create restricted to current directory. No SHELL. |
| 3 | EDUCATIONAL | File read/write restricted to current directory. No file creation. No SHELL. |
| 4 | RESTRICTED | No file access. No network. No SHELL. No POKE/OUT. |
| 5 | PARANOID | Pure computation only. No I/O of any kind. |
From the command line:
baspp --security=2 # Standard level
bpp --security=4 # Restricted level
bs --security=3 script.bas # Educational level for script executionFrom within a program:
10 SECURITY 3 ' Set to Educational levelThe SECURITY statement can only raise the security level, never lower it. Once raised, the level cannot be reduced without restarting the interpreter. This prevents untrusted code from escalating its own privileges.
| Operation | L0 | L1 | L2 | L3 | L4 | L5 |
|---|---|---|---|---|---|---|
| PRINT to console | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ |
| INPUT from keyboard | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ |
| File read (any path) | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
| File read (CWD only) | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ |
| File write (any path) | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ |
| File write (CWD only) | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ |
| File create | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
| File delete | ✓ | ✓* | ✗ | ✗ | ✗ | ✗ |
| Network connect | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
| Network listen | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ |
| SHELL / EXEC | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ |
| POKE / OUT | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ |
| MODULE LOAD | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
| ENVIRON (set) | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ |
*L1 file delete is restricted to the current directory.
When an operation is denied by the security system, Error 70 (Permission denied) is raised. The error message includes the security level and the type of operation attempted:
Permission denied at security level 3: Cannot access file outside current directory
Programs should use ON ERROR GOTO or TRY/CATCH to handle security denials gracefully.
RESTRICT provides fine-grained control within a security level:
10 RESTRICT FILE "*.bas" ' Only allow access to .bas files
20 RESTRICT NET "localhost" ' Only allow connections to localhost
30 RESTRICT PATH "/home/user/safe" ' Only allow this directoryRESTRICT rules are additive to the security level — they can further limit access but cannot grant access that the security level denies.
When a module is loaded (MODULE LOAD), it passes through the security pipeline:
- Validation — The module file is checked for integrity.
- Capability Verification — The module's declared capabilities are compared against the security level. A module that requires network access cannot load at level 3+.
- Sandbox Allocation — The module receives a sandboxed execution context.
- Registration — Module-provided keywords and devices are registered.
- Activation — The module is activated and its init function runs.
Modules cannot bypass the security system. They cannot directly modify VM instructions, execute host code, or corrupt internal stacks.
The bs batch runner should use elevated security levels when executing untrusted scripts:
# Run a student's homework with educational restrictions
bs --security=3 homework.bas
# Run a CGI script with restricted access
bs --security=4 cgi_handler.basThe security level applies globally to all tasks. Background tasks cannot operate at a different security level than the main program. If the security level is raised while tasks are running, all tasks are immediately subject to the new restrictions.
When the --log flag is enabled, security denials are logged with full context: the operation type, the file or resource involved, the security level, and the line number. This log is invaluable for debugging permission issues:
[SECURITY] DENY level=3 op=FILE_WRITE path="/etc/passwd" line=150
[SECURITY] DENY level=2 op=SHELL cmd="rm -rf /" line=200