DEV Community

Cover image for Guida completa OWASP Top 10
Cub4nH1
Cub4nH1

Posted on

Guida completa OWASP Top 10

Meta description: Scopri la guida completa OWASP Top 10, le dieci vulnerabilità web più critiche. Impara a riconoscerle e proteggere le tue applicazioni con strategie e codice di esempio.


La sicurezza delle applicazioni web è una preoccupazione crescente nel panorama digitale attuale. Ogni giorno, nuove vulnerabilità vengono scoperte e sfruttate da attaccanti sempre più sofisticati. In questo contesto, l'OWASP Top 10 rappresenta un punto di riferimento fondamentale per sviluppatori, security engineer e professionisti IT che desiderano costruire applicazioni più sicure.

L'Open Web Application Security Project (OWASP) è un'organizzazione no-profit dedicata al miglioramento della sicurezza del software. La sua lista delle dieci vulnerabilità più critiche è aggiornata periodicamente per riflettere l'evoluzione delle minacce e delle tecniche di attacco.

In questa guida completa, esploreremo ogni vulnerabilità in dettaglio, con esempi pratici, codice vulnerabile e le relative contromisure.

Cos'è l'OWASP Top 10 e perché è importante

L'OWASP Top 10 è un documento di consenso che identifica i rischi di sicuretti più critici per le applicazioni web. Non è semplicemente una lista di vulnerabilità, ma una risorsa educativa che aiuta le organizzazioni a comprendere, prevenire e mitigare i rischi più comuni.

La versione più recente (2021) ha introdotto significative modifiche rispetto alle precedenti, con nuove categorie e una ristrutturazione delle priorità. Comprendere queste vulnerabilità è essenziale per chiunque sviluppi, gestisca o testi applicazioni web.

A01:2027 – Broken Access Control

Il Broken Access Control è la vulnerabilità più critica nella lista OWASP. Si verifica quando un utente può agire al di fuori dei permessi previsti, accedendo a funzionalità o dati che non dovrebbero essere disponibili.

Esempio di codice vulnerabile

# VULNERABILE: Nessuna verifica dei permessi
@app.route('/api/users/<int:user_id>/profile')
def get_user_profile(user_id):
    user = User.query.get(user_id)
    return jsonify(user.to_dict())
Enter fullscreen mode Exit fullscreen mode

Contromisure

# SICURO: Verifica dei permessi implementata
@app.route('/api/users/<int:user_id>/profile')
@login_required
def get_user_profile(user_id):
    if current_user.id != user_id and not current_user.is_admin:
        abort(403)
    user = User.query.get(user_id)
    return jsonify(user.to_dict())
Enter fullscreen mode Exit fullscreen mode

Best practice:

  • Implementa il principio del privilegio minimo
  • Disabilita la directory listing sul server
  • Registra e monitora i tentativi di accesso non autorizzati
  • Invalida i token di sessione al logout

A02:2021 – Cryptographic Failures

Le fallacie crittografiche riguardano la protezione dei dati in transito e a riposo. Questa categoria include l'uso di algoritmi deboli, gestione impropria delle chiavi e trasmissione di dati sensibili in chiaro.

Esempio di codice vulnerabile

// VULNERABILE: Dati sensibili in chiaro
const userData = {
    email: req.body.email,
    password: req.body.password, // Password in chiaro!
    creditCard: req.body.creditCard
};
Enter fullscreen mode Exit fullscreen mode

Contromisure

// SICURO: Crittografia e hashing appropriati
const bcrypt = require('bcrypt');
const crypto = require('crypto');

async function createUser(userData) {
    const hashedPassword = await bcrypt.hash(userData.password, 12);
    const encryptedCard = encrypt(userData.creditCard, process.env.ENCRYPTION_KEY);

    return {
        email: userData.email,
        password: hashedPassword,
        creditCard: encryptedCard
    };
}

function encrypt(text, key) {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv('aes-256-gcm', Buffer.from(key, 'hex'), iv);
    let encrypted = cipher.update(text, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    return iv.toString('hex') + ':' + encrypted;
}
Enter fullscreen mode Exit fullscreen mode

Best practice:

  • Utilizza algoritmi standard e aggiornati (AES-256, RSA-2048+)
  • Non memorizzare mai password in chiaro
  • Implementa HTTPS ovunque
  • Ruota regolarmente le chiavi crittografiche

A03:2021 – Injection

Le injection sono tra le vulnerabilità più antiche e più sfruttate. SQL Injection, Command Injection e LDAP Injection permettono agli attaccanti di inviare dati malevoli che vengono interpretati come comandi dal sistema.

Esempio di codice vulnerabile

# VULNERABILE: SQL Injection
@app.route('/api/users/search')
def search_users():
    name = request.args.get('name')
    query = f"SELECT * FROM users WHERE name = '{name}'"
    result = db.execute(query)
    return jsonify(result.fetchall())
Enter fullscreen mode Exit fullscreen mode

Contromisure

# SICURO: Query parametrizzate
@app.route('/api/users/search')
def search_users():
    name = request.args.get('name')
    query = "SELECT * FROM users WHERE name = %s"
    result = db.execute(query, (name,))
    return jsonify(result.fetchall())
Enter fullscreen mode Exit fullscreen mode

Best practice:

  • Usa sempre query parametrizzate o ORM
  • Valida e sanifica tutti gli input
  • Applica il principio del privilegio minimo al database
  • Utilizza WAF come ulteriore livello di protezione

A04:2021 – Insecure Design

L'Insecure Design si concentra su difetti di progettazione piuttosto che su implementazioni difettose. Include pattern architetturali insicuri, mancanza di threat modeling e assenza di controlli di sicurezza nel design del sistema.

Strategie di prevenzione

  • Esegui threat modeling durante la fase di progettazione
  • Implementa pattern di sicurezza come Defense in Depth
  • Definisci requisiti di sicurezza chiari
  • Utilizza librerie e framework di sicurezza collaudati

A05:2021 – Security Misfconfiguration

Le configurazioni errate sono tra le vulnerabilità più comuni. Account default con password note, funzionalità non necessarie abilitate e messaggi di errore troppo dettagliati sono solo alcuni esempi.

Checklist di configurazione

# Configurazione sicura per nginx
server {
    # Disabilita la visualizzazione della versione
    server_tokens off;

    # Headers di sicurezza
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Disabilita l'accesso alle directory
    autoindex off;

    # Limita i metodi HTTP
    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
        return 405;
    }
}
Enter fullscreen mode Exit fullscreen mode

