Автореферат
Библиотека
Ссылки
Отчет о поиске
Роликовый спорт
Автобиография
Автореферат Библиотека Ссылки Отчет о поиске Роликовый спорт

Гошко Владислав Викторович

Донецкий национальный технический университет

Факультет: вычислительной техники и информатики

Специальность: экономическая кибернетика

Тема выпускной работы: Маркетинговый анализ средств защиты от спама

Руководитель: Костин Валерий Иванович

Гошко В.В.

Безопасность веб-сайта.


JavaScript

Начнем с того, что такое безопсность веб-сайта? А нужна ли она? В какой-то мере она нужна для любого сайта. К примеру, вам нужно защитить паролем какой-нибудь документ, а вы не знаете как. Для этого есть несколько способов защиты и вообще принципиальных методов. Конечно, все зависит от степени защищенности. Вот пример на JavaScript, с HTML формой:

Вот код:

<script language="JavaScript" type="text/javascript">
<!--
function access(login,password){
var login = login.value.toLowerCase();
var password = password.value;
var your_login = "admin";
var your_passw = "matrix";
var secret_page = "some.htm";
var error_page = "error.htm";
if((login == your_login) && (password == your_passw)){
document.location = secret_page;
}else{
document.location = error_page;
}
}
function clr(f1,f2){
f1.value = "";
f2.value = "";
}
//-->
</script>

Enter your login and password to access <b>secret page</b>...
<table cellpadding=0 cellspacing=0 border=0>
<tr><td>login :</td><td><input type=text id=login></td></tr>
<tr><td>password :</td><td><input type=password id=password></td></tr>
<tr><td>
<input type=button value=enter onClick="access(login,password)">
<input type=button value=reset onClick="clr(login,password)">
</td></tr>
</table>

Итак в этом коде мы видим две функции access и clr, конечно можно это было сделать формой, но это не принципиально. Аргументами функции access являются идентефикаторы полей логин, пароль соотвествено. С каким регистром будет логин не важно, так как использовалась функция toLowerCase(), которая меняет верхний регистр букв на нижний, а нижний так и остаётся (также есть функция toUpperCase() противоположная этой). Аргументами функции clr также являются два идентификатора полей, которые будут очищены при вызове этой функции. «Это все классно, но любой пользователь может просмотреть код этой страницы и найти там пароль и логин» - скажите вы, конечно, может я и не говорил что это самый безопасный способ это один из них ?. Можно код скрипта запрятать в файл, к примеру, вот так:

<script language=”JavaScript” type=”text/javascript” src=”script.js”>
</script>

Да и это также не безопасный способ, потому что обычного пользователя этим фактом можно сконфузить, но хоть немного разбирающегося в этом – НЕТ. Он просто напишет в браузере адрес страницы, на которой был скрипт, а потом название скрипта, при этом он либо загрузится в браузер или попросит сохраниться на жесткий диск. А потом этот пользователь посмотрит пароль, логин или уже сразу адрес «скрытой» странички, а если там будет не страничка, а просто выводимый текст, то найдет что ему нужно, вообщем получит все что ему надо. Этот метод будет полезен для скрытия какой-нибудь не особо важной информации. Есть и другой пример, тоже на JavaScript вместе с HTML:

<html>

<head>

<title>Password Creator v1.0</title>

</head>

<body>

<BODY>

<center><table border=1>
<tr><form name=members><td rowspan=4>
<select name=memlist size=10 onChange="showmem(this.form)">

<!-- Original: r3d_Dr4g0n -->
<!-- Web Site: not yet -->

