Security Guardrails
How VenJS keeps client-to-database requests safe by default.
Defense layers
1. Prepared statements only
Every query is built with PDO::prepare() + bound parameters. No raw SQL is assembled from client input, preventing SQL injection.
2. Identifier sanitization
Column and table names are validated against /^[A-Za-z_][A-Za-z0-9_]*$/ via sanitize_identifier(). Anything else throws Invalid identifier.
3. Table allowlist
Only tables listed in allowed_tables can be accessed. A request for any other table is rejected with Table is not allowed.
4. CORS enforcement
Requests are only processed when the Origin header matches allowed_origins. Unlisted origins receive 403. OPTIONS preflight returns 204.
5. Timing-safe API key
The X-Venjs-Key header is compared with hash_equals(), which runs in constant time to resist timing attacks. A missing/invalid key returns 401.
6. Password handling
register hashes passwords with password_hash(..., PASSWORD_DEFAULT); login verifies with password_verify and never returns the hash field.
Checklist before production
- Set a long, random
api_keyand use it on the client viavenjs.db.connect({ apiKey }). - Restrict
allowed_originsto your real domains. - List only the tables the frontend truly needs in
allowed_tables. - Set
debug => falseso exceptions don’t leak to clients. - Enforce HTTPS; consider rotating the
notification_handler.txtto a real datastore. - Harden
ven_notify.phpCORS (*by default) and add the same key handshake.
Example hardened config
$CONFIG = [
'db_host' => '127.0.0.1',
'db_port' => 3306,
'db_name' => 'prod_app',
'db_user' => 'app_rw',
'db_pass' => getenv('DB_PASS'),
'api_key' => getenv('VENJS_KEY'),
'allowed_origins' => ['https://app.example.com'],
'allowed_tables' => ['users','courses','enrollments'],
'debug' => false,
];