La review post-incidente, il threat model e i gate correnti sono in SECURITY_REVIEW.md.
Asset principali:
- continuità delle stampe e delle risposte di dispositivo;
- RAW e timeline originali;
- chiavi HMAC, password DB, segreto JWT e credenziali utenti;
- documenti normalizzati, correlazioni, alert e audit;
- disponibilità di spool, database e interfaccia investigativa.
Input non fidati:
- qualunque byte ricevuto da gestionale o stampante;
- file e metadata degli archivi legacy;
- query/body/header HTTP;
- configurazione di sito prima della validazione;
- nomi/percorso presenti nei manifest.
Avversari considerati includono un client di rete non autorizzato, payload malformati, archivio manomesso, account web con privilegi insufficienti e operatore host non privilegiato. Un amministratore root completamente ostile può sostituire codice, dati e chiavi: le catene hash non risolvono tale scenario senza un anchor esterno.
- relay senza parser/database nel percorso TCP;
- ACL per IP/rete e un solo client per target;
- timeout, backpressure e limiti di connessioni/chunk/coda;
- nessuna esecuzione o interpretazione del payload nel relay;
- separazione utenti systemd POS/RCH dal control plane;
RPG_DATABASE_URLeRPG_JWT_SECRET_FILErimossi dall'ambiente proxy;- unità hardenizzate con filesystem protetto, namespace/privilegi ridotti e sole famiglie socket necessarie.
La capability CAP_NET_BIND_SERVICE è necessaria alla route RCH se usa una
porta inferiore a 1024; non abilita configurazione degli indirizzi. L'installer
non modifica IP, route, DNS o firewall.
- file regolari e
O_NOFOLLOWdove disponibile; - pubblicazione atomica e
fsync; - SHA-256 per payload/file/manifest;
- catene per timeline e record sensibili;
- HMAC per ledger printproxy quando disponibile;
- reader con containment, limiti e controllo pre/post;
- raw e interpretazione separati, con versioning del parser.
Il formatter JSON applicativo ammette solo campi extra espliciti, limita profondità/lunghezza, rappresenta i byte come lunghezza+SHA-256 e redige pattern comuni di credenziali. La coda di log del relay è bounded e non bloccante: una perdita di record di log non deve diventare una perdita di disponibilità del data plane.
I due data plane usano account distinti
retailprintguard-pos-proxy/retailprintguard-rch-proxy, con accesso allo
spool tramite gruppo condiviso. Ingestion usa retailprintguard-worker: lo
spool canonico è dichiarato ReadOnlyPaths, mentre scritture sono ammesse solo
su archive, state e log worker. Nessuno dei proxy appartiene al gruppo DB.
I processi control plane condividono al momento l'account MariaDB DML
retailprintguard_app; l'account di migrazione è effimero e i proxy non hanno
credenziali DB. Separare in futuro API/worker e backup per tabelle/operazioni
ridurrebbe ulteriormente il blast radius.
Questi controlli sono tamper-evident. Per rendere utile la rilevazione occorre spedire periodicamente head, audit e backup verso storage separato, immutabile o con retention amministrativa indipendente.
- Argon2 per password;
- JWT HS256 con issuer, audience e scadenza;
- RBAC server-side;
- blocco temporaneo dell'account web dopo cinque fallimenti per cinque minuti e throttle locale al processo;
- verifica Argon2 fittizia per ridurre differenze temporali quando l'utente non esiste;
- query SQLAlchemy parametrizzate;
- audit hash-chained su azioni API sensibili, bootstrap e attivazione parser; quest'ultima proviene da una CLI di sistema e registra actor nullo;
- bootstrap locale del solo primo amministratore, password via doppio prompt, policy 14–1.024 caratteri/tre classi e audit hash-chained;
- correlation ID e messaggi di errore bounded;
- security header e CORS allowlist.
Il token in-memory del frontend non persiste al refresh. TLS/HSTS, limite richieste e rate limit condiviso sono responsabilità del reverse proxy autorizzato.
L'API non autentica tramite cookie: richiede un bearer token esplicito, quindi
la protezione CSRF basata su token/cookie non è applicabile al flusso corrente.
Se in futuro si introducono cookie di sessione, serviranno SameSite, flag
Secure/HttpOnly e un controllo CSRF dedicato prima del rilascio.
retailprintguard-admin non accetta password come parametro o environment e si
rifiuta quando esiste già un utente. Va eseguito localmente con accesso al file
DB protetto; il nome utente viene normalizzato case-insensitive e un advisory
lock MariaDB impedisce a due host di completare contemporaneamente il primo
bootstrap. Il workflow successivo di gestione utenti non deve riutilizzare il
bootstrap.
I segreti non devono apparire in Git, log, CLI, ticket o screenshot.
Percorsi di installazione:
/etc/retailprintguard/database.password: root0600;/etc/retailprintguard/database.env: root/gruppo DB0640;/etc/retailprintguard/jwt.secret: root/gruppo API0640;/etc/retailprintguard/review.env: root/gruppo API0640, contenente solo l'hash Argon2id della password di conferma per gli incompleti;- chiave HMAC printproxy: file regolare non symlink, almeno 32 byte.
La stringa DB nell'env contiene la password. Non eseguire systemctl show --property=Environment in output condivisi e non usare set -x negli script.
La rotazione richiede aggiornamento atomico del file e riavvio dei soli servizi
control plane.
La password di revisione non deve essere scritta in YAML o come argomento della
shell. retailprintguard-configure-review la acquisisce con doppio prompt,
scrive atomicamente il solo hash e rifiuta path alternativi/symlink. L'API
fallisce chiuso se il file non è presente o il valore non è un hash Argon2id.
Nome ambiente e percorso sono fissi nel processo API; non sono opzioni del file
di configurazione e non vengono esposti ai proxy.
La conferma non sostituisce il ruolo ADMIN: entrambe le verifiche sono
obbligatorie e i tentativi errati sono sottoposti a throttle.
- MariaDB è configurata su
127.0.0.1; - API su
127.0.0.1:8080; - nginx espone intenzionalmente la UI su
0.0.0.0:8081; - il firewall deve limitare TCP/8081 alla sola rete amministrativa autorizzata;
- ACL applicativa e firewall devono limitare i gestionali autorizzati;
- la pubblicazione definitiva richiede reverse proxy HTTPS approvato; il bind pubblico IPv4 da solo non fornisce cifratura o controllo perimetrale.
Non usare gli indirizzi RFC 5737 dell'esempio. Gli IP reali vengono mantenuti solo nella configurazione locale protetta.
Il backup operativo contiene dump DB, evidenze e copie di configurazione/segreti
con permessi 0600, ma il formato .tar.gz non è cifrato. Il file deve
essere trasferito su storage cifrato e accessibile solo agli amministratori.
La copia fuori sito deve avere politica di cancellazione, test restore e log di
accesso.
RAW, testo, tavoli, operatori e pagamenti possono contenere dati personali o commerciali. Prima del go-live definire:
- base giuridica e informativa;
- ruoli autorizzati e separazione dei compiti;
- retention distinta per raw, normalizzato, audit e backup;
- procedura di accesso/esportazione/cancellazione compatibile con obblighi fiscali e investigativi;
- pseudonimizzazione degli operatori quando l'identità completa non serve;
- divieto di payload nei log tecnici.
RETENTION_DAYS=0 significa conservazione indefinita finché non interviene una
procedura approvata; non è un default privacy-neutro.
I log strutturati devono contenere solo identificativi, contatori e messaggi
bounded. Non abilitare hexdump/payload in produzione. diagnose.sh produce un
report bounded e payload-free, ma i log possono comunque rivelare endpoint e
identificativi: revisionarli prima di inviarli fuori organizzazione.
- TLS con certificati e rinnovo gestito;
- firewall host/network e segmentazione VLAN;
- NTP affidabile e monitorato;
- storage cifrato, quota e allarme disco;
- export dei log/head verso un dominio amministrativo separato;
- vulnerability/patch management;
- revisione periodica utenti/ruoli;
- test di restore e incident response;
- validazione Debian 12/systemd 252 e NIC reali.
- Non modificare o cancellare lo spool.
- Annotare UTC, release, device/session/job e correlation ID.
- Creare backup verificato; proteggere hash e supporto separatamente.
- Limitare l'accesso web, senza spegnere il relay se la stampa deve continuare.
- Esportare log e head senza payload non necessario.
- Analizzare copie read-only; documentare ogni comando e custode.
- Ruotare credenziali solo con piano che non distrugga la verificabilità degli HMAC storici.
Un alert applicativo è un indizio tecnico, non una conclusione disciplinare o legale automatica.