Migliorare la sicurezza in JavaScript

Ogni linguaggio di programmazione presenta un proprio insieme di vulnerabilità di sicurezza, e JavaScript non fa eccezione. Sfruttare le vulnerabilità di JavaScript può portare a manipolazione dei dati, dirottamento di sessioni, accesso non autorizzato ai dati e altro ancora. Sebbene comunemente associati alla funzionalità lato client, i rischi di sicurezza di JavaScript possono anche rappresentare minacce significative negli ambienti lato server.

Per qualsiasi applicazione, la fiducia dei clienti è di fondamentale importanza. Mantenere questa fiducia richiede la protezione dei dati dei clienti e l’assicurazione della sicurezza delle applicazioni. Fortunatamente, implementare le giuste misure di protezione può mitigare questi rischi e migliorare la sicurezza della tua applicazione.

In questo articolo, esploreremo alcune delle minacce di sicurezza JavaScript più comuni e discuteremo strumenti e strategie efficaci per proteggere la tua applicazione da potenziali attacchi.

Scripting Inter-Sito

Cross-site scripting (XSS) è un exploit di sicurezza che consente a un attaccante di iniettare codice dannoso lato client in un sito web. Secondo il Top 10 security delle vulnerabilità del Open Web Application Security Project (OWASP) nel 2021, XSS si classifica come il terzo vettore di attacco più comune.

Come Mitigare XSS

Validazione dell’Input

Assicurati che l’input dell’utente aderisca ai tipi di dati, formati e intervalli attesi. Rimuovi o sfuggi i caratteri potenzialmente dannosi per prevenire iniezioni.

JavaScript

 

function validateInput(input) {
  return input.replace(/[^a-zA-Z0-9]/g, ''); // Allow only alphanumeric characters
}

Codifica dell’Output

Convertire i caratteri speciali nell’output nei loro equivalenti di entità HTML per neutralizzare potenziali script dannosi prima del rendering.

JavaScript

 

function encodeHTML(input) {
  return input.replace(/&/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
    .replace(/'/g, ''');
}

Clickjacking

Clickjacking è un attacco ingannevole che induce gli utenti a fare clic su un elemento con cui non intendono interagire. Questa tecnica coinvolge l’incorporazione di un sito web legittimo all’interno di uno dannoso, spesso utilizzando un HTML <iframe> invisibile o posizionato in modo fuorviante, per dirottare le azioni dell’utente. Di conseguenza, gli aggressori possono rubare le credenziali di accesso, ottenere autorizzazioni non autorizzate o addirittura ingannare gli utenti nell’installare malware senza saperlo. 

Un modo comune per raggiungere questo obiettivo è utilizzare il CSS per aggiungere un pulsante sovrapposto con opacity impostato quasi a 0. Questo induce l’utente a fare clic su un pulsante o un collegamento non intenzionato.

Come Prevenire il Clickjacking

Le X-Frame-Options istruiscono il browser se il sito può essere incorporato all’interno di un iframe. Ha tre opzioni: 

  1. DENY – Impedisce che la pagina venga visualizzata in un iframe completamente
  2. SAMEORIGIN – Consente di incorporare la pagina solo se la richiesta proviene dallo stesso dominio 
  3. ALLOW-FROM – Consente di incorporare la pagina solo da un dominio specifico e attendibile 

In Node.js è possibile utilizzare helmet per impostare queste opzioni come mostrato di seguito:

JavaScript

 

const helmet = require("helmet");
const app = express();
app.use(
  helmet({
    xFrameOptions: { action: "sameorigin" },
  }),
);

Una difesa efficace contro il clickjacking è implementare l’intestazione Content Security Policy (CSP). La CSP fornisce un controllo granulare su come e dove il contenuto può essere incorporato, prevenendo il framing non autorizzato.

Per mitigare i rischi di clickjacking, includi la direttiva frame-ancestors nella tua intestazione CSP. Ad esempio:

HTML

 

Content-Security-Policy: frame-ancestors 'self' https://www.example.org;

Questa policy garantisce che il documento protetto possa essere incorporato solo dalla propria origine ('self') e dai domini esplicitamente consentiti, come example.org. Blocca tutti i tentativi non autorizzati di incorniciare il contenuto, proteggendo gli utenti dagli attacchi di clickjacking.

Nota: Se frame-ancestors e X-Frame-Options sono entrambi impostati, i browser che supportano frame-ancestors ignoreranno X-Frame-Options.

Cross-Site Request Forgery (CSRF)

CSRF (a volte chiamato anche XSRF) sfrutta la fiducia che un sito web ha nel browser di un utente effettuando richieste non autorizzate per conto dell’utente. Gli aggressori ingannano gli utenti facendoli eseguire azioni senza il loro consenso, portando potenzialmente a violazioni dei dati o transazioni indesiderate. Alcuni esempi sono l’aggiornamento dei dettagli personali della vittima, l’inizio di un trasferimento di fondi dal conto bancario della vittima o persino la reindirizzazione di una consegna a un indirizzo diverso.

Esaminiamo un esempio specifico di questo. Stai visitando il sito web della tua banca e hai effettuato l’accesso. Supponiamo che tu riceva un’email per un giveaway che si finge essere la tua banca. Il link ti porta a una pagina web apparentemente innocua. Dietro le quinte, viene attivata e inviata una richiesta POST all’applicazione bancaria legittima.

PowerShell

 

curl --location --request POST 'https://acmebank.com/transfer?routing=852363&fromAccountNumber=123456789&toAccountNo=987654321' \
--header 'Cookie: session=acmebanksessionvalue'

Sul lato dell’applicazione acmebank.com, il tag “script” invia il modulo non appena l’utente carica la pagina, senza alcuna convalida dell’utente o che l’utente si accorga di ciò che sta accadendo, come mostrato di seguito.

HTML

 

<html>
  <body>
    <form action="https://acmebank.com/transfer" method="POST">
      <input type="hidden" routing="852363" fromAccountNo="123456789" toAccountNo="987654321" amount="5000" />
    </form>
    <script>
  	window.addEventListener("DOMContentLoaded", () => {
    document.querySelector("form").submit();
  	});
	</script>
  </body>
</html>

Il modulo sopra crea la seguente richiesta all’applicazione reale, acmebank. La richiesta contiene il cookie di sessione dell’utente legittimo, ma contiene il nostro numero di conto bancario! Poiché la tua sessione con la tua banca è ancora attiva, il trasferimento dell’importo avverrà se non ci sono altre convalide in atto. 

Come Difendersi Contro il CSRF

Imposta l’attributo SameSite su Strict. Questo controlla se un cookie viene inviato con richieste cross-site.

  • Questi cookie di sessione dovrebbero avere una vita breve. Richiedi una nuova autenticazione per azioni sensibili per mitigare i rischi.

Utilizzare token univoci di sessione CSRF. Questo token può quindi essere incluso all’interno di un modulo inviato dal browser. Per ogni richiesta, il server confronta il token inviato dal client con il valore memorizzato per la sessione. Utilizzare la libreria csrf-csrf per configurare token univoci.

Rubare Dati di Sessione

Il dirottamento di sessione avviene quando un attaccante ruba il token di sessione di un utente, permettendo loro di fingersi l’utente e ottenere accesso non autorizzato al loro account.

Come Prevenire il Dirottamento di Sessione

Utilizzare Cookie Sicuri

Impostare i flag Secure e HttpOnly sui cookie di sessione per prevenire l’accesso non autorizzato. Impostando l’attributo Secure si impedisce al cookie di sessione di essere trasmesso in chiaro e consente solo la trasmissione su connessioni HTTPS. Impostando l’attributo HttpOnly si impone albrowser di non permettere l’accesso al cookie dal DOM il che impedisce agli attacchi basati su script lato client di accedere ai dati sensibili memorizzati in quei cookie.

Abilitare l’Autenticazione Multifattore (MFA)

Aggiungi un livello extra di sicurezza per verificare gli utenti. Questo è un metodo molto comune che incontrerai nella maggior parte delle applicazioni sicure. Facili integrazioni sono disponibili tramite fornitori come Okta e Duo.

Implementare la Scadenza della Sessione

Scadere automaticamente le sessioni inattive per ridurre le finestre di attacco.

Pratiche e Strumenti di Codifica per una Sicurezza di Alto Livello

Scansione delle Vulnerabilità

Uno scanner di vulnerabilità mantiene la sicurezza della tua applicazione. Scansionare le tue librerie, la rete, le applicazioni e i dispositivi aiuta a individuare le debolezze che gli attaccanti potrebbero sfruttare. Strumenti come Snyk e Sonarqube possono essere facilmente integrati nei codebase JavaScript. Questi strumenti lavorano in parallelo con elenchi noti di vulnerabilità mantenuti da OWASP. Con un’integrazione senza soluzione di continuità come parte del processo di sviluppo, questi scanner forniscono ai team di sviluppo e di sicurezza una visibilità in tempo reale e accurata sulle vulnerabilità del codice e sulle soluzioni per correggerle.

Test di penetrazione e valutazioni

I programmatori possono adottare pratiche di test di penetrazione per sondare attivamente ed esplorare le potenziali vulnerabilità all’interno di un’applicazione. Gli hacker etici simulano attacchi del mondo reale per valutare la postura della sicurezza delle applicazioni web manipolando il codice JavaScript e le interazioni degli utenti.

Per realizzare ciò, gli sviluppatori possono scrivere codice JS personalizzato per simulare gli scenari, oppure possono utilizzare strumenti specializzati di penetration testing che sfruttano JavaScript per automatizzare il processo di scansione delle vulnerabilità comuni come XSS, utilizzando OWASP ZAP. Maggiori informazioni sul penetration testing sono disponibili nella guida ufficiale di OWASP.

Firewall dell’Applicazione Web (WAF)

Con la crescita delle applicazioni, cresce anche il traffico web, aumentando l’esposizione agli attacchi. Implementare un Firewall dell’Applicazione Web (WAF) aiuta a proteggersi dal traffico malevolo filtrando e monitorando le richieste HTTP. Ciò implica l’integrazione con fornitori di WAF di terze parti come Cloudflare o AWS WAF. Con il WAF, è possibile definire regole come:

  • Paese o posizione geografica da cui provengono le richieste.
  • Indirizzo IP, intervallo CIDR e nomi di dominio da cui provengono le richieste.
  • Limitare lunghezze di richiesta e parametri di query per prevenire attacchi di injection.
  • Codice SQL che potrebbe essere dannoso. Gli attaccanti cercano di estrarre dati dal database inserendo codice SQL dannoso in una richiesta web. Questo è noto come SQL injection.
  • Rilevare e bloccare script incorporati che potrebbero far parte di attacchi XSS.

Un WAF può anche aiutare a mitigare gli attacchi Distributed Denial of Service (DDoS), garantendo la disponibilità dell’applicazione.

Proteggere l’integrità dei dati

Implementare robuste misure di integrità dei dati è essenziale quando si memorizzano o si accede a informazioni sicure. Le migliori pratiche includono:

  • Applicare politiche di password robuste e incoraggiare l’uso di gestori di password. Inoltre, incoraggiare i tuoi utenti ad utilizzare un gestore di password in modo che possano utilizzare password più complesse e non debbano preoccuparsi di ricordarle (Usa LastPass o 1Password).
  • Proteggersi dagli attacchi di forza bruta sulle pagine di accesso con limitazione della velocità, blocco dell’account dopo un certo numero di tentativi non riusciti e sfide CAPTCHA.
  • Utilizzando gli header HTTP come:

Conclusione

La sicurezza di JavaScript è un processo continuo che richiede un approccio proattivo per proteggere le applicazioni dalle minacce in evoluzione. L’implementazione di best practices come la convalida dell’input, gli header CSP, la gestione sicura delle sessioni e la scansione delle vulnerabilità può ridurre significativamente il rischio di attacchi come XSS, CSRF e furto di sessione.

Inoltre, l’utilizzo di strumenti di sicurezza come i WAF, i test di penetrazione e l’autenticazione multifattoriale rafforza la resilienza dell’applicazione. Dare priorità alla sicurezza in ogni fase dello sviluppo permetterà agli sviluppatori di creare applicazioni robuste, affidabili per gli utenti, che rimangano protette contro le moderne minacce informatiche.

Source:
https://dzone.com/articles/enhancing-security-in-javascript