Darkwood · Security Engineering · Darkwaar40

Darkwood technical session · @matyo91Act I · The game
Move, contain the portals, and let Auto-Scan clear nearby threats before they reach the Core.

The thesis
Security is continuous operational work—not a perimeter completed once.
The security model
Not equivalence: a game condenses uncertainty, people, data loss, and recovery into legible decisions.
Act II · Defensive security
Validation, least privilege, patching, and network restrictions constrain what can happen.
Logs, metrics, traces, anomaly signals, and alerts reveal what may already be happening.
Exposure
Attack-surface management
Before · unknown + broad
/admin/debug/v1/v2old-workerCI tokenroot DBunused packageAfter · known + necessary
/v2scoped workerleast-privilege DBrotated secretFewer entry points. Smaller blast radius. Clear ownership.
Patching under pressure

Game upgrade ≠ software patch. Real remediation changes code or configuration, then requires testing, deployment, rollback, and verification.
21 October 2026 · PHP security release
Discovery → triage → coordination → fix → packaging → communication → deployment
Fixed versions cited by CERT-FR
Sources: CERTFR-2026-ALE-014 · The PHP Foundation
The exposure window closes only when the fix is deployed and verified.
Vulnerability prioritization
A conceptual model—not a universal numerical formula. Add existing exploitation, controls, remediation cost, and cost of delay.
Defense in depth
Layering reduces the chance that one defect becomes total compromise.
Act III · PHP + Symfony
Dependency signal
composer validate --strict
composer audit --locked
composer outdated --direct
Track the PHP support calendar and ship security patch releases.
Know Symfony support dates before the branch becomes an emergency.
Run Composer audit in CI and on a schedule—not from memory.
Sources: php.net/supported-versions.php · symfony.com/releases · getcomposer.org/doc/03-cli.md#audit
Symfony security baseline
security.yaml
security:
password_hashers:
App\Entity\User: 'auto'
firewalls:
main:
lazy: true
login_throttling:
max_attempts: 5
interval: '1 minute'
framework.yaml
framework:
csrf_protection: true
session:
cookie_secure: true
cookie_httponly: true
cookie_samesite: lax
Application throttling raises brute-force cost. DDoS protection belongs at a cheaper edge.
Identity is not permission
Who is presenting this request?
May this identity act on this object?
#[IsGranted('PROJECT_DELETE', 'project')] checks the action against the actual project—not only the login state.
Safe input and data handling
Doctrine · bind values
$projects = $repository->createQueryBuilder('p')
->andWhere('p.owner = :owner')
->setParameter('owner', $user)
->getQuery()
->getResult();
Dynamic identifiers still require an allowlist.
Keep contextual auto-escaping. Audit every |raw.
Use a deployment manager or Symfony vault; keep keys separate.
Exclude passwords, session IDs, access tokens, and private keys.
Production mode, least privilege, narrow web root, tested headers.
Act IV · Darkwood Identity
Standards do not remove security work. They make the required work explicit and reviewable.
OIDC Authorization Code + PKCE S256
Trust, tokens and sessions
OIDC authenticates identity claims. Navi still decides who may administer Navi.
Actual repository state · inspected 24 Oct 2026
oidc_loginPlanned in repository design documentation; Symfony 8.2 was still under development.
Repository code confirms implementation—not deployed production rollout or a completed live login.
Act V · Limits
Data can be copied while the Core still reads 100.
It is defined by defenders lacking an available fix—not by hit points.
It needs tested backups, rebuilt credentials, restoration, and forensic confidence.
They adapt to controls, defenders, incentives, and opportunity.
The durable lesson
The system changes. The threat changes. The loop must keep moving.
Play Darkwaar40 — Breach

Darkwood · @matyo91