Já vi essa pergunta e agora sei como passar variáveis de shell corretamente para o awk.
Entretanto, notei um comportamento curioso em minhas tentativas incorretas iniciais:
ip=10.170.115.13
echo $ip
10.170.115.13
echo foo | awk "{print ${ip} }"
10.170.1150.13
Observe o 0 extra na saída acima.
Esse é um comportamento indefinido ou há uma razão lógica para o 0 aparecer onde aparece?
Aqui está minha versão awk:
awk --version
awk version 20200816
Isso também acontece com gawk
:
gawk --version
GNU Awk 5.3.1, API 4.0, (GNU MPFR 4.2.1, GNU MP 6.3.0)
Copyright (C) 1989, 1991-2024 Free Software Foundation.
Quando a variável é substituída no script, parece que
Como não há aspas em torno do IP,
awk
tenta analisá-lo como números, não como uma string.Acho que na verdade está sendo analisado como 3 números:
10.170
,.115
, e.13
. O 0 extra vem do formato padrão para imprimir números de ponto flutuante, que sempre inclui um dígito antes do ponto decimal;.13
é impresso como0.13
..115
também se torna0.115
, mas não obtemos um zero extra ali porque10.170
se torna10.17
(já que os zeros à direita após o decimal são descartados).A solução correta é usar a
-v
opção para converter a variável shell em umaawk
variável. Para consertar isso com seu método de substituição de variáveis, você precisa adicionar aspas literais para que seja analisado como uma string.Isso não tem nada a ver com a injeção em si, observe que
dá saída
Observe que isso também acontecerá para 3 pontos
dá saída
Eu suspeito que o tokenizer GNU
AWK
detecta 2 números, pois10.171.115
é10.171
e.115
(certa maneira de escrever 0,115) e então os normaliza (vejaOFMT
) e então os concatena como uma string vazia é tratada como um operador de concatenação (por exemplo, como emprint $1$2
). Mais pesquisas sobre o tokenizer do GNUAWK
são necessárias para provar ou negar essa hipótese, mas eu não tenho conhecimento suficiente para fazer isso.