<!-- "member name | password | destination pagename |" -->
<option selected value="John Smith|password|mainpage|">John Smith
<option value="Peter Jones|theirpwd|endpages|">Peter Jones
<option value="Sue Brown|asdfvcxz|nowheres|">Sue Brown
<option value="Sally West|zaqxswde|logintop|">Sally West
</select></td>
<td align=right>User:</td><td><input type=hidden value="0" name=entry>
<input type=text name=memname size=8 value=""></td></tr>
<tr><td align=right>Password:</td><td><input type=text name=password size=8 maxlength=8><font size="-1"><-- Must be exactly 8 characters</font></td></tr>
<tr><td align=right>Page Name:</td><td><input type=text name=pagename size=8 maxlength=8><b>.html</b><font size="-1"><-- Must be exactly 8 characters</font></td></tr>
<tr><td colspan=2 align=center>
<input type=button value="New User" onclick="addnew(this.form);">
<input type=button value="Delete User" onclick="delthis(this.form);">
<input type=button value="Update/Show Coding" onclick="update(this.form); create(this.form);"></td></tr>
<tr><td colspan=3 align=center>
<input type=text size=60 name=message value="Note: Password/Page Name must be exactly 8 letters! (a-z)">
<input type=hidden name=num value=1></td>
</form></tr>
</table>
<hr size=2 width=75%>
<form name=js><textarea cols=75 rows=10 name=scrpt wrap=virtual>
<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
var params=new Array(4);
var alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHI";
function check(form) {
which=form.memlist.selectedIndex;
choice = form.memlist.options[which].value+"|";
if (choice=="x|") {
alert("Please Select Your Name From The List");
return;
}
p=0;
for (i=0;i<3;i++) {
a=choice.indexOf("|",p);
params[i]=choice.substring(a,p);
p=a+1;
}
h1=makehash(form.pass.value,3);
h2=makehash(form.pass.value,10)+" ";
if (h1!=params[1]) {
alert("Incorrect Password!"); return; };
var page="";
for (var i=0;i<8;i++) {
letter=params[2].substring(i,i+1)
ul=letter.toUpperCase();
a=alpha.indexOf(ul,0);
a-=(h2.substring(i,i+1)*1);
if (a<0) a+=26;
page+=alpha.substring(a,a+1); };
top.location=page.toLowerCase()+".html";
}
function makehash(pw,mult) {
pass=pw.toUpperCase();
hash=0;
for (i=0;i<8;i++) {
letter=pass.substring(i,i+1);
c=alpha.indexOf(letter,0)+1;
hash=hash*mult+c;
}
return(hash);
}
// End -->
</script>
</textarea>
</form>
<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
var params=new Array(4);
var script=document.js.scrpt.value;
var alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHI";
showmem(document.members);
function showmem(form) {
document.members.num.value=document.members.memlist.length;
var which=form.memlist.selectedIndex;
splt(form.memlist[which].value);
form.entry.value=which+1;
for (i=2;i<5;i++) {
form.elements[i].value=params[i-2]; };
}
function splt(choice) {
p=0;
for (i=0;i<3;i++) {
a=choice.indexOf("|",p);
params[i]=choice.substring(a,p);
p=a+1;
}
}
function addnew(form) {
newmem=getfields(form);
var who=prompt("New User's Name:","");
form.memlist[form.memlist.length] = new Option(who, newmem, false, true);
if (navigator.appName=="Netscape") {
document.js.scrpt.value=script;
history.go(0);
}
else {
showmem(document.members);
}
}
function getfields(form) {
newmem="";
for (i=2;i<5;i++) {
newmem+=form.elements[i].value+"|"; };
for (i=3;i<5;i++) {
a=form.elements[i];
for (k=0;k<8;k++) {
}
}
return(newmem);
}
function delthis(form) {
if (confirm("Delete "+form.memname.value+"?")) {
form.memlist.options[form.entry.value-1]=null;
form.message.value=form.memname.value+" Deleted";
form.memlist.selectedIndex=0;
if (navigator.appName=="Netscape") {
document.js.scrpt.value=script;
history.go(0);
}
else {
showmem(document.members);
}
}
}
function update(form) {
msg="no";
a=form.elements[i];
for (k=0;k<8;k++) {
b=a.value.substring(k,k+1);
c=b.toUpperCase();
form.memlist[form.entry.value-1].value=getfields(form);
form.message.value=form.memname.value+"'s record was updated";
}
}
function create(form) {

var html="<center><form name=login>\n";
html+="<table border=1 cellpadding=3>\n\n";
html+="<!-- Original: r3d_Dr4g0n -->\n";
html+="<!-- Web Site: not yet -->\n";
html+='<tr><td colspan=2 align=center><font size="+2">';
html+='<b>Members-Only Area!</b></font></td></tr>\n';
html+="<tr><td>Username:</td><td><select name=memlist>\n<option value='x'>";
for (j=0;j<form.memlist.length;j++) {
splt(form.memlist.options[j].value);
h1=makehash(params[1],3);
h2=makehash(params[1],10)+" ";
var page="";
for (var i=0;i<8;i++) {
letter=params[2].substring(i,i+1);
ul=letter.toUpperCase();
a=alpha.indexOf(ul,0);
a+=(h2.substring(i,i+1)*1);
page+=alpha.substring(a,a+1);
}
html+="\n<option value='"+params[0]+"|"+h1+"|"+page+"'>"+params[0];
};
html+="\n</select></td></tr>\n";
html+="<tr><td>Password:</td><td><input type=password size=10 maxlength=8 name=pass></td></tr>\n";
html+='<tr><td colspan=2 align=center><input type=button value="Login" onclick="check(this.form)"></td>\n';
html+="</tr>\n</table>\n</form>\n";
document.js.scrpt.value=html+script+"</center>";
}
function makehash(pw,mult) {
pass=pw.toUpperCase();
hash=0;
for (i=0;i<8;i++) {
letter=pass.substring(i,i+1);
c=alpha.indexOf(letter,0)+1;
hash=hash*mult+c;
}
return(hash);
}
// End -->
</script>
</center>

