AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 443511
Accepted
Viktor
Viktor
Asked: 2018-05-14 00:36:10 +0800 CST2018-05-14 00:36:10 +0800 CST 2018-05-14 00:36:10 +0800 CST

É perigoso executar echo sem aspas?

  • 772

Eu vi alguns tópicos semelhantes, mas eles estão se referindo a não citar variáveis, o que eu sei que pode levar a resultados indesejados.

Eu vi este código e queria saber se seria possível injetar algo para ser executado quando esta linha de código for executada:

echo run after_bundle

shell security
  • 2 2 respostas
  • 9158 Views

2 respostas

  • Voted
  1. Stéphane Chazelas
    2018-05-14T02:12:01+08:002018-05-14T02:12:01+08:00

    Apenas uma nota extra sobre a boa resposta de @Kusalananda .

    echo run after_bundle
    

    está bem porque nenhum dos caracteres nesses 3 argumentos¹ passou para echoconter caracteres que são especiais para o shell.

    E (o ponto extra que quero destacar aqui) não há nenhuma localidade do sistema onde esses bytes possam ser convertidos em caracteres especiais para o shell.

    Todos esses caracteres estão no que o POSIX chama de conjunto de caracteres portáteis . Esses caracteres devem estar presentes e codificados da mesma forma em todos os conjuntos de caracteres em um sistema POSIX².

    Portanto, essa linha de comando será interpretada da mesma forma, independentemente da localidade.

    Agora, se começarmos a usar caracteres fora desse conjunto de caracteres portátil, é uma boa ideia colocá-los entre aspas mesmo que não sejam especiais para o shell, porque em outro locale, os bytes que os constituem podem ser interpretados como caracteres diferentes que podem se tornar especial para a casca. Observe que se você está usando echoou qualquer outro comando, o problema não é, echomas como o shell analisa seu código.

    Por exemplo, em um UTF-8:

    echo voilà | iconv -f UTF-8 -t //TRANSLIT
    

    Isso àé codificado como 0xc3 0xa0. Agora, se você tiver essa linha de código em um script de shell e o script de shell for invocado por um usuário que usa uma localidade cujo conjunto de caracteres não é UTF-8, esses dois bytes podem criar caracteres muito diferentes.

    Por exemplo, em uma fr_FR.ISO8859-15localidade, uma localidade francesa típica usando o conjunto de caracteres padrão de byte único que abrange o idioma francês (o mesmo usado para a maioria dos idiomas da Europa Ocidental, incluindo o inglês), esse byte 0xc3 é interpretado como o Ãcaractere e 0xa0 como o não- quebrando o caractere de espaço.

    E em alguns sistemas como o NetBSD³, esse espaço sem quebra é considerado um caractere em branco ( isblank()nele retorna true, é correspondido por [[:blank:]]) e shells como bash, portanto, o tratam como um delimitador de token em sua sintaxe.

    Isso significa que, em vez de executar echocomo $'voil\xc3\xa0'argumento, eles o executam $'voil\xc3'como argumento, o que significa que não será impresso voilàcorretamente.

    Fica muito pior com conjuntos de caracteres chineses como BIG5, BIG5-HKSCS, GB18030, GBK, que têm muitos caracteres cuja codificação contém a mesma codificação que |, `, \(para citar o pior) (também aquele ridículo SJIS, também conhecido como Microsoft Kanji, exceto que é em ¥vez de \, mas ainda é tratado como \pela maioria das ferramentas, pois é codificado como 0x5c lá).

    Por exemplo, se em uma zh_CN.gb18030localidade chinesa, você escreve um script como:

    echo 詜 reboot
    

    Esse script será gerado 詜 rebootem uma localidade usando GB18030 ou GBK, 唰 rebootem uma localidade usando BIG5 ou BIG5-HKSCS, mas em uma localidade C usando ASCII ou uma localidade usando ISO8859-15 ou UTF-8, fará com rebootque seja executado porque a codificação GB18030 of 詜é 0xd4 0x7c e 0x7c é a codificação de |em ASCII, então acabamos executando:

     echo �| reboot
    

    (que representa, no entanto, o byte 0xd4 é renderizado na localidade). Exemplo usando o menos prejudicial unameem vez de reboot:

    $ echo $'echo \u8a5c uname' | iconv -t gb18030 > myscript
    $ LC_ALL=zh_CN.gb18030 bash ./myscript | sed -n l
    \324| uname$
    $ LC_ALL=C bash ./myscript | sed -n l
    Linux$
    

    ( unamefoi executado).

    Portanto, meu conselho seria citar todas as strings que contêm caracteres fora do conjunto de caracteres portátil.

    No entanto, observe que, como a codificação de \e `é encontrada na codificação de alguns desses caracteres, é melhor não usar \ou "..."ou $'...'(dentro dos quais `e/ou \ainda são especiais), mas, '...'em vez disso, citar caracteres fora do conjunto de caracteres portátil.

    Não tenho conhecimento de nenhum sistema que tenha uma localidade em que o conjunto de caracteres tenha qualquer caractere (além 'dele, é claro) cuja codificação contenha a codificação de ', portanto, esses '...'devem ser definitivamente os mais seguros.

    Observe que vários shells também oferecem suporte a uma $'\uXXXX'notação para expressar caracteres com base em seu ponto de código Unicode. Em shells como zshe bash, o caractere é inserido codificado no conjunto de caracteres do local (embora possa causar comportamentos inesperados se esse conjunto de caracteres não tiver esse caractere). Isso permite que você evite inserir caracteres não-ASCII em seu código shell.

    Então acima:

    echo 'voilà' | iconv -f UTF-8 -t //TRANSLIT
    echo '詜 reboot'
    

    Ou:

    echo $'voil\u00e0'
    echo $'\u8a5c reboot'
    

    (com a ressalva de que pode interromper o script quando executado em locais que não possuem esses caracteres).

    Ou melhor, pois \também é especial para echo(ou pelo menos algumas echo implementações, pelo menos as compatíveis com Unix):

    printf '%s\n' 'voilà' | iconv -f UTF-8 -t //TRANSLIT
    printf '%s\n' '詜 reboot'
    

    (observe que \também é especial no primeiro argumento para printf, portanto, caracteres não ASCII também devem ser evitados, caso possam conter a codificação de \).

    Observe que você também pode fazer:

    'echo' 'voilà' | 'iconv' '-f' 'UTF-8' '-t' '//TRANSLIT'
    

    (isso seria um exagero, mas poderia lhe dar alguma tranquilidade se você não tiver certeza de quais personagens estão no conjunto de caracteres portátil)

    Certifique-se também de nunca usar a `...`forma antiga de substituição de comando (que introduz outro nível de processamento de barra invertida), mas use -a $(...).


    ¹ tecnicamente, echotambém é passado como argumento para o echoutilitário (para dizer como foi invocado), é o argv[0]e argcé 3, embora na maioria dos shells hoje em dia echoseja embutido, exec()de modo que um /bin/echoarquivo com uma lista de 3 argumentos seja simulado pelo Concha. Também é comum considerar a lista de argumentos como começando com o segundo ( argv[1]to argv[argc - 1]), pois é sobre eles que os comandos agem principalmente.

    ² uma exceção notável a isso sendo a ja_JP.SJISlocalidade ridícula dos sistemas FreeBSD cujo conjunto de caracteres não possui nenhum caractere \nem ~!

    ³ observe que, embora muitos sistemas (FreeBSD, Solaris, mas não os GNU) considerem U+00A0 como um [[:blank:]]em localidades UTF-8, poucos o fazem em outras localidades como as que usam ISO8859-15, possivelmente para evitar esse tipo de problema.

    • 27
  2. Best Answer
    Kusalananda
    2018-05-14T00:41:47+08:002018-05-14T00:41:47+08:00

    Para o caso específico

    echo run after_bundle
    

    citação não é necessária. Nenhuma citação é necessária porque o argumento to echosão strings estáticas que não contêm expansões de variáveis ​​ou substituições de comandos, etc. Elas são "apenas duas palavras" (e como Stéphane aponta , elas são adicionalmente construídas a partir do conjunto de caracteres portátil ).

    O "perigo" surge quando você lida com dados variáveis ​​que o shell pode expandir ou interpretar. Nesses casos, deve-se tomar cuidado para que o shell faça a coisa certa e que o resultado seja o pretendido.

    As duas perguntas a seguir contêm informações relevantes sobre isso:

    • Por que printf é melhor que echo?
    • Implicações de segurança de esquecer de citar uma variável em shells bash/POSIX

    echoàs vezes é usado para "proteger" comandos potencialmente prejudiciais em respostas neste site. Por exemplo, posso mostrar como remover arquivos ou mover arquivos para um novo destino usando

    echo rm "${name##*/}.txt"
    

    ou

    echo mv "$name" "/new_dir/$newname"
    

    Isso produziria comandos no terminal em vez de realmente remover ou renomear arquivos. O usuário pode então inspecionar os comandos, decidir se eles parecem ok, removê-los echoe executá-los novamente.

    Seu comando echo run after_bundlepode ser uma instrução para o usuário ou pode ser um trecho de código "comentado" que é muito perigoso para ser executado sem saber as consequências.

    Usando echoassim, é preciso saber o que o comando modificado faz e deve-se garantir que o comando modificado seja realmente seguro (possivelmente não seria se contivesse redirecionamentos e usá-lo em um pipeline não funcionasse, etc.)

    • 20

relate perguntas

  • FreeBSD's sh: funções de lista

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • o que grep -v grep faz

  • Como salvar um caminho com ~ em uma variável?

  • Existe um daemon syslog que implementa RFC 5848 "Signed Syslog Messages"?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve