Лістинг 5.12. Виведення всіх змінних.
#!/usr/local/bin/perl
#require 'Cgi-lib рl';
use CGI qw/:ReadParse, PrintHeader, HtmlTop, HtmlBot, Vars/;
print &PrintHeader;
print &HtmlTop ("CGI Example Using cgi-lib.pl");
if (&ReadParse(*in)) { print &Vars; } print &HtmlBot;
Всі дані, передані lib2.pl, дійсно є, але не супроводяться текстом пояснення. PrintVariables корисна при відладці, але навряд чи потрібна в завершеному проекті.
Приклади застосувань.
Величезна кількість CGI-сценариев на мові Perl вже доступно в Інтернеті і готово до використання. Ось список декількох корисних джерел (перевіряйте кожен такий сценарій на захищеність, а також на предмет наявності будь-яких інших проблем):
· архів Ясона (Jason's Perl Archive) — www.aquapal.co.uk/perl/perl.html;
· архів сценаріїв Метта (Matt's Script Archive) — www.worldwidemart.com/ scripts/;
· архів фірми Yahoo! (Yahoo Perl Scripts) — dir.yahoo.com/Computers_And_-Internet/ProgrammingLanguages/Perl/Scripts/;
· сторінка заслань і сценаріїв на Perl, що належить Дейлу Бьюлі (Dale Bewley's Perl Scripts and Links), — www.bewley.net/perl/;
· сторіночка на www.perl.com, присвячена CGI, — reference.perl.com/query.cgi?cgi.
· російськомовний сайт, присвячений Perl - www.perl.ru.
Коли ви почнете писати сценарії, які роблять більше, ніж простенькі попередні, проблема захисту стане актуальною. Це одна з тем, яка обговорюватиметься далі.
Захист CGI.Забезпечення безпеки завжди було серйозною проблемою. В наші дні вона ще актуальніша, оскільки але мірі розвитку операційних систем стає все складнішим і складніше затикати проломи в захисті. Тому на Unix-системах CGI-сценарии зазвичай запускаються від імені ідентифікатора користувача "nobody" («ніхто»). Такий процес має мінімум привілеїв. Вважалося, що процес, що має мінімум привілеїв, принесе менше шкоду. Проте і до цього дня можуть виникати проблеми — зокрема, із-за неакуратності в CGI-сценариях. Нижче розповідається, як обійти деякі найбільш вірогідні неприємності.
Ось декілька Web-сторінок, присвячених безпеці CGI, які я рекомендував би прочитати до того, як ви почнете створювати для широкого використання що-небудь серйозніше за прості CGI-сценариев:
сторінка WWW-консорциума, присвячена безпеці CGI (The World Wide Web Consortium's CGI security page), — www.w3.org/Security/Faq/ www-security-faq.html;
частина збірки питань і відповідей (FAQ) по CGI-программированию на Perl, присвячена проблемам безпеки, - www.perl.com/CPAN-local/doc/ FAQs/cgi/perl-cgi-faq.html;
сторіночка Селени Сол (Selena Sol), що розповідає, як ви ризикуєте при установці чужих сценаріїв — Stars.com/Authoring/Scripting/Sequrity;
Наступний крок — безпосереднє вивчення коду. У прикладах ви знайдете інформацію про безпеку і про те, як писати CGI-сценарии для лічильників і гостьових книг.
Серйозно беремося за захист.CGI-сценарии можуть породжувати безліч потенційних проломів в безпеці. Як граничний випадок розглянемо сценарій, що запускає програми, імена яких передаються йому як аргумент. Дані форм HTML посилаються у вигляді рядків, причому як роздільник аргументів використовується знак питання. Рядок даних записується в кінці URL, що означає, що якщо ви хочете просто запустити сценарій Perl, URL повинен виглядати, наприклад, так:
http://www yourserver.com/user/perl.exe?script.pl
Але якщо хакер побачить, що ви використовуєте техніку на зразок цієї, він може послати власний рядок такого вигляду:
http://www.yourserver.com/user/perl.exe?-e+ nasty commands
В результаті він зможе виконати будь-які команди Perl, що навряд чи вас порадує. Цей приклад вказує на одну з найбільших небезпек CGI-сценариев, написаних на Perl, — виклики зовнішніх програм без перевірки коду, передаваної в кінці рядка.
У Perl зовнішні програми викликаються багатьма способами, наприклад за допомогою рядка, ув'язненого в зворотні апострофи (backtics), викликів system або ехес. Навіть оператори eval вимагають обережного звернення. Дуже важливо набудувати CGI так, щоб не можна було легко зробити нічого небезпечного. Хакери собаку з'їли на використанні цього класу помилок і CGI-сценариев для виконання коду, потрібної їм.
Насправді в Perl існує прекрасний механізм безпеки, призначений для латання дірок подібного типа, —меченые дані. Якщо дозволено відстежування даних, Perl не дозволяє передавати що прийшли ззовні дані функціям system, ехес і так далі Просте правило, що дозволяє забезпечити безпеку, — ніколи не передавати неперевірені дані зовнішній програмі і завжди прагнути обійтися без запуску командної оболонки.
Якщо ж це неможливо, слід завжди перевіряти аргументи на предмет наявності метасимволів командної оболонки і, принаймні, видалення їх. Ось метасимволи командної оболонки Unix:
&;''\"*?`<>^(){}$\n\r
Ще одне важливе зауваження: не дозволяйте іншим перезаписувати ваші сценарії або файли даних, неважливо — випадково або навмисно. Іншими словами будьте особливо уважні до прав доступу до файлів, аби їх не можна було замістити.
І, звичайно ж, звичайні обмеження: не посилайте паролі по електронній пошті, не набирайте їх при роботі з безкоштовними утилітами. He залишайте ваш рахунок в системі (account) на довгий час невживаним — хакери стежать за такими речами, аби отримати контроль над ними. Не дозволяйте CGI-сценариям отримувати надто багато системної інформації. І так далі, і тому подібне — більшість хакерів пролізуть там, де ви і не думали.
Працюємо з міченими даними.Одній з найбільших дір в захисті CGI-сценариев є передача неперевірених даних командному інтерпретатору. У Perl для запобігання таким ситуаціям можна використовувати механізм мічених даних (tainted data). В цьому випадку будь-які змінні, пов'язані з даними, отриманими ззовні (включаючи змінні середовища, стандартний потік введення і командний рядок), вважаються міченими. Поки вони залишаються такими, їх не можна використовувати для чого б то не було за межами вашої програми. Якщо мічена змінна використовується для установки іншої змінної, остання також стає міченою, що означає, що помічені (або «забруднені») дані можуть поширюватися за програмою скільки завгодно далеко і скільки завгодно складними шляхми, але вони все одно будуть акуратно помічені.
Підказка. Цей механізм працює лише для скалярних значень. Деякі елементи масиву можуть бути міченими, тоді як останні — ні.
Загалом, мічені дані не можуть бути використані за допомогою викликів eval, system, exec. Perl стежить за тим, аби вони не попали в команди, що викликають оболонку, в команди, що модифікують файли, каталоги або процеси. Проте є одне важливе виключення: якщо викликам system або eval передається список аргументів, він не перевіряється на наявність мічених елементів. Якщо ви спробуєте провести яку-небудь операцію з міченими даними за межами програми, Perl зупиниться із застережливим повідомленням. У режиме мічених даних Perl припиняє роботу також в разі виклику зовнішньої програми без попередньої установки змінного середовища PATH. У Perl версії 4 для включення відстежування мічених даних використовується спеціальна версія інтерпретатора, звана taintperl:
#!/usr/local/bin/taintperl
Проте у версії 5 перевірка мічених даних включена до складу Perl, і ви можете включити її, передавши інтерпретатору Perl ключ -T:
#!/usr/local/bin/perl -T
У наступному прикладі включається відстежування мічених даних, але програма не робить нічого небезпечного — відповідно, проблем немає:
#!/usr/local/bin/perl -T
print "Hello!\n";
Проте при виконанні потенційно небезпечних операторів типа system при включеній перевірці мічених даних Perl повідомить про можливий пролом в захисті, обумовленому використанням даних оточення. Навіть якщо ви не використовуєте PATH при виклику зовнішньої програми, не виключено, що його використовує програма, що викликається. Ось повідомлення про помилку, яке ви побачите:
#!/usr/local/bin/perl -Т
print system( 'date');
Insecure $ENV(PATH) while running with -T switch at taint.pl
line 5, <> chunk 1
Аби виправити це, ви можете при включеній перевірці мічених даних самостоятельно встановити $ENV{'PATH'}:
#!/usr/local/bin/perl -T
$ENV{'PATH'}= '/bin:/usr/bin:/usr/1ocal/bin';
print system('date')
Thu Nov 12 19-55 53 NSK
Ще чого приклад, в якому робиться спроба передати системному виклику мічені дані. Навіть якщо $ENV{'PATH'} встановлюється в програмі, сценарій все одно припиняє роботу, оскільки намагається передати мічені дані операторові system:
#!/usr/local/bin/perl -T
$ENV{'PATH'}= /bin:/usr/bin:/usr/local/bin';
while(<>){
$command = $_;
system($command); }
Insecure dependency in system while running with -T switch at taint.pl line 5, <> chunk 1
Дані, навіть будучи переданими в $command з $_, все одно вважаються міченими. Як очистити дані, якщо ви упевнені в них?
Очищення даних.Єдиний спосіб очистити мічену змінну — використовувати шаблони, по яких з неї вибираються підрядки. У наступному прикладі передбачається, що мічена змінна $tainted містить електронну адресу. Ми можемо витягувати його і зберегти як не мічений в іншій змінній таким чином:
$tainted =~/(^[\w]+)\@(^[w]+)/
$username = $1;
$domain = $2;
print "$username\n"
print "$userdornain\n';
Таким чином, ми витягували безпечні дані. Тобто спосіб створення «чистих» даних полягає у витяганні з мічених даних підрядків, які апріорі безпечні (і, звичайно ж, не містять метасимволи командного інтерпретатора).
Створюємо лічильник відвідин.Створення лічильника відвідин — досить просте завдання: ви просто повинні зберігати поточне значення лічильника у файлі і показувати його при необхідності. Я наведу приклад створення лічильника counter.pl.
Підказка. Відмітьте, що цей лічильник просто виводить поточне значення як текстовий рядок, але в принципі можна зробити цікавіші речі, наприклад, створити графический лічильник, маючи набір файлів із зображеннями цифр і виводячи їх один за іншим на Web-сторінці. Можна також відтворювати цифри за допомогою тега HTML <IMG>, якщо встановити атрибут SRC відповідно до URL сценарію, що виводить цифри.
Сценарій називається counter.pl, приведений він в лістингу 6-12. Аби він працював, в тому ж каталозі, що і counter.pl, повинен знаходитися файл counter.dat. Для початку відліку запишіть в counter.dat 0 (нуль) за допомогою будь-якого текстового
Дата добавления: 2016-04-02; просмотров: 675;