</body>

</html>

Изначально это просто HTML страница, содержащая текстовое поле с последующей генерацией скрипта защиты страницы.

Смысл сгенерированого скрипта в том чтобы как можно сильнее запутать пользователя, на тот случай если он откроет сам код HTML’а и попытается разобраться или найти скрытый документ. Это будет сложнее, чем в предыдущем методе, но все-таки, если захотеть можно и «полететь» ?. Этот скрипт при правильном пароле переходит на скрытую страницу, что делает это не безопасным т.к. адрес сохраняется в истории браузера. К примеру, вы пришли в интернет кафе, открываете свой сайт, вводите свой пароль, переходите на свою скрытую страницу, что-то делаете, встаете и уходите. А потом какой-нибудь «хакер» приходит открывает историю браузера по поиску, находит все ссылки связанные с вашим адресом страницы и находит адрес скрытой страницы. Конечно, перед уходом можно очистить историю. А если вы забудите очистить? Всё... скрытая страница становится нескрытой. Эти методы тоже в какой-то степени не безопасные, но, как я уже говорил выше, всё зависит от степени безопасности.

Эти методы были на JavaScript’е, я думаю, на этом с JavaScript закончим и перейдем к Perl’у.


Perl

Perl – Practical Extraction and Report Language. Язык программирования Perl появился 1987 году, когда Ларри Уоллу (Larry Wall) понадобился хороший инструмент для выполнения административных задач. Perl официально был объявлен как «Практический язык написания отчетов». Perl является очень гибким и мощным языком для выполнения многих задач, начиная с системного администриорования и заканчивая обеспечением интерактивного взаимодейсвия с посетителями ваших web-страниц.

Изначально Perl предназначался для выполнения задач по чтению данных из файлов, манипулированию данными и созданию отчетов на осонове имеющихся данных. Однако по происшествии многих лет и после нескольких доработок Perl был адаптирован для использования в Web в качестве языка программирования, используемого для создания приложений CGI (Common Gateway Interface – общий шлюзовый интерфейс). В результате этого стало возможным создание более сложных страниц для Web-узлов, поддерживающих интерактивное взаимодействие с пользователем. Perl может также применяться для выполнения задач по отображению текста на Web-страницах либо в целях получения информации от заказчика с последующей её отправкой по электроной почте. Вообще говоря, о возможностях этого языка можно говорить бесконечно.

Кто хочет немного больше узнать относительно внутреней структуры Perl, могут представлять его себе как результат скрещивания языков sed, awk, sh и C.

В отличие от C язык программирования Perl является интерпретируемым (хотя компиляторы существуют), поэтому при работе с ним не требуется выполнять компиляцию с целью создания пригодного для выполнения файла, содержащего машинный код. Программа на языке Perl представляет собой стандартный текстовый файл, который можно свободно загружать и редактировать. При этом программу не нужно компилировать и затем повторно компилировать всякий раз, когда выполняются какие-либо измнения. Это весьма полезное свойство позволяет ускорить процесс отладки.

А теперь пример защиты паролем какой-нибудь странички на вашем сайте:

1. #!/usr/bin/perl

2. #--- Simple Access Acceptor v1.0 Alpha
3. #--- by r3d_Dr4g0n
4. #--- for all bugz
5. #--- mailto : r3d_drag0n@ukr.net

6. use CGI qw(:standart);
7. use CGI::Carp qw(fatalsToBrowser);

