Perché scappare se the_content non lo è?


8

La funzione integrata the_contentscorre attraverso diversi filtri, ma non sfugge all'output. Sarebbe difficile farlo, dato che HTML e persino alcuni script devono essere permessi.

All'uscita, the_content sembra scorrere questi filtri (dalla 5.0):

add_filter( 'the_content', 'do_blocks', 9 );
add_filter( 'the_content', 'wptexturize' );
add_filter( 'the_content', 'convert_smilies', 20 );
add_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'shortcode_unautop' );
add_filter( 'the_content', 'prepend_attachment' );
add_filter( 'the_content', 'wp_make_content_images_responsive' );

(and)

add_filter( 'the_content', 'capital_P_dangit' );
add_filter( 'the_content', 'do_shortcode' );

Sostituisce anche una semplice stringa:

$content = str_replace( ']]>', ']]>', $content );

E poi get_the_content esegue una piccola parte dell'elaborazione relativa al link "more" e un bug con le lingue straniere.

Nessuno di questi impedisce l'iniezione di script XSS, giusto?

Durante il salvataggio, i dati vengono disinfettati tramite wp_kses_post. Ma poiché si tratta di un processo costoso, capisco perché non viene utilizzato in output.

La regola empirica per l'escaping di WordPress è che tutto deve essere evitato, indipendentemente dal risanamento dell'input e il più recentemente possibile. Ho letto diversi articoli dicendo questo, perché il database non deve essere considerato una fonte attendibile.

Ma per i motivi sopra, the_content non lo segue. Né i temi principali (ovvero TwentyNineteen) aggiungono ulteriore escape all'output.

Quindi ... perché aiuta qualcosa a fuggire altrove? Se fossi un hacker con accesso al database, non aggiungerei semplicemente il mio codice al contenuto di un post?


Hai dimenticatowp_kses_post
Tom J Nowell

Funziona attraverso wp_kses_post in uscita? Dove?
progettato il

Risposte:


10

Se fossi un hacker con accesso al database, non aggiungerei semplicemente il mio codice al contenuto di un post?

Se hai accesso al database, è probabile che tu abbia abbastanza accesso che la fuga non ti fermerà. L'evasione non ti aiuterà se sei stato violato. Non dovrebbe. Ci sono altri motivi per scappare. I due principali che mi vengono in mente sono:

Per gestire input non autorizzati

Il contenuto dei post di WordPress viene disinfettato quando viene salvato, ma non tutto il resto. Ad esempio, il contenuto trasmesso tramite una stringa di query nell'URL non viene disinfettato. Né è contenuto nei file di traduzione, necessariamente. Entrambe sono fonti di contenuto che non hanno nulla a che fare con il sito compromesso. Quindi il testo e il contenuto traducibili estratti dall'URL devono essere sfuggiti.

Per impedire agli utenti di rompere accidentalmente il markup

L'evasione non è solo per sicurezza. Ne hai bisogno anche per impedire agli utenti di rompere accidentalmente il markup del loro sito. Ad esempio, se l'utente inserisce virgolette o >simboli in alcuni contenuti del plug-in, interromperebbe il markup, quindi dovresti evitare quell'output. Non vuoi essere troppo aggressivo nella sanificazione dell'input, perché ci sono ragioni perfettamente valide per cui un utente potrebbe voler usare quei caratteri.


“La fuga non riguarda solo la protezione dai cattivi. Sta solo rendendo durevole il nostro software. Contro input male casuali, contro input malevoli o contro il maltempo. "

Questo è dalle linee guida VIP di WordPress sull'evasione . C'è molto altro da dire su questo argomento e dovresti dargli una lettura.


Grazie, è utile. Avevo letto un post su VIP sull'evasione e l'autore menzionava specificamente l'idea di qualcuno che avesse ottenuto l'accesso al DB ma non al server. Comunque penso che il tuo ragionamento su questo punto abbia più senso. E, suppongo, a volte stai sfuggendo al contenuto vulnerabile dal database anche senza che qualcuno abbia avuto accesso completo al database, cioè tramite un plugin o anche solo un commento.
progettato il

9

In realtà sono un ingegnere di VIP che fa molta revisione del codice :) Contrassegno un sacco di scappare.

ma non sfugge all'output

Non proprio, non sfugge all'output, il che è sorprendente per la maggior parte delle persone. Questo perché se sei un super amministratore hai le unfiltered_htmlcapacità, quindi non può sfuggire all'output. Invece lo esegue wp_kses_postsu input. Idealmente dovresti rimuovere quella funzionalità però.

Ecco l'implementazione al momento attuale:

function the_content( $more_link_text = null, $strip_teaser = false ) {
    $content = get_the_content( $more_link_text, $strip_teaser );

    /**
     * Filters the post content.
     *
     * @since 0.71
     *
     * @param string $content Content of the current post.
     */
    $content = apply_filters( 'the_content', $content );
    $content = str_replace( ']]>', ']]>', $content );
    echo $content;
}

Il meccanismo ideale per sfuggire a tutto ciò che passa attraverso il the_contentfiltro d'altra parte è:

echo apply_filters( 'the_content', wp_kses_post( $content ) );

In questo modo rendiamo il contenuto sicuro, quindi lo eseguiamo attraverso il filtro, evitando che vengano rimossi gli incorporamenti, ecc.

Quindi perché scappare

Il punto di fuga è generare HTML valido, la maggiore sicurezza che fornisce è solo un piacevole effetto collaterale.

