C'è un modo per passare dati sensibili in bash usando un prompt, per qualsiasi comando?


40

Supponiamo che stavo usando sha1passper generare un hash di una password sensibile sulla riga di comando. Posso usare sha1pass mysecretper generare un hash di mysecretma questo ha lo svantaggio che mysecretè ora nella storia di Bash. C'è un modo per raggiungere l'obiettivo finale di questo comando evitando di rivelare mysecretin testo semplice, magari usando un passwdprompt in stile?

Sono anche interessato in un modo generalizzato a fare questo per passare dati sensibili a qualsiasi comando. Il metodo cambierebbe quando i dati sensibili vengono passati come argomento (come in sha1pass) o su STDIN a un comando.

C'è un modo per raggiungere questo obiettivo?


Modifica : questa domanda ha attirato molta attenzione e ci sono state diverse buone risposte offerte di seguito. Un riassunto è:

  • Secondo la risposta di @ Kusalananda , idealmente non si dovrebbe mai dare una password o un segreto come argomento della riga di comando a un'utilità. Questo è vulnerabile in diversi modi come descritto da lui, e si dovrebbe usare un'utilità meglio progettata in grado di prendere l'input segreto su STDIN
  • La risposta di @ vfbsilva descrive come impedire che le cose vengano archiviate nella storia di bash
  • @La risposta di Jonathan descrive un metodo perfettamente valido per raggiungere questo obiettivo, purché il programma possa prendere i suoi dati segreti su STDIN. Come tale, ho deciso di accettare questa risposta. sha1passnel mio PO era solo un esempio, ma la discussione ha stabilito che esistono strumenti migliori che raccolgono dati su STDIN.
  • come osserva @R .. nella sua risposta , l'uso dell'espansione del comando su una variabile non è sicuro.

Quindi, in sintesi, ho accettato la risposta di @ Jonathan poiché è la soluzione migliore dato che hai un programma ben progettato e ben educato con cui lavorare. Sebbene passare una password o un segreto come argomento della riga di comando sia fondamentalmente non sicuro, le altre risposte forniscono modi per mitigare i semplici problemi di sicurezza.


6
Non solo: chiunque si trovi sulla stessa macchina con il permesso di elencare i processi in esecuzione può potenzialmente vedere che sha1pass mysecretè in esecuzione, e quindi sapere cos'è mysecret. (Funziona solo per pochi secondi mentre il programma è effettivamente in esecuzione, ovviamente ...)
MathematicalOrchid

@MathematicalOrchid Questo potrebbe essere evitato eseguendolo in una macchina virtuale privata. Ma potrebbe essere troppo lavoro da configurare per generare una sola password ... :-)
Kusalananda

5
@Kusalananda Il mio punto era più "non mettere mai dati sensibili sulla riga di comando, anche se capisci come disattivare la cronologia dei comandi" ...
MathematicalOrchid

2
Solo per questo sai, SHA-1 è deprecato per hash di chiavi o password da diversi anni.
David Foerster,

2
Si noti che se il sistema esegue un demone di controllo, tutti i comandi e tutti gli argomenti di tutti gli utenti vengono registrati centralmente da root, quindi chiunque possa accedere a quei registri vedrà questo.
Randall,

Risposte:


21

Se si utilizza la shell zsho bash, utilizzare l'opzione -s per readincorporare la shell per leggere una riga dal dispositivo terminale senza farne eco.

IFS= read -rs VARIABLE < /dev/tty

Quindi puoi usare un reindirizzamento di fantasia per usare la variabile come stdin.

sha1pass <<<"$VARIABLE"

Se qualcuno corre ps, vedranno solo "sha1pass".

Ciò presuppone che sha1passlegge la password da stdin (su una riga, ignorando il delimitatore di riga) quando non viene fornito alcun argomento.


Credo che abbiamo stabilito che sha1passnon utilizza il suo flusso di input standard.
Kusalananda

@Kusalananda Okay, ma questo metodo funzionerà con programmi che leggono da stdin.
Jonathan,

Quindi, supponendo che l'utilità possa prendere il suo input segreto su STDIN, questa è una soluzione sana e sicura, dal punto di vista della sicurezza?
cemulate il

Ho deciso di accettare questa risposta, dato che è la soluzione migliore dato che hai un programma ben progettato con cui lavorare. sha1passera solo un esempio nel mio PO, e chiaramente non era la scelta migliore da usare per questo.
cemulate il

1
@cemulate, ... non sicuro su una riga di comando . Nel contesto di un heredoc o herestring (come nella risposta qui), non è esposto a ps, ma può essere scritto in un file temporaneo - se uno vuole evitarlo, allora sshpass < <(printf '%s\n' "$VARIABLE")potrebbe essere considerato (perché printfè incorporato, non un comando esterno, non viene passato execve accessibile tramite ps).
Charles Duffy,

36

