Термінова допомога студентам
Дипломи, курсові, реферати, контрольні...

Безпечне програмування на Perl

РефератДопомога в написанніДізнатися вартістьмоєї роботи

Часто завдання скрипта CGI на Perl полягає у отриманні від користувача списку ключових слів і видів використання в операціях пошуку по масці перебування які збігаються імен файлів (чи чого — нибудь іншим). Саме собою це небезпечно. Небезпечна оптимізація, яку окремі програми Perl використовують із прискорення пошуку. З використанням перемінної в операції пошуку, вираз компілюється всякий раз і… Читати ще >

Безпечне програмування на Perl (реферат, курсова, диплом, контрольна)

Безопасное програмування на Perl

Дмитрий Громов.

Как уникнути передачі користувальних змінних оболонці ОС при виклик exec () і system ()?

В Perl ви можете запускати зовнішні програми різними шляхами. Можете перехоплювати висновок зовнішніх програм, використовуючи зворотні кавычки:

$date = `/bin/date`;

Вы можете відкривати «тунель «(pipe) до программе:

open (SORT, «| /usr/bin/sort | /usr/bin/uniq »);

Вы можете запускати зовнішні програми розвитку й чекати закінчення їх виконання через system ():

system «/usr/bin/sort < foo. in » ;

или ви можете запускати зовнішні програми без повернення управління з допомогою exec ():

exec «/usr/bin/sort < foo. in » ;

Все ці висловлювання є небезпечними якщо користуються дані, запроваджені користувачем, які можуть містити метасимволы. Для system () і exec () існує синтаксична можливість, що дозволяє запускати зовнішні програми безпосередньо, без звернення до оболонки ОС. Якщо ви хоч передаєте зовнішньої програмі аргументи, які становлять не рядок, а список, то Perl нічого очікувати використовувати оболонку, і метасимволы не викличуть небажаних побічних ефектів. Например:

system «/usr/bin/sort », «foo.in » ;

Вы можете використати цю особливість у тому, щоб відкрити тунель, не звертаючись до оболонки ОС. Викликаючи open в магічною послідовності символів |-, ви запускаєте копію Perl і відкриваєте тунель (pipe) до цієї копії. Дочірня копія Perl потім негайно запускае зовнішню програму, використовуючи список аргументів для exec ().

open (SORT, «|- «) || exec «/usr/bin/sort » ,$uservariable;

while $line (@lines) {.

print SORT $line, «n » ;

}.

close SORT;

Для читання з тунелю без звернення до оболонки можна використовувати схожий спосіб, з послідовністю -|:

open (GREP, «-| «) || exec «/usr/bin/grep » ,$userpattern,$filename;

while () {.

print «match: $_ «;

}.

close GREP;

Это ті форми open (), які потрібно завжди залучити до випадках, як у іншій ситуації ви використовували б перенапрямок open (piped open).

Еще більш хитра можливість дозволяє вам запускати зовнішні програми розвитку й обманювати їх щодо свого назви. Це під час використання програм, дії яких залежить від того, з допомогою якого імені вони запущены.

Вот синтакс:

system $настоящее_имя «ложное_имя », «аргумент1 », «аргумент2 «.

Например:

$shell = «/bin/sh «.

system $shell «-sh », «-norc «.

Этот приклад запускає sh — оболонку ОС — безпосередньо з ім'ям «-sh », який змушує її діяти інтерактивно. Заметте, що ця ім'я програми має зберігатися як перемінної, І що між ім'ям перемінної та початком списку аргументів немає запятой.

Можно записати цю команду більш компактно:

system { «/bin/sh «} «-sh », «-norc «.

Что таке «перевірки зарізниці «(taint checks) в Perl? Як кажуть їхні включить?

Как ми бачили, одне з найчастіше трапляються проблеми з безпекою при програмуванні CGI — передача оболонці ОС користувальних змінних і їх перевірки. Perl пропонує механізм перевірки «зарізниці «, який дозволяє цього. Будь-яка змінна, яка проинициирована даними за межами програми (включаючи дані з середовища, стандартного введення й посилення командної рядки) сприймається як «заразна », не може бути більш використана поза програми. Зараза може поширюватися. Якщо вже ви використовуєте заражену зміну для присвоєння значення інший перемінної, друга змінна також виявляється заражене. Заражені перемінні неможливо знайти використовуватимуться виклику eval (), system (), exec () чи piped open (). Якщо ви і спробуєте це, Perl перестає працювати і виводить попередження. Perl також відмовиться працювати, коли ви спробуєте викликати зовнішню програму, не встановивши явно значення перемінної PATH.

В версії 4 мови Perl перевірка включається під час використання спеціальної версії інтерпретатора, яка називається «taintperl » :

#!/usr/local/bin/taintperl.

В версії 5 — використовуйте прапорT під час запуску интерпретатора:

#!/usr/local/bin/perlT.

Ниже описано як «знезаражувати «(untaint) переменные.

Для повнішого обговорення питання можна до CGI/Perl Taint Mode FAQ (автор — Gunther Birzniek).

OK, я включив перевірку зарізниці, як ви вже рекомендували. Тепер мій скрипт перестає працювати з повідомленням «Insecure $ENV{PATH} at line XX «при кожному запуске!

Даже коли ви не довіряєте перемінної PATH під час запуску зовнішніх програм, існує можливість, що це робить зовнішня програма. Тому треба завжди включати таку рядок на початку вашого скрипта, коли ви використовуєте taint checks:

