Token XSRF aggiunto ai moduli dinamicamente

2

Non l'ho visto da nessuna parte in natura, quindi mi chiedo se è sicuro iniettare nei moduli della stessa origine l'input nascosto contenente il token XSRF usando JavaScript come questo:

document.addEventListener('DOMContentLoaded', () => {
    // Get token from <html> tag
    const XSRF_TOKEN = document.documentElement.getAttribute('data-xsrf-token');
    const uri = new URI(document.URL);

    // Loop through all forms
    Array.from(document.getElementsByTagName('form')).forEach(el => {
        let actionUri = new URI(el);

        // Only append hidden input to same-origin forms with method POST
        if (actionUri.origin() === uri.origin() && el.method === 'post') {
            let tokenInput = document.createElement('input');
            tokenInput.name = 'xsrf_token';
            tokenInput.type = 'hidden';
            tokenInput.value = XSRF_TOKEN;
            el.appendChild(tokenInput);
        }
    })
});

Il token verrebbe generato per utente per sessione e consegnato con la pagina HTML come valore di attributo sull'elemento <html> .

Naturalmente ciò funzionerebbe solo nelle parti dell'applicazione per le quali è richiesto JavaScript. È molto più semplice che inserire l'input nascosto ovunque.

Molti siti suggeriscono di utilizzare un framework per questo, tuttavia questa non è un'opzione fattibile e se deve essere nascosto input sul caricamento della pagina, il meglio che posso fare è creare una funzione Twig helper per emettere il tag, ma ciò richiede ancora che cosparso ovunque. E se questo è il caso, allora come funzionano i moduli creati dinamicamente?

Non penso che il metodo JavaScript sia meno sicuro di <input type=hidden> ovunque perché il token è recuperabile dal modulo in caso di XSS comunque, ma c'è qualcos'altro che mi manca?

    
posta rink.attendant.6 12.01.2017 - 01:57
fonte

1 risposta

0

I token CSRF ad iniezione dinamica sono un approccio testato sul campo senza difetti di sicurezza intrinsechi.

Ad esempio, il progetto OWASP CSRFGuard supporta questa funzione:

OWASP CSRFGuard 3 supports the ability to dynamically inject CSRF prevention tokens throughout the DOM currently loaded in the user's browser. This strategy is extremely valuable with regards to server-side performance as it simply requires the serving of a dynamic JavaScript file.

Il blog tecnologico iFixit ha anche un articolo su la loro implementazione "minimalista" di questa idea:

We use a small amount of javascript to automatically set a cookie and add a form field immediately before a form is submitted. The server then compares the form field with the cookie and ignores the request if they don't match. This frees us from the hassle of ensuring every form includes a hidden csrf <input> in every template.

Nel loro esempio di codice puoi vedere che il token viene aggiunto poco prima dell'invio, il che è probabilmente più sicuro che aggiungerlo caricamento del documento (poiché qualcosa potrebbe causare la modifica del target del modulo nel frattempo):

window.addEvent('domready', function() {
   /**
    * Setup triggers on the .submit() function and the 'submit' event so we
    * can add csrf inputs immediately before the form is submitted.
    */
   $$('form').each(function(form) {
      // Ensure all forms submitted via a traditional 'submit' button have
      // an up-to-date CSRF input
      form.addEvent('submit', function() {
         ensureFormHasCSRFFormField(form);
      });
      // Ensure all forms submitted via form.submit() have an up-to-date CSRF
      // input
      var oldSubmit = form.submit;
      // Wrap the default submit() function with our own
      form.submit = function () {
         ensureFormHasCSRFFormField(form);
         return oldSubmit.apply(form, Array.from(arguments));
      }
   });
});

Non ci sono problemi di sicurezza inerenti con questo approccio se si assicura che il target del modulo abbia l'origine corretta. Riduce anche alcuni attacchi, ad es. in questo scenario . (L'articolo tratta di una falla XSS in cui il CSP previene tutti gli script inline, quindi l'autore dell'attacco è limitato all'iniezione HTML puro. L'autore presenta un metodo per modificare l'obiettivo modulo-azione senza JS al fine di estrarre un CSRF token impostato in un campo di input nascosto. Ora se quel token è stato invece aggiunto dinamicamente, l'attacco sarebbe fallito perché il tuo script avrebbe riconosciuto che il modulo si sottomette a un'origine non attendibile.)

    
risposta data 12.01.2017 - 02:54
fonte

Leggi altre domande sui tag