Представим, что у вас есть код:
Ничего экзотичного. Вариации такого кода могут встретиться где угодно. Смысл кода, надеюсь, ясен (я не имею в виду его практическую ценность).
Вы уже увидели ошибку? Если да, то дальше можно не читать.
А я, признаться, не сразу понял в чем дело( Вот наглядный пример:
Конечно, вы уже обратили внимание на последнюю попытку. И поняли, что произошло — внедрение регулярного выражения ведущего к раскрытию данных. Ошибка настолько же редкая, насколько интересная.
Дело в том, что переменные внутри регулярных выражений по умолчанию интерпретируются. Из-за этого можно внедрить такое выражение, которое будет матчить всегда.
Безопасный выход конечно же есть: метасимволы \Q и \E. \Q отключает интерпретирование метасиволов вплоть до \E (или до конца регулярного выражения, если \E опущен).
Возьмите за правило обрамлять переменные с непроверенными данными в \Q\E при подставновке в регулярки.
Практической ценности не несет в силу очень экзотических условий для выполнения. Просто интересно.
Представим, что по какой-то причине в скрипте оказалось строчка
Вот такие дела. Благо разработчики интерпретатора предвидели это: по умолчанию такие вещи не прокатывают. Но! Даже если
- chomp(my $input = <STDIN>);
- my $kinda_secret = get_data($input);
- if(defined $kinda_secret) {
- print 'Your secret is: ', $kinda_secret
- }
- else {
- print 'No soup for you'
- }
-
- sub get_data {
- my $input = shift;
- open my $fh, '<', 'data.file' or return;
- my $retval;
- while(<$fh>) {
- if(/^$input:(.+?)$/) {
- $retval = $1;
- last
- }
- }
- close $fh;
-
- $retval
- }
* This source code was highlighted with Source Code Highlighter.
Ничего экзотичного. Вариации такого кода могут встретиться где угодно. Смысл кода, надеюсь, ясен (я не имею в виду его практическую ценность).
Вы уже увидели ошибку? Если да, то дальше можно не читать.
А я, признаться, не сразу понял в чем дело( Вот наглядный пример:
ksurent@desktop:~> cat data.file password1:hello1 password2:hello2 ksurent@desktop:~> perl -l t.pl password1 Your secret is: hello1 ksurent@desktop:~> perl -l t.pl password No soup for you ksurent@desktop:~> perl -l t.pl .+ Your secret is: hello1 ksurent@desktop:~>
Конечно, вы уже обратили внимание на последнюю попытку. И поняли, что произошло — внедрение регулярного выражения ведущего к раскрытию данных. Ошибка настолько же редкая, насколько интересная.
Дело в том, что переменные внутри регулярных выражений по умолчанию интерпретируются. Из-за этого можно внедрить такое выражение, которое будет матчить всегда.
Безопасный выход конечно же есть: метасимволы \Q и \E. \Q отключает интерпретирование метасиволов вплоть до \E (или до конца регулярного выражения, если \E опущен).
Возьмите за правило обрамлять переменные с непроверенными данными в \Q\E при подставновке в регулярки.
Небольшое дополнение
Практической ценности не несет в силу очень экзотических условий для выполнения. Просто интересно.
Представим, что по какой-то причине в скрипте оказалось строчка
use re 'eval';. Ну мало ли, например, используются где-то сложные динамические регулярки. Это приведет аж к внедрению кода:
ksurent@desktop:~> perl -l t.pl (??{system'id'}) uid=1000(ksurent) gid=100(users) группы=16(dialout),33(video),100(users) uid=1000(ksurent) gid=100(users) группы=16(dialout),33(video),100(users) No soup for you ksurent@desktop:~>
Вот такие дела. Благо разработчики интерпретатора предвидели это: по умолчанию такие вещи не прокатывают. Но! Даже если
use re 'eval';в скрипте нет, то можно получить небольшой кусок кода, что тоже не сыграет разработчику на руку.
ksurent@desktop:~> perl -l t.pl (??{system'id'}) Eval-group not allowed at runtime, use re 'eval' in regex m/^(??{system'id'}):(.+?)$/ at t.pl line 15, <$fh> line 1. ksurent@desktop:~>