CSRF con JSON POST quando Content-Type deve essere application / json

9

Sto testando un'applicazione web per cui vengono eseguite le azioni aziendali inviando richieste JSON come ad esempio:

POST /dataRequest HTTP/1.1
Host: test.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 
Firefox/55.0
Accept: */*
Accept-Language: pl,en-US;q=0.7,en;q=0.3
Content-Type: application/json; charset=utf-8
Content-Length: 99
Cookie: SESSIONID=7jtyutuytu1a
Connection: close

{"F":"test.AppRequestFactory","I":[{"O":"5vhghgjhgjE0="}]}

Ho creato la pagina di invio automatico HTML come questa

<html>
<head>
</head>
<body onload=document.getElementById('xsrf').submit()>
    <form id="xsrf" action="https://test.com/dataRequest" method=post enctype="text/plain">
    <input name='{"F":"test.AppRequestFactory","I":[{"O":""O":"5vhghgjhgjE0' value='"}]}' type='hidden'>
    </form>
</body>
</html>

Il problema è che verrà inviato con l'intestazione Content-Type: text/plain , ma il server accetta solo Content-Type: application/json; charset=utf-8 .

Ho letto la discussione CSRF con JSON POST dove uno dei commenti afferma:

Use something like this: var blob= new Blob([JSON.stringify(YOUR JSON)], {type : 'application/json; charset=UTF-8'}); to generate a JSON blob and it'll send perfectly. CSRF in seconds!

Ma non ho idea di come usare questo approccio.

Questa applicazione è vulnerabile all'attacco CSRF?

    
posta user187205 01.10.2017 - 18:53
fonte

3 risposte

8

Is this application vulnerable to CSRF attack?

Sì, è vulnerabile. Il prerequisito, tuttavia, è Flash . Con l'aiuto di Flash, è possibile creare un'intestazione Content-type con qualsiasi valore arbitrario. Quello che devi fare è POSTARE una richiesta al tuo dominio e quindi emettere un reindirizzamento 307. Si prega di fare riferimento allo screenshot qui sotto:

Perulterioriinformazioni,fairiferimentoa questo articolo cm2.pw .

Use something like this: var blob= new Blob([JSON.stringify(YOUR JSON)], {type : 'application/json; charset=UTF-8'}); to generate a JSON blob and it'll send perfectly. CSRF in seconds!

Questo, afaik, è già stato risolto nei browser moderni. Tuttavia, funziona ancora in IE con file URI.

    
risposta data 21.12.2017 - 09:16
fonte
5

Warning: This answer may be wrong and to optimistic. See 1lastBr3ath's answer above.

No, non penso che l'applicazione sia vulnerabile.

Puoi modificare l'intestazione Content-Type , ad es. utilizzando l' API di recupero . Tuttavia, ci sono solo tre valori che puoi utilizzare per le richieste cross domain:

application/x-www-form-urlencoded
multipart/form-data
text/plain

Se lo cambi in qualcos'altro, come application/json , il browser prima farà una richiesta di OPTIONS al server, per vedere se permette che quell'intestazione sia cambiata. Questo comportamento fa parte di CORS ed è progettato per limitare le richieste del dominio incrociato può fare con JavaScript per quelli vecchio stile che potresti fare con HTML semplice. Quindi, a meno che il server non permetta specificamente a qualsiasi dominio di impostare questa intestazione (che sarebbe una cosa stupida da fare), sei sfortunato.

Si noti, tuttavia, che questo sembra essere un caso di "sicurezza per caso". Mi affiderei a qualcosa di più strong per la mia protezione CSRF (e forse lo fanno, una volta superata l'ostacolo del tipo di contenuto). Che cosa succede se un giorno qualcuno pensa che sarebbe bello se il server accetti altri tipi di contenuto e rimuova quella limitazione? Con questa configurazione, sarebbe facile aprire accidentalmente un buco di sicurezza.

    
risposta data 02.10.2017 - 11:37
fonte
0

Un altro modo per ottenere ciò è sfruttando il fatto che la maggior parte dei parser json rispetta l'uso dei commenti. Quindi, creando un semplice modulo html con un input nascosto, puoi inserire i dati JSON come nome dell'elemento di input per farlo pubblicare sul corpo. In questo senario l'unico problema è che quando il modulo viene inviato, il corpo del post avrà il valore '=' (dal nome dell'ingresso = formato del valore). Quindi per evitare ciò e rendere nuovamente valido il jus puoi aggiungere un indicatore di commento alla fine del nome (i tuoi dati json). In questo modo il carattere '=' verrà commentato quando analizzato.

Ecco un esempio:

<html>
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="https://www.example.com/" method="POST" enctype="text/plain">
      <input type="hidden" name='{"name":"value"}//' value="" />
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html>
    
risposta data 07.01.2019 - 12:11
fonte

Leggi altre domande sui tag