Idealmente, non digitare mai una password in chiaro nella riga di comando come argomento di un comando. In questo modo la password diventa un argomento per il comando e gli argomenti della riga di comando possono essere visualizzati nella tabella dei processi utilizzando strumenti semplici come pso registrati in alcuni registri di controllo.

Detto questo, ci sono certamente modi per nascondere la password effettiva dalla cronologia dei comandi della shell.

sha1pass "$( head -n 1 )"

Quindi digitare la password e premere Enter. Il headcomando utilizzato qui accetta esattamente una riga di input e l'ultima riga digitata non farà parte dei dati a cui viene passato sha1pass.

Per impedire l'eco dei personaggi:

sha1pass "$( stty -echo; head -n 1; stty echo )"

Il stty -echocomando disattiva l'eco dei caratteri digitati sul terminale. L'eco viene quindi ripristinato con stty echo.

Per trasmettere l'input standard, quell'ultimo comando potrebbe essere modificato (avresti fatto questo se i sha1passdati accettati sull'input standard fossero stati accettati, ma sembra che questa particolare utility ignori il suo input standard):

{ stty -echo; head -n 1; stty echo; } | somecommand

Se è necessario un input su più righe (quanto sopra presuppone che debba essere passata una riga singola, senza caratteri di nuova riga alla fine), quindi sostituire l'intero headcomando con cate terminare l'input (assumendo che somecommandsi legga fino alla fine del file) con Ctrl+D( di seguito Returnse si desidera includere un carattere di nuova riga nell'input o due volte in caso contrario).

Funzionerebbe a prescindere dalla shell che stavi usando (purché fosse una shell tipo Bourne o rc).

Alcune shell possono essere create per non salvare i comandi digitati nei loro file di cronologia se il comando è preceduto da uno spazio. Questo di solito comporta la necessità di impostare HISTCONTROLil valore ignorespace. Questo è supportato da almeno bashe kshsu OpenBSD, ma non da eg ksh93o dash. zshgli utenti possono utilizzare l' histignorespaceopzione o la loro HISTORY_IGNOREvariabile per definire un modello da ignorare.

Nelle shell che supportano la lettura readsenza l'eco dei caratteri sul terminale, è anche possibile utilizzare

IFS= read -rs password     # -s turns off echoing in bash or zsh
                           # -r for reading backslashes as-is,
                           # IFS= to preserve leading and trailing blanks
sha1pass "$password"

ma questo ovviamente ha ancora lo stesso problema nel rivelare potenzialmente la password nella tabella dei processi.

Se l'utilità legge dallo standard input e se la shell supporta "here-string", è possibile modificare quanto sopra

IFS= read -rs password
somecommand <<<"$password"

Riepilogo dei commenti di seguito:

  • L'esecuzione di un comando con una password fornita nella riga di comando, eseguita da tutti i comandi precedenti, ad eccezione di quello che invia i dati al comando, renderà potenzialmente la password visibile a chiunque sia in esecuzione pscontemporaneamente. Nessuno dei comandi precedenti salverà comunque la password digitata nel file di cronologia della shell se eseguita da una shell interattiva.

  • I programmi ben educati che leggono le password in chiaro lo fanno leggendo dal loro input standard, da un file o direttamente dal terminale.

  • sha1pass richiede la password sulla riga di comando, digitata direttamente o usando una qualche forma di sostituzione dei comandi.

  • Se possibile, utilizzare un altro strumento.


11
Questo non è corretto Il risultato dell'espansione del comando $(...)sarà parte della riga di comando e sarà visibile psnell'output tranne che su un sistema con hardened / proc.
R ..

3
@Kusalananda, anche sovrascrivendo l'argv dopo che hai iniziato lascia una finestra vulnerabile prima che abbia luogo la sovrascrittura; è una mitigazione, non una correzione.
Charles Duffy,

5
@Kusalananda, nessun programma ben progettato per le password di hashing richiederà input nella riga di comando, quindi il condizionale è fondamentalmente un dato - in caso contrario , si dovrebbe scegliere uno strumento diverso.
Charles Duffy,

4
@CharlesDuffy: lo strumento qui sembra sostanzialmente rotto. sha1passeseguito senza password sulla riga di comando sembra produrre un output senza leggere nulla ... Quindi OP deve scegliere uno strumento diverso.
R ..

8
Questa risposta non è sicura dal punto di vista della sicurezza e l'unico vantaggio è che la password non viene visualizzata nella cronologia della shell, ma tale vantaggio è più facile da ottenere includendo uno spazio davanti al comando
Ferrybig

25

Se si imposta in questo HISTCONTROLmodo:

HISTCONTROL=ignorespace

e avvia il comando con uno spazio:

~$  mycommand

non verrà archiviato nella cronologia.


10

Passa i dati sensibili tramite una pipe o here-doc:

command_with_secret_output | command_with_secret_input

o:

command_with_secret_input <<EOF
$secret
EOF

Va bene che i segreti siano nelle variabili della shell (non esportate), ma non si possono mai usare quelle variabili nelle righe di comando, solo nei documenti qui e negli interni della shell.

Come notato da Kusalananda in un commento, se si immettono comandi in una shell interattiva, le righe immesse per un documento qui verranno archiviate nella cronologia della shell, quindi non è sicuro digitare una password lì, ma dovrebbe comunque essere variabili di shell sicure da usare contenenti segreti; la storia conterrà il testo $secretpiuttosto che qualunque cosa $secretestesa.

L'uso delle espansioni di comandi non è sicuro :

command_with_secret_input "$(command_with_secret_output)"

perché l'output verrà incluso nella riga di comando e visibile psnell'output (o leggendo manualmente da / proc) tranne nei sistemi con hardened / proc.

Anche l'assegnazione a una variabile va bene:

secret=$(command_with_secret_output)

Quello che sto cercando è un comando effettivo command_with_secret_outputche mi consente di digitare l'output segreto. Esiste un comando del genere che potrebbe essere sostituito qui?
cemulare il

Si noti che digitando un documento qui in una bash sessione interattiva si salverà il documento nel file cronologico.
Kusalananda

@cemulate: basta usare la shell incorporata read, ad es read -r secret. Quindi il tuo segreto è dentro $secret. Se lo desideri, puoi eseguire stty prima / dopo per nascondere l'input.
R ..

3
@Kusalananda: sha1passsembra fondamentalmente rotto / inutilizzabile / non sicuro poiché non può leggere la password da stdin o da un file. Una diversa utility è necessaria per risolvere il problema, credo.
R ..

1
@cemulate Il tuo ultimo commento a R è esattamente sul posto. Ecco perché non aiuterà. read -rsfarà il lavoro (se includi -rper essere in grado di avere password con barre rovesciate), ma poi sei tornato a mostrare potenzialmente la password nell'elenco dei processi (e a seconda se l'account di processo è attivato e come è configurato , anche nei registri di contabilità del processo).
Kusalananda

6

Basta scrivere il valore in un file e passare il file:

$ cat > mysecret
Big seecreeeet!
$ cat mysecret | sha1pass 

Non sono sicuro di come sha1passfunzioni, se può prendere un file come input, puoi usarlo sha1pass < mysecret. In caso contrario, l'utilizzo catpotrebbe essere un problema poiché include la nuova riga finale. In tal caso, utilizzare (se il proprio headsupporto -c):

head -c-1 mysecret | sha1pass 

2
Perché scrivere la password su disco nel tuo primo esempio quando puoi semplicemente fare cat | sha1pass? cat mysecret | sha1passe sha1pass < mysecrethanno lo stesso comportamento rispetto alle newline finali. catnon aggiunge nuove righe. Comunque, se sha1passsupporta il passaggio della password attraverso l'input standard, mi aspetterei che ignori da solo la nuova riga. Dopotutto, i file con linee che non sono terminate da newline sono innaturali in unix, quindi sarebbe imbarazzante aspettarsi un file che non è terminato da una nuova riga.
JoL

@JoL i) perché non ci avevo pensato: / Ma come funzionerebbe? cat | sha1passsembra funzionare sha1passprima di darmi la possibilità di inserire qualsiasi input. ii) No, ovviamente cat mysecretnon aggiunge una nuova riga, non ho mai detto di cataggiungerla, solo che la include .
terdon

