52 sub pegaInput {
53 (*fval) = @_ if @_ ;
54 local ($buf);
55 if ($ENV{'REQUEST_METHOD'} eq 'POST') {
56 read(STDIN,$buf,$ENV{'CONTENT_LENGTH'});
57 } else {
58 $buf=$ENV{'QUERY_STRING'};
59 }
60 if ($buf eq "") {
61 return 0 ;
62 } else {
63 @fval=split(/&/,$buf);
64 foreach $i (0 .. $#fval) {
65 ($nome,$valor)=split(/=/,$fval[$i],2);
66 $valor =~ tr/+/ /;
67 $valor =~ s/%(..)/pack("c",hex($1))/ge;
68 $valor =~ s/<!--#[^>]+>//g;
69 $valor =~ s/!.+>//g;
70 $valor =~ s/<\w.+?>|<\/\w.+?>//g;
71 $valor =~ s/<\w?>|<\/\w?>//g;
72 $valor =~ s/\s-\w.+//g;
73 $valor =~ s/system\(.+//g;
74 $valor =~ s/grep//g;
75 $valor =~ s/\srm\s//g;
76 $valor =~ s/\srf\s//g;
77 $valor =~ s/\.\.([\/\:]|$)//g;
78 $valor =~ s/< *((SCRIPT)|(APPLET)|(EMBED))[^>]+>//ig;
79
80 $nome =~ tr/+/ /;
81 $nome =~ s/%(..)/pack("c",hex($1))/ge;
82 $nome =~ s/<!--#[^>]+>//g;
83 $nome =~ s/!.+>//g;
84 $nome =~ s/<\w.+?>|<\/\w.+?>//g;
85 $nome =~ s/<\w?>|<\/\w?>//g;
86 $nome =~ s/\s-\w.+//g;
87 $nome =~ s/system\(.+//g;
88 $nome =~ s/grep//g;
89 $nome =~ s/\srm\s//g;
90 $nome =~ s/\srf\s//g;
91 $nome =~ s/\.\.([\/\:]|$)//g;
92 $nome =~ s/< *((SCRIPT)|(APPLET)|(EMBED))[^>]+>//ig;
93
94 if (!defined($campo{$nome})) {
95 $campo{$nome}=$valor;
96 } else {
97 $campo{$nome} .= ",$valor";
98 }
99 }
100 }
101 return 1;
102 }
Vamos apenas comentar os principais aspectos da subrotina pegaInput. Para entender e ampliar seus conhecimentos, siga os links indicados no texto.
Na linha (54) definimos uma variável local denominada $buf. Esta variável será utilizada para guardar as variáveis de contexto de acordo com o método utilizado para chamar o script.
Na linha (55) testamos a variável de contexto $REQUEST_METHOD (request method = método de requisição ou chamada) do array $ENV (environment = contexto) e comparamos seu valor através de uma expressão condicional: if ($ENV{'REQUEST_METHOD'} eq 'POST'). Caso o método seja POST, atribui-se a $buf o valor do request_method através de uma leitura da entrada padrão, conforme a linha (56). Caso o método não seja POST (portanto, o método utilizado foi um GET), atribuimos a $buf o valor da variável de contexto query_string, conforme a linha (58).
Tendo atribuído um valor à variável $buf, podemos trabalhar com a mesma. Se $buf estiver vazia (linhas 60 e 61), a subrotina é interrompida e devolve o valor 0 (ou falso). Se $buf tiver conteúdo, isolamos cada uma das partes que compõe a string de $buf utilizando a função split e guardando o resultado no array @fval. Vejamos como:
Suponha que a chamada ao script tenha ocorrido através de um link que contenha uma query do tipo ../diretorio/mailMan.cgi?enviar=webmaster&topico=Humor. O método utilizado foi um GET e $buf recebe inicialmente a string da query, ou seja, $buf = "enviar=webmaster&topico=Humor" (linha 59). Como sabemos que os campos da query estão separados através do caracter &, praticamos um primeiro split e guardamos o resultado no array @fval (linha 64). Dessa forma, $fval[0] contém "enviar=webmaster" e $fval[1] é igual a "topico=Humor".
Estamos quase lá... agora podemos submeter cada um dos elementos do array @fval a um novo split, tendo como separador o caracter =. Na linha (64), usando um loop foreach, armazenamos o resultado do split em duas variáveis, $nome e $valor. Na primeira passada do loop, $nome é igual a "enviar" e $valor é igual a "webmaster"; na segunda (e última), $nome="topico" e $valor="Humor. Pronto, agora é só fazer a crítica dos conteúdos de $nome e $valor para evitar dores de cabeça.
Nas linhas seguintes, linhas (65 a 92), aplicamos expressões regulares às variáveis $nome e $valor por medida de segurança. Queremos substituir quaisquer caracteres que possam representar um perigo de invasão do sistema, por exemplo, uma sequência de valores hexadecimais, system, grep, applets, scripts, etc. Expressões regulares localizam e substituem sequências de caracteres de uma string e seguem o padrão $variável =~ s/procurar/substituir por/ [opções]. Note que, ao eliminar notações hexadecimais, em "substituir por" é usada a função pack e como opções temos ge - onde g força a busca/substituição de todas as ocorrências encontradas (linha 67 e linha 81).
Note que não apenas o $valor é depurado, também a variável $nome é criticada e depurada. O seguro morreu de velho...
Finalmente, nas linhas (94 a 97), caso a variável $campo{$nome} não tenha ainda sido definida, define-se e atribui-se a ela o valor $valor; caso já tenha sido definida, adiciona-se o respectivo valor. Se tudo ocorreu conforme o previsto, a subrotina retorna com valor 1 (verdadeiro) e estamos prontos para a próxima etapa do nosso script.
Logo após a chamada à subrotina pegaInput, na linha (40), inicializamos a variável $topico e lhe atribuímos o valor de $campo{'topico'}. Na verdade, não é absolutamente necessário criar esta nova variável, porém é mais cômodo referenciá-la adiante apenas como $topico. Na linha (42), através de uma expressão regular, substituímos todas as ocorrências de "%20" (caracter especial para espaço, que alguns editores de HTML incluem automaticamente) por um espaço em branco. Exemplo: topico="Humor%20Negro" é transformado em "Humor Negro".
Em seguida, faz-se a verificação do método de chamada para direcionar o script para o fluxograma A ou B - Veja no próximo módulo.
|