Files
Thanakorn ae98dcdcdd Harden web root, secrets and realtime auth
- .htaccess: refuse .git, .env, docker, nodejs, sdlc*, scripts, archives and
  app internals; security headers, HSTS over TLS, optional HTTPS redirect
- uploads served through app/file.php to signed-in users only
- Apache/PHP hardening config for the container (ServerTokens, expose_php)
- least-privilege DB account and APP_SECRET_KEY via docker/php/provision.php;
  SMTP passwords re-encrypted with a random IV (secret_box.php)
- Socket.IO rooms from a PHP-signed token; /emit and cron refuse empty secrets
- escape notification text; CLI guards on build scripts; no fixed demo password
2026-09-24 14:53:40 +07:00

23 lines
880 B
PHP

<?php
/**
* cron_auth.php — Secret-based auth for cron endpoints called by Node.js scheduler.
* No session required. Validates x-cron-secret header against NODE_EMIT_SECRET.
* Sets up $pdo1, $pdo2, and $answer identical to db_auth.php.
*/
ini_set('display_errors', 0);
ini_set('log_errors', 1);
header('Content-Type: application/json; charset=utf-8');
require_once __DIR__ . '/../../config.php';
require_once __DIR__ . '/../../dbconn.php';
// An empty configured secret must never match an empty header.
$secret = (string)($_SERVER['HTTP_X_CRON_SECRET'] ?? '');
if (!defined('NODE_EMIT_SECRET') || NODE_EMIT_SECRET === '' || !hash_equals((string)NODE_EMIT_SECRET, $secret)) {
http_response_code(403);
exit(json_encode(['success' => 0, 'message' => 'Forbidden']));
}
$data = json_decode(file_get_contents('php://input'), true) ?? [];
$answer = ['success' => 0];