$ENV{ «PATH «} = «/bin:/usr/bin:/usr/local/bin » ;

Отредактируйте її те щоб перерахувати директорії, які ви хочете шукати. Думка про вклюяении поточного директорія («. ») у складі перемінної PATH є поганий идеей.

Как «знезаразити (untaint) переменную?

После того, як змінна заражене, Perl дасть вам можливості використовувати їх у функціях system (), exec (), piped open, eval (), зворотних лапках, або будь-якої функції, які впливають щось поза програми (наприклад — unlink). Ви можете цього навіть коли ви перевірили зміну утримання метасимволов чи використовували команду tr/// чи p. s/// видалення метасимволов. Єдиний спосіб знезаразити зміну — використовувати операцію пошуку по масці і вилучення збігається подстроки. Наприклад, якщо змінна повинна містити адресу електронної пошти, то витягти знезаражену копію адреси можна наступним образом:

$mail_address=~/(w[w-.]*)@([w-.]+)/;

$untainted_address = «$ 1@$ 2 » ;

Такая маска дозволить виділити адресу у вигляді «кому@куда », де елементи «кому «і «куди «можуть включати літери, крапки й тирі. Більше того, «кому «неспроможна починатися з тирі, використовуваного у багатьох програмах як службовий символ командної строки.

Я видаляю метасимволы з перемінної, але Perl продовжує думати, що вона заражена!

Смотри вище у відповідь це запитання. Єдиний спосіб знезаразити зміну — застосувати пошук по маске.

Действительно чи небезпечна операція пошуку $foo=~/$user_variable/?

Часто завдання скрипта CGI на Perl полягає у отриманні від користувача списку ключових слів і видів використання в операціях пошуку по масці перебування які збігаються імен файлів (чи чого — нибудь іншим). Саме собою це небезпечно. Небезпечна оптимізація, яку окремі програми Perl використовують із прискорення пошуку. З використанням перемінної в операції пошуку, вираз компілюється всякий раз і під час операції. Для запобігання перекомпилирования, що посідає час, можна використовувати спеціальний прапор — o, що сприятиме з того що вираз буде откомпилировано лише однажды:

foreach (@files) {.

m/$user_pattern/o;

}.

Теперь, проте, Perl ігноруватиме будь-які зміни у перемінної, що сприятиме неправильної роботі циклів такого рода:

foreach $user_pattern (@user_patterns) {.

foreach (@files) {.

print if m/$user_pattern/o;

}.

}.

Для обходу цієї проблеми програмісти, пишучі на Perl, часто використовують такий трюк:

foreach $user_pattern (@user_patterns) {.

eval «foreach (@files) { print if m/$user_pattern/o; } «;

}.

Проблема полягає у цьому, що у операторі eval () використовується користувальницька змінна. Якщо змінна не піддається ретельної перевірці, можна змусити eval () виконати довільний код на Perl. Щоб зрозуміти, ніж це загрожує, подумайте, що буде у разі, якщо змінна матиме таке значення: «/; system «rm * »; / «.

Проверки зарізниці (див. вище) дозволяють впіймати би потенційно небезпечним у цій галузі. Можете вибирати між відмовою від таких оптимізації, чи ретельним знезараженням перемінної перед використанням. Корисна можливість у Perl5 полягає у використанні Q і E для коментування метасимволов те щоб вони були использованы:

print if m/Q$user_patternE/o;

Мой скрипт CGI вимагає великі привелегии, що вона отримує як користувач nobody. Як мені змінити ідентифікатор пользователя?

Прежде всього, справді необхідно? Надання великих прав збільшує ризик та дозволяє взломанному скрипту завдати більше шкоди. Коли хочете надати скрипту права користувача root, то спочатку ДУЖЕ добре подумайте.

Вы можете змусити скрипт виконуватися з правами його власника шляхом установки біта s:

chmod u+s foo.pl.

Вы можете надати їй права групи, до якої підключено власник, встановивши біт p. s на полі группы:

chmod g+s foo.pl.

Однако, багато системи Unix містять лазівку, що дозволить зламувати такі скрипти. Це стосується лише скриптов, а чи не компилированных програм. У цих системах спроба запуску скрипта на Perl, котрій виставили p. s біти, призведе до появи повідомлення про помилку з боку самої Perl.

На таких системах у вас є дві возможности:

Можно виправити ядро те щоб заборонити установку цих бітов для файлів скриптов. Perl тим щонайменше буде правильно визначати ці битки, і встановлювати ідентифікатор користувача. Детальну інформацію це можна знайти у Perl faq:

internet.

Вы можете помістити скрипт в оболонку, напмсанную на З. Зазвичай це відбувається так:

#include.

void main () {.

execl («/usr/local/bin/perl », «foo.pl », «/local/web/cgi-bin/foo.pl », NULL);

}.

После компілювання програми, выставте p. s біти. Програма виконуватиметься з правами власника, запускати інтерпретатор Perl і виконувати скрипт, що міститься у файлі «foo.pl » .

Кроме того, можна запускати сам сервер з правами користувача, достатніми для виконання необхідних дій. Якщо вже ви використовуєте сервер CERN, те в них є можливість запускати сервер з різними правами до різних скриптов. Див. документацію CERN щоб одержати подальшої информации.

Список литературы

Для підготовки даної праці були використані матеріали із сайту internet.

Показати весь текст
Заповнити форму поточною роботою