HTML, chmod, contenitori e cron
Il ragionamento alla base di quattro utilità: perché un editor HTML ha bisogno di una lista consentita e di una sandbox, perché la S maiuscola in una stringa chmod è importante, cosa un comando docker run non può esprimere in compose e le due regole cron che catturano tutti.
L'editor HTML: una lista consentita, non un filtro
L'editor produce HTML e HTML proveniente da una casella di testo è il vettore di iniezione più vecchio esistente. Qui si confondono due domande diverse, quindi vale la pena separarle. Il primo è "è possibile indurre questo editor a emettere markup che esegue il codice nella pagina che lo visualizza?" Il secondo è "è un modo sicuro per eliminare HTML ostile da una fonte non attendibile?" Questo strumento risponde sì al primo e no al secondo, e lo dice sul pannello anziché lasciarti supporre il contrario.
Il meccanismo è una lista consentita. È consentito un elenco di elementi; ogni altro elemento viene scartato, quindi il suo testo sopravvive e il suo tag no. È consentito un elenco di attributi per elemento; tutto il resto viene eliminato, il che rende ogni gestore di eventi impossibile anziché semplicemente bloccato. I nomi degli attributi vengono scritti in minuscolo prima del test, quindi oNeRrOr e ONERROR sono lo stesso nome rifiutato di onerror. Gli elementi i cui contenuti il parser HTML tratta come testo non elaborato (script, stile, textarea, iframe, titolo) vengono rimossi insieme ai loro contenuti, perché scartarli incollerebbe l'origine dello script nel documento come markup.
Gli indirizzi dei collegamenti ricevono il proprio controllo. Il valore viene decodificato dall'entità e privato degli spazi bianchi e dei caratteri di controllo prima che il suo schema venga letto, perché questo è ciò che fa un browser quando naviga: javascript:alert(1) e jav ascript:alert(1) raggiungono entrambi lo stesso posto. Sopravvivono solo http, https, mailto, tel, ftp e relativi indirizzi. Un riferimento a un carattere che lo strumento non è in grado di risolvere - : è il classico - fa sì che l'intero indirizzo venga rifiutato anziché superato, perché un filtro che comprende meno input rispetto al browser è un filtro con un buco.
Non è presente alcun pulsante immagine e img non è nella lista consentita. Un tag immagine consentito è una richiesta in uscita da qualunque punto arrivi il documento e una superficie di errore. Per un editore che produce prosa, non vale neanche la pena.
La difesa che non dipende dalla perfezione di tutto ciò è l'anteprima. Viene visualizzato in un iframe con un attributo sandbox che non garantisce nulla: nessuno script, nessun modulo, nessun accesso dalla stessa origine. Se un payload sopravvivesse alla lista consentita, il browser si rifiuterebbe comunque di eseguirlo lì. Questa è una garanzia strutturale piuttosto che una promessa sul nostro codice.
L'onesta limitazione: questo è un disinfettante basato su stringhe, non un parser HTML5 completo. I differenziali del parser - input in cui un browser costruisce un albero diverso rispetto a quello fatto da questo tokenizzatore - sono la nota debolezza di ogni disinfettante costruito in questo modo. Per l'output ti generi in questo editor che va bene. Per pulire HTML arrivato da uno sconosciuto, utilizza un disinfettante confrontato con un parser reale, su un server che controlli.
Chmod: la lettera maiuscola è l'intero messaggio
Una modalità file Unix è composta da dodici bit: tre bit di autorizzazione per ciascuno di proprietario, gruppo e altro, più setuid, setgid e lo sticky bit. La forma ottale è una lettura diretta di quei bit, motivo per cui 4 + 2 + 1 = 7 significa leggere, scrivere ed eseguire.
La forma simbolica che ls stampa è quella in cui i bit speciali diventano interessanti, perché non hanno una propria colonna. setuid sostituisce il carattere di esecuzione del proprietario, setgid sostituisce il carattere di esecuzione del gruppo e sticky sostituisce l'altro carattere di esecuzione. La lettera è minuscola quando è impostato anche il bit di esecuzione sottostante e UPPER maiuscola quando non lo è.
Quindi 4755 è rwsr-xr-x — un programma setuid che può essere eseguito — mentre 4644 è rwSr--r--, un file setuid che nessuno può eseguire. La S maiuscola è il sistema che ti dice che il bit è inerte, ed è quasi sempre un errore piuttosto che una scelta. Lo stesso vale per 1644, che mostra rw-r--r-T: uno sticky bit su un file normale in cui il bit other-execute è chiaro, che su un kernel moderno non fa esattamente nulla.
Altre due distinzioni che vale la pena tenere ben chiare. La stringa di nove caratteri che ls stampa non è l'argomento preso da chmod: chmod vuole una lista di assegnazioni come u=rwx,g=rx,o=rx,u+s. E gli stessi bit significano cose diverse su una directory rispetto a un file: esegui significa "può entrare e attraversare", setgid significa "nuovi file ereditano questo gruppo" e il bit adesivo significa "chiunque può creare, solo il proprietario può eliminare", che è il motivo per cui /tmp è 1777.
la finestra mobile viene eseguita per comporre: analisi e cosa non converte
Il convertitore divide il comando con un tokenizzatore che riconosce le virgolette scritto per questo strumento. Niente viene eseguito, valutato o passato a una shell. Un comando contenente apici inversi, $(...) o un punto e virgola viene letto come caratteri letterali, perché l'unica cosa che questo strumento fa con il tuo input è leggerlo.
La maggior parte dei flag viene mappata in modo pulito: porte, volumi, ambiente, etichette, policy di riavvio, funzionalità, controlli di integrità, limiti di risorse, DNS e host aggiuntivi hanno tutti chiavi di composizione con lo stesso significato. I volumi denominati e le reti definite dall'utente necessitano di una dichiarazione di livello superiore nonché del riferimento al servizio, quindi l'output ne porta uno: external: true sulle reti, perché l'esecuzione di una finestra mobile di rete a cui potrebbe unirsi era già esistente.
Alcuni flag non hanno un equivalente di composizione, ed è qui che i convertitori di solito falliscono silenziosamente. --rm non è una proprietà del servizio: un servizio di composizione non viene rimosso quando esce. -d descrive come hai richiamato CLI, non qual è il servizio. --link è legacy, --mount richiede un formato lungo che questo strumento non scrive, --gpus dipende dal driver. Ognuno di questi produce un avviso con nome invece di svanire. Anche un flag sconosciuto produce un avviso e viene considerato come se non assumesse alcun valore, perché supporre che ne sia richiesto uno trasformerebbe il nome dell'immagine in un argomento e produrrebbe un file con sicurezza sbagliato.
L'output non contiene una versione di livello superiore: key. Compose v2 lo ignora e le versioni attuali lo avvertono; è obsoleto da quando la specifica di composizione ha sostituito le vecchie versioni del formato file.
Citare non è cosmetico. Una mappatura della porta scritta come 8080:80 senza virgolette viene letta come un numero dai parser YAML 1.1 e sì, no, on e off sono booleani nello stesso dialetto. Tutto ciò che potrebbe essere frainteso viene citato; tutto ciò che viene letto in modo pulito come una stringa viene lasciato intatto, quindi il file rimane leggibile.
Cron: due regole che catturano tutti
La prima è la regola del giorno. Quando sia il giorno del mese che il giorno della settimana sono impostati su qualcosa di diverso da *, cron esegue il lavoro quando EITHER corrisponde, non quando lo fanno entrambi. Quindi 0 0 13 * 5 è "mezzanotte del 13 e mezzanotte ogni venerdì", ovvero circa cinque volte al mese, non "venerdì 13", che avviene una o due volte all'anno. Il generatore avvisa ogni volta che entrambi i campi sono limitati e la frase che scrive dice "o" anziché "e".
Il secondo è il fuso orario. Cron utilizza la zona della macchina su cui viene eseguito, che spesso è UTC su un server e quasi mai la zona della persona che scrive il crontab. L'anteprima successiva richiede quindi quale zona utilizzare piuttosto che assumere la tua. Gli orari vengono calcolati come orari dell'orologio in quella zona, quindi un lavoro quotidiano rimane alla stessa ora locale durante il cambio dell'ora legale anziché spostarsi di un'ora - e un'ora locale che non esiste, nell'ora saltata ogni primavera, viene lasciata fuori dall'elenco, perché cron non verrà eseguito neanche in quel caso.
La sintassi stessa è piccola: una stella, un numero, un intervallo a-b, una lista a,b,c, un passo */n o a-b/n, e i nomi del mese e del giorno JAN-DEC E SUN-SAT. Entrambi 0 E 7 significa domenica. Un valore nudo con un passo, ad esempio 5/15 nel campo dei minuti, significa "da 5 fino alla fine dell'intervallo, ogni 15", che è minuto 5, 20, 35 E 50.
La convalida è rigorosa di proposito. 60 * * * * viene rifiutato perché i minuti si fermano a 59; * * * * 8 viene rifiutato perché il campo del giorno si ferma a 7; */0 * * * * viene rifiutato perché un passo pari a zero non corrisponde a nulla. Sei campi di solito indicano un'espressione Quartz o systemd il cui primo campo è secondi, quindi l'errore lo dice invece di contare solo. Una pianificazione sintatticamente valida ma che non potrà mai essere eseguita — 0 0 30 2 * chiede per il 30 febbraio — viene accettata e contrassegnata, perché rifiutarla sarebbe sbagliata e tacere sarebbe peggio.
Cosa succede a ciò che incolli
- Ogni conversione, hash, decodifica e differenza viene eseguita nella scheda del tuo browser. Nessun input viene caricato, registrato o archiviato su un server, perché non è coinvolto alcun server una volta caricata la pagina.
- Gli hash provengono dall'implementazione Web Crypto del browser e gli UUID dal suo generatore casuale crittograficamente sicuro. Nessuno dei due prevede una chiamata di rete.
- Niente di ciò che digiti viene scritto nella memoria locale o in un cookie. Ricaricando la pagina la si elimina; chiudendo la scheda la si elimina.
- L'analisi a livello di sito viene eseguita solo sull'host di produzione canonico configurato e viene divulgata nell'Informativa sulla privacy; gli host locali e di anteprima lo rifiutano. Valori, token, URL e contenuti dei file incollati sono esclusi dagli eventi di analisi di ToolAcre. La pubblicità è disabilitata nella configurazione attuale.
- Detto questo: una chiave JWT o API è una credenziale attiva. L'abitudine più sicura è non incollarne mai uno in una pagina web che non hai scritto tu, per quanto attendibili siano le sue affermazioni, inclusa questa.
Domande
Posso incollare HTML ostile nell'editor per pulirlo?
Puoi incollarlo e non verrà eseguito nulla: il gestore incolla disinfetta il payload degli appunti prima che venga inserito qualsiasi cosa e l'anteprima è un iframe sandbox senza script di autorizzazione. Ma non utilizzare il risultato come controllo di sicurezza per input non attendibili. Questa è una lista consentita basata su stringhe per l'output di un editor, non un filtro XSS generico e il parser di un browser può raggiungere un albero diverso rispetto a un tokenizzatore come questo. Per i contenuti non attendibili, disinfetta su un server con un vero parser HTML5.
Perché l'editor cancella le mie immagini e le mie tabelle?
Perché non sono nella lista consentita. Le immagini sono una richiesta in uscita e una superficie di errore; le tabelle sono semplicemente al di fuori dello scopo di questo editor. Il loro contenuto testuale sopravvive, i tag no. Questo è il funzionamento della lista consentita e non un bug, ma significa che non è lo strumento giusto per modificare un documento esistente complesso.
Perché chmod 4644 mostra una S maiuscola?
Perché setuid è impostato e il bit di esecuzione del proprietario non lo è. La lettera maiuscola significa che il bit speciale non ha nulla su cui agire: è un file setuid che non può essere eseguito. La s minuscola significa che entrambi i bit sono impostati. La stessa regola ti dà S per setgid e T per lo sticky bit, e riportarlo all'indietro è l'errore più comune nei calcolatori di modalità.
Il convertitore docker esegue il mio comando?
No, e non può. Il comando è suddiviso da un tokenizzatore che comprende le virgolette e nient'altro. Non esiste alcuna valutazione, né shell, né processo figlio: la pagina non ha modo di avviarne uno. Tutto ciò che incolli rimane nella scheda.
Perché il convertitore avvisa invece di rilasciare semplicemente un flag che non è in grado di gestire?
Perché un file di composizione che esegue silenziosamente meno del comando da cui proviene è peggio di nessun output: lo scopri in produzione. Ogni bandiera che non è rappresentata ha un nome, con cosa fare al riguardo. Se non vedi alcun avviso, non è andato perduto nulla.
Perché le prossime esecuzioni cron sono diverse da quelle eseguite dal mio server?
Quasi sempre il fuso orario. Cron utilizza la zona della macchina che lo esegue; l'anteprima utilizza la zona selezionata nel menu a discesa. Impostalo sulla zona del tuo server, spesso UTC, e loro dovrebbero essere d'accordo. L'altro candidato è la regola del giorno: se sono impostati sia il giorno del mese che il giorno della settimana, cron viene eseguito su entrambi, il che avviene più spesso di quanto la maggior parte delle persone intenda.
Limitazioni
- Il disinfettante HTML è una lista consentita per l'output di questo editor, implementato come tokenizzatore di stringhe anziché come parser HTML5 completo. Non è un filtro XSS generico e non deve essere utilizzato come tale.
- L'editor non ha immagini, tabelle, colori o controlli dei caratteri e non c'è modo di aggiungerli: tutto ciò che è al di fuori della lista consentita viene rimosso.
- La superficie di modifica utilizza document.execCommand, che è deprecato e non ha alcuna sostituzione implementata. I browser lo supportano ancora; il comportamento differisce leggermente tra loro, specialmente riguardo alla nidificazione delle liste.
- Il calcolatore chmod copre solo i dodici bit di autorizzazione. Elenchi di controllo degli accessi, attributi estesi, contesti SELinux, aritmetica umask e ACL di Windows non rientrano nell'ambito.
- Il convertitore docker traduce un singolo comando di esecuzione docker in un singolo servizio. Non legge i Dockerfile, non risolve le immagini e non può esprimere --mount, --gpus, --device, --link o --volumes-from; ognuno di questi produce invece un avviso con nome.
- I flag che il convertitore non riconosce vengono considerati come se non assumessero alcun valore. Se un flag di questo tipo ne ha preso uno, il valore verrà interpretato erroneamente: l'avviso lo dice e la rimozione del flag è la soluzione.
- Il generatore cron legge solo il formato crontab a cinque campi. Espressioni Quartz e systemd a sei campi, @reboot e le espressioni non standard L, W, # e ? gli operatori vengono rifiutati anziché indovinati.
- Gli orari di esecuzione successiva provengono dal database del fuso orario del browser tramite Intl. Sono un'anteprima, non una garanzia: la macchina che esegue cron potrebbe avere una zona diversa, una versione diversa del database o un demone che non era in esecuzione quando è arrivato il momento.