18 novembre 2025 / 02:38 PM

Guida al Security Testing per sviluppatori: da SAST a Pentest

Dive into Data, Analytics, and AI with articles, guides, and real cases that help you turn data into business value.

Integrare la sicurezza in ogni livello delle tue applicazioni cloud, web e di BI.

Benvenuti su Tech Station, l'hub di SDG Group dedicato alle ultime innovazioni in data e analytics!

Oggi, in un ambiente cloud-first, non può più essere un pensiero secondario, ma invece un elemento cruciale per rendere un software affidabile, scalabile e sicuro. Che si tratti di pipeline ETL per la reportistica o di un frontend basato su React, le vulnerabilità possono insidiarsi a ogni livello, dal codice non sicuro alle risorse cloud mal configurate.

Questo articolo offre un'introduzione molto pratica ai principali tipi di test di sicurezza. Si rivolge a sviluppatori .NET e architetti che lavorano nell'ambito della business intelligence basata su cloud e delle applicazioni web, includendo una sezione specifica con esempi di best practice per ogni tipo di problema di sicurezza.

Cercavi qualcos'altro? Guarda tutti gli altri contenuti qui.

techstation generica

Comprendere le minacce e le vulnerabilità comuni

I sistemi digitali, come applicazioni web, servizi di cloud computing e piattaforme di business intelligence, hanno interfacce che interagiscono direttamente con i clienti finali, applicazioni di terze parti e altri servizi.

Queste interfacce rendono tali applicazioni bersagli per hacker che cercano di violare e sfruttare le vulnerabilità.

 

1_cuKZ-cN-bGaGwmw0DJJTbA-1

 

In questa sezione, esploreremo alcune delle minacce più comuni in questi ambienti e i modi migliori per difendersi durante lo sviluppo.

 

Pericoli tipici

Le soluzioni moderne affrontano un'ampia gamma di minacce alla sicurezza.

Tra queste c'è l'SQL Injection (SQLi), uno degli attacchi più noti, che comporta l'uso di campi di input per ottenere l'accesso e modificare i dati all'interno di un database.

Un altro tipo molto diffuso è il Cross-Site Scripting (XSS), in cui script dannosi vengono incorporati in qualsiasi tipo di contenuto visualizzato da altri utenti. Questo script può rubare una sessione, reindirizzare un client o utilizzare le API disponibili.

A volte questo è collegato a un altro tipo chiamato Cross-Site Request Forgery (CSRF), che si affida a utenti già autenticati per eseguire azioni involontariamente.

Ecosistemi più complessi potrebbero portare a vulnerabilità come Insecure Direct Object References (IDOR), che sorgono a causa di controlli di accesso non sicuri sulle applicazioni, come quando identificatori grezzi vengono passati direttamente all'interno di query URL e API.

Infine, ci sono header di sicurezza mal configurati e policy CORS permissive.

 

 

Esempio di SQL Injection

Vediamo due casi: il secondo, ovvero l'esempio "Corretto", protegge dagli attacchi di SQL injection perché viene utilizzata una query parametrizzata ($1) per isolare i comandi SQL dall'input dell'utente, cosa che non viene fatta nell'esempio"Errato".


Errato:


app.get('/user', async (req, res) => {
const username = req.query.username;
const query = `SELECT * FROM users WHERE username = '${username}'`;
const result = await db.query(query);
res.json(result);
});pyt


Corretto:


