An unauthenticated attacker could guess a real device_id and 429-lock that camera by hammering /api/events before HMAC verification ran, dropping its accident events. Add a cheap pre-auth per-IP limiter (Config::ingestIpRateLimitPerMin, default 300/min) that fires before any device-secret lookup, and move the existing per-device limiter to run only after HMAC + timestamp + nonce checks succeed, so only authenticated requests consume a device's own quota.
19 lines
984 B
PHP
19 lines
984 B
PHP
<?php
|
|
declare(strict_types=1);
|
|
namespace App;
|
|
|
|
final class Config
|
|
{
|
|
private function __construct(private array $a) {}
|
|
|
|
public static function fromArray(array $a): self { return new self($a); }
|
|
|
|
public function dbDsn(): string { return (string)($this->a['db_dsn'] ?? ''); }
|
|
public function dbUser(): string { return (string)($this->a['db_user'] ?? ''); }
|
|
public function dbPass(): string { return (string)($this->a['db_pass'] ?? ''); }
|
|
public function snapshotDir(): string { return (string)($this->a['snapshot_dir'] ?? __DIR__ . '/../storage/snapshots'); }
|
|
public function nonceTtl(): int { return (int)($this->a['nonce_ttl'] ?? 86400); }
|
|
public function timestampWindow(): int { return (int)($this->a['timestamp_window'] ?? 300); }
|
|
public function rateLimitPerMin(): int { return (int)($this->a['rate_limit_per_min'] ?? 60); }
|
|
public function ingestIpRateLimitPerMin(): int { return (int)($this->a['ingest_ip_rate_limit_per_min'] ?? 300); }
|
|
}
|