A06:2021 – Vulnerable and Outdated Components

L'uso di componenti con vulnerabilità note è un rischio significativo. Librerie, framework e moduli di terze parti devono essere costantemente monitorati e aggiornati.

Strumenti di gestione delle dipendenze

# Verifica vulnerabilità nelle dipendenze
npm audit
pip safety check
mvn dependency-check:check

# Aggiornamento automatico
npm audit fix
pip-compile --upgrade
Enter fullscreen mode Exit fullscreen mode

A07:2021 – Identification and Authentication Failures

Le falle nell'autenticazione permettono attacchi come credential stuffing, brute force e session hijacking. L'implementazione corretta di meccanismi di autenticazione è cruciale.

Esempio di implementazione sicura

# SICURO: Autenticazione con rate limiting e lockout
from flask_limiter import Limiter
from datetime import datetime, timedelta

login_attempts = {}

def check_brute_force(ip_address):
    if ip_address in login_attempts:
        attempts = login_attempts[ip_address]
        if attempts['count'] >= 5:
            if datetime.now() - attempts['last_attempt'] < timedelta(minutes=15):
                return True
            else:
                login_attempts[ip_address] = {'count': 0, 'last_attempt': datetime.now()}
    return False

@app.route('/api/login', methods=['POST'])
@limiter.limit("5 per minute")
def login():
    if check_brute_force(request.remote_addr):
        return jsonify({'error': 'Troppi tentativi. Riprova tra 15 minuti.'}), 429
    # ... logica di autenticazione
Enter fullscreen mode Exit fullscreen mode

A08:2021 – Software and Data Integrity Failures

Questa categoria riguarda la verifica dell'integrità del software e dei dati. Include aggiornamenti non verificati, pipeline CI/CD insicure e serializzazione non sicura.

A09:2021 – Security Logging and Monitoring Failures

Senza un logging e un monitoraggio adeguati, le violazioni di sicurezza possono rimanere non rilevate per mesi. L'implementazione di sistemi di logging robusti è essenziale per il threat detection.

Esempio di logging strutturato

import logging
import json
from datetime import datetime

class SecurityLogger:
    def __init__(self):
        self.logger = logging.getLogger('security')
        handler = logging.FileHandler('security.log')
        handler.setFormatter(logging.Formatter('%(message)s'))
        self.logger.addHandler(handler)
        self.logger.setLevel(logging.INFO)

    def log_event(self, event_type, user_id, details, severity='INFO'):
        log_entry = {
            'timestamp': datetime.utcnow().isoformat(),
            'event_type': event_type,
            'user_id': user_id,
            'details': details,
            'severity': severity,
            'source_ip': request.remote_addr
        }
        self.logger.info(json.dumps(log_entry))

security_logger = SecurityLogger()
Enter fullscreen mode Exit fullscreen mode

A10:2021 – Server-Side Request Forgery (SSRF)

L'SSRF permette agli attaccanti di indurre il server a effettuare richieste verso destinazioni non previste. Questa vulnerabilità è particolarmente pericolosa in architetture cloud e microservizi.

Contromisure

# SICURO: Validazione degli URL
from urllib.parse import urlparse
import ipaddress

ALLOWED_HOSTS = ['api.trusted-service.com', 'cdn.ourdomain.com']

def is_safe_url(url):
    parsed = urlparse(url)

    # Verifica che l'host sia nella whitelist
    if parsed.hostname not in ALLOWED_HOSTS:
        return False

    # Verifica che non sia un IP privato
    try:
        ip = ipaddress.ip_address(parsed.hostname)
        if ip.is_private or ip.is_loopback:
            return False
    except ValueError:
        pass

    return True

@app.route('/api/fetch')
def fetch_data():
    url = request.args.get('url')
    if not is_safe_url(url):
        return jsonify({'error': 'URL non autorizzato'}), 400
    # ... procedi con la richiesta
Enter fullscreen mode Exit fullscreen mode

Conclusione

L'OWASP Top 10 rappresenta una risorsa indispensabile per chiunque lavori nel campo della sicurezza web. Comprendere queste vulnerabilità e implementare le contromisure appropriate è il primo passo verso applicazioni più sicure.

Ricorda che la sicurezza è un processo continuo, non un obiettivo da raggiungere una volta per tutte. Aggiorna regolarmente le tue conoscenze, esegui test di sicurezza periodici e mantieni un approccio proattivo verso la protezione delle tue applicazioni.

Vuoi approfondire la sicurezza web? Iscriviti alla nostra newsletter per ricevere aggiornamenti settimanli sulle ultime vulnerabilità e best practice. Condividi questo articolo con il tuo team e aiutaci a costruere un web più sicuro per tutti!

Top comments (0)