app.get('/user', async (req, res) => {
const username = req.query.username;
const query = `SELECT * FROM users WHERE username = $1';
const result = await db.query(query, [username]);
res.json(result);
});

 

Il primo esempio dimostra come una query SQL venga interpolata direttamente con i valori di input. Di per sé, questo è uno dei modi non sicuri che porta facilmente a un problema di SQL injection, poiché un attaccante può tentare di eseguire query per accedere a informazioni non autorizzate.

Il secondo caso viene risolto tramite query parametrizzate, che isolano la logica della query dai valori di input. Ciò garantisce automaticamente che i valori di input vengano trattati esclusivamente come tali e non come query, rendendo questa interrogazione sicura by design.



Esempio di Cross-Site Scripting (XSS)

Errato:


function UserMessage({ message }) {
  return <div dangerouslySetInnerHTML= />;
}


Corretto:


function UserMessage({ message }) {
  return <div>{message}</div>;
}

 

In questo esempio, il contenuto creato dall'utente viene iniettato direttamente negli elementi utilizzando dangerouslySetInnerHTML, il che bypassa completamente qualsiasi protezione fornita da React. Ciò può rendere qualsiasi app che utilizza questo metodo per visualizzare informazioni molto suscettibile agli attacchi XSS.

Il secondo esempio sfrutta il comportamento predefinito fornito da React, che esegue automaticamente l'escape sia dei tag HTML che dei caratteri speciali. Ciò garantisce che qualsiasi input fornito da un utente venga trattato come testo semplice, che non è eseguibile, prevenendo così qualsiasi attacco XSS.



Esempio di Cross-Site Request Forgery (CSRF)

Questa volta il codice "Corretto" difende dagli attacchi Cross-Site Request Forgery (CSRF) controllando un token segreto univoco per verificare che la richiesta non sia stata falsificata, mentre il codice "Errato" controlla semplicemente la richiesta rispetto a quanto memorizzato nella sessione dell'utente.


Errato (senza protezione):


app.post('/update-email', (req, res) => {
  const newEmail = req.body.email;
  const userId = req.session.userId;

  // Update email without CSRF check
  db.query('UPDATE users SET email = ? WHERE id = ?', [newEmail, userId], (err) => {
    if (err) return res.status(500).send('Error');
    res.send('Email updated');
  });
});


Corretto (con middleware csurf):


// Using csurf middleware in Express
const csrf = require('csurf');
app.use(csrf());

app.get('/update-email-form', (req, res) => {
  res.render('update-email', { csrfToken: req.csrfToken() });
});

app.post('/update-email', (req, res) => {
  const newEmail = req.body.email;
  const userId = req.session.userId;

  db.query('UPDATE users SET email = ? WHERE id = ?', [newEmail, userId], (err) => {
    if (err) return res.status(500).send('Error');
    res.send('Email updated');
  });
});
 


Il CSRF si basa sulla fiducia tra un'app web e il browser del suo utente.

Senza una protezione specifica contro questo, come token CSRF e cookie same-site, possono verificarsi attività dannose a causa di utenti autenticati che vengono ingannati nel compiere azioni indesiderate.

Includere token CSRF nelle richieste che alterano lo stato garantisce che solo le richieste sul tuo dominio possano intraprendere azioni vitali.



Esempio di Policy CORS permissiva

Il codice "Corretto" limita correttamente l'accesso alle API a un sito web specifico (your-frontend.com), rispetto all'esempio "Errato" che utilizza un carattere jolly (*) per consentire a qualsiasi sito web su Internet di effettuare richieste per rubare le tue informazioni.


Errato:


app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  next();
});


Corretto:


const cors = require('cors');

app.use(cors({
  origin: ['https://your-frontend.com'],
  methods: ['GET', 'POST'],
  credentials: true
}));



Configurazioni CORS errate, in particolare quelle che consentono l'accesso a qualsiasi origine tramite "*", possono inavvertitamente rendere la tua API disponibile per abusi da parte di fonti terze.

È imperativo garantire che solo i domini autorizzati possano accedere alle tue risorse, assicurandosi al contempo di inviare le credenziali solo quando assolutamente necessario.

 

 

Come difendersi: best practice di codifica sicura

La protezione contro gli attacchi di sicurezza più comuni può essere ottenuta anche senza un team di sviluppo dedicato alla sicurezza, ma seguendo alcune best practice, come ad esempio:

  • Fin dall'inizio: valida e sanifica sempre qualsiasi input, non importa quanto sembri innocuo. Impiega la validazione lato server e le definizioni di schema per garantire input puliti ed evita di costruire query SQL utilizzando la concatenazione.

  • La gestione dell'autenticazione e delle sessioni può sfruttare standard solidi come OAuth2, OpenID Connect e/o JWT. È anche fondamentale mantenere token di breve durata e progettare meccanismi di gestione del logout per evitare problemi di sessione.

  • Il principio del privilegio minimo dovrebbe essere sempre applicato: i permessi sul backend dovrebbero essere limitati a ciò che è assolutamente richiesto e, ove possibile, dovrebbero essere implementati ruoli granulari all'interno del proprio ambiente cloud.

  • Non rendere mai disponibili le route di amministrazione agli utenti regolari.

  • Non hard-codare mai segreti e/o chiavi API, in particolare sul frontend.

  • Infine, sfrutta l'automazione. Con utility di analisi statica, linter e scanner di sicurezza integrati nella tua pipeline CI/CD, puoi identificare le vulnerabilità in anticipo. Queste utility possono segnalare pattern non sicuri prima ancora che arrivino in produzione.

 

 

Guida alle principali categorie di Security Testing

Sebbene le best practice possano mantenerti al sicuro, è il security testing a rivelare ciò che non sapevi di aver trascurato.

Questo perché, indipendentemente dal fatto che tu stia implementando soluzioni di business intelligence, applicazioni web o tecnologie cloud-native, l'integrazione di test di sicurezza è fondamentale per identificare ciò che un hacker potrebbe sfruttare rispetto a ciò che sai di aver perso.

Di seguito vediamo un elenco che descrive alcuni dei tipi di test di sicurezza più critici e come si relazionano al tuo ciclo di sviluppo e distribuzione:

    • SAST — Static Application Security Testing: il vantaggio principale di SAST è che fornisce test di sicurezza white-box, il che implica che viene eseguito su un'app esaminando i suoi codici sorgente, bytecode e/o binari senza eseguirli. Pertanto, un obiettivo chiave è identificare vulnerabilità di sicurezza come attacchi SQL injection, buffer overflow e/o gestione insicura delle informazioni.

      • Quando usarlo: Ideale durante i processi di sviluppo e/o revisione del codice. Lo strumento può essere facilmente integrato dai team DevOps nella loro pipeline CI/CD per scansionare i codici e identificare i difetti in tempo reale. Possono sorgere falsi positivi durante l'impiego di SAST.

      • Tool comuni: Snyk, SonarQube, Fortify Static Code Analyzer, Semgrep, Checkmarx, CodeQL (GitHub Advanced Security).

    • SCA — Software Composition Analysis: l'obiettivo principale di SCA è scansionare le applicazioni per scoprire componenti open source e librerie di terze parti utilizzate nella tua app. Lo strumento analizza se queste librerie presentano vulnerabilità note, versioni obsolete e conflitti di licenza confrontandole con database di vulnerabilità disponibili pubblicamente come NVD (National Vulnerability Database).

      • Quando usarlo: Particolarmente rilevante nei moderni sforzi di sviluppo software che dipendono in modo piuttosto esteso dal software open source. Lo scopo principale di SCA è assicurarsi che le dipendenze siano sicure e conformi.

      • Tool comuni: Snyk, GitHub Dependabot, OWASP Dependency-Check, Black Duck, WhiteSource (Mend), Google Cloud Assured OSS.

    • IAST — Interactive Application Security Testing: gli strumenti IAST continuano a tracciare le applicazioni in un ambiente live mentre vengono sottoposte a test (come test funzionali/test di integrazione). IAST è più preciso di altre soluzioni perché utilizza i punti di forza sia di SAST che di DAST per analizzare le applicazioni in esecuzione.

      • Quando usarlo: Dimostrato di funzionare bene all'interno di ambienti QA dove c'è un testing interattivo dell'app. IAST consente agli sviluppatori di ottenere maggiori informazioni sui problemi di sicurezza, inclusi meno falsi positivi rispetto ad altri tipi di test di sicurezza.

      • Tool comuni: Contrast Security, Seeker by Synopsys, HCL AppScan IAST.

    • DAST — Dynamic Application Security Testing: DAST è un tipo di test black box perché analizza l'ambiente di esecuzione dell'applicazione valutata. Questo metodo simula attacchi alle applicazioni utilizzando la loro interfaccia front-end o le API, controllando così vulnerabilità come XSS, SQLi e scarsa gestione degli errori senza dover accedere al codice sorgente.

      • Quando usarlo: Ideale da usare all'interno di ambienti di staging/pre-produzione per costruire simulazioni di attacchi e scoprire vulnerabilità di runtime. DAST è particolarmente utile quando si valutano applicazioni di terze parti o applicazioni legacy dove l'accesso al codice sorgente non è disponibile.

      • Tool comuni: OWASP ZAP, Burp Suite, Netsparker, Acunetix, Qualys Web Application Scanning.

    • Pentest — Penetration Testing: il penetration testing viene eseguito da hacker etici per effettuare attacchi reali a un sistema e scoprire possibili vulnerabilità contro cui possono essere lanciati attacchi. Il livello a cui il penetration testing può consentire l'accesso a un sistema è white box, black box e gray box.

      • Quando usarlo: Solitamente eseguito prima di grandi rilasci, audit di conformità o importanti modifiche all'architettura. Questo può offrire una revisione completa del feedback ed è spesso la convalida finale prima dei deployment live.

      • Tool comuni: Metasploit, Burp Suite Pro, Kali Linux, Nmap, Wireshark.

 

0_M9c47_RmHy7OR2VV

 

 

Conclusioni: costruire una cultura della sicurezza

Il ruolo della sicurezza non è qualcosa che si compie una volta sola, ma piuttosto una mentalità che deve essere instillata in ogni fase, inclusa la pianificazione e lo sviluppo del prodotto.

Che si tratti di uno strumento di business intelligence guidato dai dati o di un'app web basata su cloud, la codifica sicura e gli approcci strategici ai test potrebbero fare la differenza tra un'app sicura e una pericolosa.

Abbiamo discusso alcuni importanti tipi di test di sicurezza, tra cui Analisi Statica e Dinamica, Penetration Testing e SCA, ognuno con i propri punti di forza e usi all'interno dell'SDLC.

Individualmente e combinati, costituiscono un meccanismo di sicurezza completo in grado di proteggere dalle minacce contemporanee.

Tuttavia, ciò richiede più dei semplici strumenti. Sono necessarie consapevolezza nella comunità di sviluppo, lavoro di squadra e una mentalità di miglioramento continuo della sicurezza.

Essere proattivi e incorporare la sicurezza in anticipo può portare alla costruzione di sistemi che sono sia potenti che resilienti.


Pronto a costruire applicazioni più resilienti e sicure, integrando la sicurezza nel tuo ciclo di sviluppo?  Contattaci per una consulenza personalizzata e scopri come la nostra competenza nello sviluppo software sicuro può aiutarti a implementare strategie di testing robuste e a costruire una cultura della sicurezza all'interno del tuo team.