#--- your password and login
8. $admin_page = "/www/r3d_Dr4g0n/passwd.rsa";
9. $title_of_the_page = "This is access to admin page...";
10. $admin_login = "r3d_Dr4g0n";
11. $admin_passwd = "h4x0r";

#--- be careful with text below

12. $query = new CGI;
13. $login = $query->param("login");
14. $password = $query->param("password");

15. print $query->header();
16. print $query->start_html($title_of_the_page,"r3d_drag0n\@ukr.net"),
$query->h1($title_of_the_page);

17. if(($login eq $admin_login) and ($password eq $admin_passwd)){
18. open(SEC,"$admin_page") or die $!;
19. while(<SEC>){
#--- do something with $_
20. print;
}
21. close(SEC);
}
22. else{
23. print "Enter your login and password to access admin page !!!","<BR>",$query->start_form(),"login :",$query->textfield("login","your login",16,32),
"<BR>","password :",$query->textfield("password","your password",16,32),"<BR>",$query->submit(-value=>"access"),
$query->reset(-value=>"clear"),$query->end_form();
}

Чтобы хоть немножко разобраться в этом коде начнем по порядку. В Perl’е имеются переменные только трех типов (и это значительно отличает Perl от других языков программирования, в которых используются переменные многих типов):

  • Скалярная переменная
  • Массив
  • Ассоциативный массив

Скалярный тип данных является единственным типом, при использовании которого возможно присвоение переменой значений. Причем в качестве значения может фигурировать как целое число, так и набор символов. Скалярная переменная начинается с знака $, что позволяет отличить ее от других типов переменных, например от переменных массива. Переменной массива используется сивол @, а переменной ассоциативного массива (или хеша) – символ %. Так, а теперь разбор самого кода.

Строка 1 обязательна, но не обязательно, что именно такая. На каждом сервере или компьютере Perl может быть на разных дисках или в разных папках, эта папка типичная для многих серверов. Строки 2-5 это комментарии. Строка 6 подлключает стандартный модуль CGI (входящий в стандартную поставку Perl’а), а строка 7 подключает можуль CGI::Carp (тоже стандартный), он замещает warn и die, а также функции carp, croak и confess обычного модуля Carp более надежными и содержательными версиями. При этом данные по-прежнему отсылаются в журнал ошибок сервера. Строки 8-11 скалярные переменные, по названию которых можно догадаться, что они задают. Строка 12 присваевает переменной $query новый объект CGI (объектно-ориентированный метод программирования). Строки 13-14 идентификаторы полей login и password заданых в строке 23 методом textfield. Строка 15 строит текст заголовка. По умолчанию она генерирует заголовки для документов text/html, но вы можете изменить тип содержимого и передать другие необязательные параметры:

print $query->header(-TYPE =>”text/plain”,
-EXPIRES =>”now”);

Строка 16 выводит в браузер заголовок страницы (тег <title>) и заголовок первого уровня (тег <h1>) с названием страницы ($title_of_the_page). Строка 17 проверяет, правильно ли вы ввели пароль и логин если правильно, то открывает файл $admin_page, а если не открывается то вывведется ошибка что-то вроде: “no such file or directory” в HTML формате, а если бы я не использовал CGI::Carp то ошибка выввелась не в виде HTML, а формате text/plain. В строке 18 комманда open используется для открытия файла $admin_page, а имя SEC в качестве дескриптора этого файла. Также командой open можно создавать, дописывать файлы, например:

open(FILE,”>temp.txt”);
print FILE “this is temp file”;
close(FILE);

Таким образом, создастся файл temp.txt в директории скрипта.

Вот пример дописи в файл:

open(FILE,”>>temp.txt”);
print FILE “adding to file some strings…”;
close(FILE);

В строке 19 происходит чтение дескриптора SEC и выполнение цикла. Во время каждой итерации содержание текущей строки файла сохраняется в специальной переменной $_. Если применить комманду print без аргументов, просто выводится содержимое переменной $_, т.е. текущая строка файла. Строки 22-23 выполняются по умолчанию (или если введен неправильный пароль и логин), т.е. выводится форма логин, пароль.

В этом примере используется форма с методом POST, что позволяет не показывать параметры формы в address bar браузера, а если бы использовался метод GET, то после нажатия кнопки access в address bar’е написалось следующее:

htpp://www.yoursite.com/cgi-bin/access.pl?login=r3d_Dr4g0n&password=h4x0r

Что опять же дает возможность залесть в историю браузера и все «вынюхать».