Vedo, ma non è nemmeno come < mysecretrimuoverlo. :)
JoL

Non importa. Ora che ho riletto, vedo che lo hai detto per proporre in seguito head -c-1. Immagino di essermi appena confuso sul perché usare cat mysecret | sha1passe poi proporre sha1pass < mysecret. Immagino che la preoccupazione sia che sha1pass possa lamentarsi dei file regolari per stdin; Non sono sicuro del perché.
JoL

@JoL è più perché non ho mai usato sha1passe non sono riuscito a trovare un manuale o -hqualsiasi altra forma di documentazione nei pochi minuti che ho passato a cercare e quindi non sono riuscito a capire se l'esecuzione è sha1pass footrattata foocome una stringa di input o come un file di input . Pertanto ho dato le opzioni per affrontare ogni possibilità.
terdon

1

Se ciò che Terdon ha fatto è possibile, questa è la soluzione migliore, passando attraverso input standard. L'unico problema rimasto è che ha scritto la password sul disco. Possiamo farlo invece:

stty -echo
echo -n "password: "
head -1 | sha1pass
stty echo

Come ha detto Kusalananda, stty -echoassicura che ciò che scrivi non venga visto fino a quando non lo fai di stty echonuovo. head -1otterrà una riga dall'input standard e la passerà a sha1pass.


0

io userei

sha1pass "$(cat)"

catleggerebbe da stdin fino a EOF, che può essere causato premendo Ctrl + D. Quindi, il risultato verrebbe passato come argomento asha1pass


3
La risposta di R .. spiega perché questo non è sicuro.
hvd,
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.