Per impedire agli utenti di rompere accidentalmente il markup

Ci sono molte ragioni per scappare, ma fondamentalmente stai facendo rispettare le aspettative. Prendi il seguente codice:

<a href="<?=$url?>">

Ci aspettiamo $urldi contenere un URL adatto ad un hrefattributo, ma cosa succede se non lo è? Bene, perché lasciarlo al caso, imponiamolo:

<a href="<?=esc_url( $url )?>">

Ora sarà sempre un URL. Non importa se un hacker inserisce un'immagine $urlo se un utente digita nel campo sbagliato o se esiste uno script dannoso. Sarà sempre un URL valido perché abbiamo detto che sarà un URL. Certo potrebbe essere un URL molto strano, ma soddisferà sempre l'aspettativa che un URL sia presente. È molto utile, sia per la convalida del markup, per la sicurezza, ecc

Detto questo, fuggire non è validazione, fuggire non è sanificazione. Questi sono passaggi separati che avvengono in diversi punti del ciclo di vita. La fuga obbliga le cose a soddisfare le aspettative, anche se le fa impazzire.

A volte mi piace pensare di scappare come uno di quei giochi giapponesi con il gigantesco muro di schiuma con il taglio. I concorrenti devono adattarsi alla forma del cane o vengono scartati, solo per i nostri scopi ci sono laser e coltelli attorno al buco. Qualunque cosa rimanga alla fine sarà a forma di cane, e sarà spietata e severa se non sei già a forma di cane.

Ricorda:

  • disinfettare presto
  • convalidare in anticipo
  • scappare tardi
  • scappare spesso

La sicurezza è un passaggio multiplo, strato di difesa a più livelli, la fuga è uno degli strati esterni di difesa in uscita. Può manipolare il codice di attacco su un sito compromesso rendendolo inutile, contrastare gli exploit aperti e assicurarsi che il tuo client non rompa un sito inserendo i tag in un campo che non dovrebbero. Non è un sostituto per le altre cose, ed è di gran lunga lo strumento di sicurezza più sottoutilizzato in un manuale per gli sviluppatori.

Quanto al perché scappare se the_contentnon lo fa? Se hai un diluvio in arrivo, e 5 buchi in un muro, ma solo il tempo per sistemare 3, fai spallucce e non aggiusti nessuno? O mitighi il rischio e riduci l'area di attacco?

Forse posso aiutarti a correggere quelle ultime 2 buche con questo frammento:

add_filter( 'the_content' function( $content ) {
    return wp_kses_post( $content );
}, PHP_INT_MAX + 1 );

Qui impostiamo la priorità sul numero più alto possibile in PHP, quindi aggiungiamo 1 in modo che trabocchi al numero più basso possibile che può essere rappresentato. In questo modo tutte le chiamate a the_contentsfuggiranno al valore prima di qualsiasi altro filtro. In questo modo gli incorporamenti ecc funzionano ancora, ma gli utenti non possono intrufolarsi in HTML pericoloso tramite il database. Inoltre, cerca di rimuovere la unfiltered_htmlfunzionalità da tutti i ruoli


1
Grazie per la prospettiva aggiuntiva. In realtà avevo letto il tuo post su questo argomento sul tuo sito e mi chiedevo se avresti avuto qualcosa da aggiungere.
progettato il

4

Il punto di fuga è generare HTML valido, la maggiore sicurezza che fornisce è solo un piacevole effetto collaterale.

I filtri applicati al contenuto generano un codice HTML valido da qualcosa che è un mix di HTML e altri testi che hanno qualche altra sintassi come i codici brevi. Il fatto che parte del contenuto sia già valido HTML impedisce l'applicazione di escape su tutto.

Per quanto ksesriguarda le funzioni correlate, non è possibile applicarle principalmente perché non si dispone di un contesto sufficiente per sapere quale utilizzare. Ad esempio, potrebbe esserci un processo che utilizza il the_contentfiltro per aggiungere JS al contenuto del post, pertanto il core non può indovinare in base a cose come l'autore del post se JS è legittimo o meno.

Quindi ... perché aiuta qualcosa a fuggire altrove? Se fossi un hacker con accesso al database, non aggiungerei semplicemente il mio codice al contenuto di un post?

Ancora una volta, l'escaping serve per generare HTML valido. Da un POV di sicurezza non è che la fuga fornisce sicurezza ma che un codice che sfugge alla fortuna dovrebbe essere sospetto in quanto potrebbe essere più facile da sfruttare. Ad esempio, il modo in cui core usa _ee '__` per le traduzioni significa che chiunque sia in grado di convincerti ad installare una traduzione non ufficiale potrebbe essere in grado di aggiungere duro per rilevare JS nel file di traduzione e hackerare il tuo sito. Questo è un buon esempio di "fai quello che dico e non quello che faccio".


Grazie, Mark, per la prospettiva aggiuntiva.
progettato il

2

Se fossi un hacker con accesso al database, non aggiungerei semplicemente il mio codice al contenuto di un post?

Penso che la tua domanda risponda da sola. Se eri un hacker con accesso al db, allora hai già ottenuto l'accesso di cui hai bisogno. L'escaping dell'output non lo cambia affatto.

Il motivo della fuga dell'output sta valutando i dati non attendibili per evitare che l'hacker ottenga tale accesso in primo luogo.


Grazie per la tua risposta. Penso di essermi concentrato troppo sull'idea di impedire a un hacker di perdere la foresta per gli alberi.
progettato il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.