Docs / Backend / Security Guardrails
ven.php

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

Do not ship with defaults. Update these before going live:
  • Set a long, random api_key and use it on the client via venjs.db.connect({ apiKey }).
  • Restrict allowed_origins to your real domains.
  • List only the tables the frontend truly needs in allowed_tables.
  • Set debug => false so exceptions don’t leak to clients.
  • Enforce HTTPS; consider rotating the notification_handler.txt to a real datastore.
  • Harden ven_notify.php CORS (* 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,
];