Поэтому этот способ можно считать почти безопасным. «Почему почти» - спросите вы, - «что еще может быть: в address bar’e ничего непоказывается, скрипт просмотреть нельзя, ну что еще???». А еще вот, что, если кому-нибудь очень уж захочется посмотреть вашу страницу это всё не очень просто, но теоритически возможно, на телефонной станции (или провайдере) полностью записать весь траффик. А там и посмотреть, тут уже ненадо будет даже смотреть пароль просто посмотреть, что вам возвращал сервер и все. Для этого придумали SSL (Secure Sockets Layer) - протокол защищенных сокетов. Протокол, гарантирующий безопасную передачу данных по сети, комбинирует криптографическую систему с открытым ключом и блочное шифрование данных. То есть это значит вы обмениваетесь с сервером открытыми ключами и все и узнать что вы посылали на сервер и что он возвращал нельзя будет никаким способом (если выполнены все предыдущие ?). И даже теперь я не могу сказать, что это самый безопасный способ. «Почему???» - спросите вы, да потому что все созданное человеком им же самим может быть разрушено…

И напоследок...

Поскольку любой сценарий, написанный на CGI позволяет внешнему пользователю запускать программы на недоступном ему компьютере, любая программа CGI представляет потенциальную угрозу для безопасности вашего узла. Поэтому несколько советов:

  • Проверяйте все, в том числе возвращаемые значения всех элементов формы, даже скрытые элементы и значения, сгенерированые кодом JavaScript. Многие наивно полагают, – раз они приказали JavaScript проверить значения полей формы перед отправкой данных, то значения действительно будут проверены. Ничего подобного! Пользователь может тривиально обойти ограничения – запретить JavaScript в своем браузере или сделать фальшивую форму или общаться на уровне HTTP без браузера.
  • Проверяйте значения, возвращаемые системными функциями
  • Никогда не запускайте скрипт со сменой прав, если только это не вызвано абсолютной необходимостью. Подумайте, не будет ли достаточно сменить идентификатор группы. Любой ценойизбегайте запуска с правами администратора. Если вам приходится использовать setuid или setgid, используйте командный интерпретатор, если только на вашей машине нельзя безопасно запускать сценарии Perl с setuid и вы точно знаете, что этьо такое.
  • Всегда шифруйте пароли, номера кредитных карт, номера соцмального страхования и все остальное, что обычно не печатается на первых страницах местных газет. При работе с такими данными слкдует использовать безопасный протокол SSL.

Почему Perl скрипт не работает???

Есть несколько частых причин:

  1. Права доступа к сценарию не установлены должным образом
  2. Файл или файлы сценария выгружены на сервер в двоичном формате вместо формата ASCII
  3. Неправильно задано местоположение Perl (#!/usr/bin/perl)
  4. Perl отсутствует на том компьютере, где выполняется сценарий, или же имеющаяся его версия устарела.
  5. Не был установлен заголовок HTML документа (print “Content-type: text/html\n\n” или print $query->header())
  6. В сценарии имеется ошибка, попробуйте попыйтесь выполнить сценарий в режиме командной строки для обнаружения и устранения ошибок

Советы

Чтобы быстрее научиться программировать на Perl’е я советую поставить у себя Perl под Win32, какой-нибудь сервер и, конечно же, Perl редактор.

  • Perl под Win32:
  • ActivePerl является самым последним двоичным дистрибутивом Perl от ActiveState и заменяет собой программное обеспечение, которое ранее распространялось как Perl для Win32. Новейшая версия ActivePerl, занимает где-то 8 Mb, так же как и другие инструменты, имеющие отношение к Perl, доступна на Web-узле компании ActiveState по адресу http://www.ActiveState.com.
  • Сервера:
  • Вообще-то их очень много всяких разных, хороших и плохих, но мне приглянулся Small_HTTP_SERVER написанный нашим соотечественником Максимом Феоктистовым. Он маленького размера (70-100 Kb) и очень легко настраивается, правда бесплатно работает только 21 день. Последнюю версию можно скачать на http://srv.mf.inc.ru/news.htm
  • Perl редакторы:
  • Из всех повидавших мною редакторов я выделил только два:
    Perl Builder (http://www.solutionsoft.com)
    DzSoft Perl Editor (http://www.dzsoft.com)

    Ну вот и все, выбирайте любые скрипты защиты ваших страниц.

    Удачи.