WebScript.Ru
C:\   главная  ::   о сайте  ::  каталог скриптов  ::  гнездо  ::  форум  ::   авторам  :: Новостройки ::   ХОСТИНГ  ::

|| разделы::
|| поиск по сайту::

|| реклама::
|| новости почтой::
Рассылки Subscribe.Ru ::



Новости сайта WebScript.Ru
Популярные статьи

Hot 5 Stories

|| рекомендуем::




AntiSpam: Прячем Емайлы


Прислал: Роман Юрьев [ 13.08.2004 @ 12:41 ]
Раздел:: [ Веб-технологии ]


Здравствуйте уважаемые читатели. Технологии защиты email адресов на сайтах обсуждают достаточно давно. Web-разработчики постоянно изобретают механизмы сокрытия электронных адресов, или значительного усложнения процесса их автоматического сбора. Понятно, что единого и универсального решения, которое устраивало бы и разработчиков и посетителей сайтов не существует. Те что есть, широко используются, но со временем устаревают. Злодеи-спамеры находят пути решения или обхода применяющихся технологий. То решение, которое я хочу вынести на ваш суд, не является универсальным и абсолютным . Но применяя его сейчас, можно еще какое-то время успешно усложнять жизнь тем, кто наживается на нашем времени и нервах, воруя и продавая базы с награбленными Емайл-базами.
К данному решению я пришел тогда, когда четко и ясно определил чего хочу я (как разработчик), чего хотят посетители моего сайта и чего ждут от моего сайта спаммеры. Чтобы вы с легкостью следовали за моими рассуждениями, буду писать так, как, когда-то, рассуждал сам.

Чего хотят разработчики:

  1. Незначительные требования кода к ресурсам сервера
  2. Легкость контроля и модернизации кода
  3. Небольшого количества кода
  4. Гарантия сокрытия ВСЕХ email адресов, которые могут находиться в тексте страниц сайта

Чего хотят рядовые посетители сайта:

  1. Возможность безбоязненно оставлять свои электронные адреса в различных разделах сайта
  2. Возможность работы с Email адресами других посетителей, так же как и обычно (доступ через один клик)

Чего хотят спаммеры:

  1. Наличия в исходном коде страницы электронных адресов, открытом виде.

При желании можно пополнить списки требований, но эти, на мой взгляд, являются основными. Наибольшая эффективность работы будет в том случае, если на сайте используется система шаблонов. Так как в этом случае можно скрывать адреса которые могут встретиться в теле страниц, например email администратора, владельца сайта и т.д.
Кратко о том, как это должно работать. У нас есть страницы сайта, статические (готовые) и динамические (формирующиеся в процессе запроса пользователя). При запросе статической страницы, мы должны обработать весь текст страницы, сделать необходимое преобразование встреченных емайл адресов, отдать текст в браузер. При формировании динамических страниц, мы можем преобразовывать встреченные емайл адреса прямо в процессе, а можем записать весь результат выполнения в переменную, обработать, а потом отдать в браузер.
Вас наверное уже давно мучает вопрос, что же я собираюсь преобразовывать? Поясню основной принцип сокрытия адресов. При нахождении в тексте страницы емайла, мы заменяем его на специальную ссылку. Пример:

Исходный текст:
... а вот мой ящик: superuser@downmail.ru Как приедешь назад, напиши мне как провел отпуск ...

Текст страницы после обработки:
... а вот мой ящик: <a href="./mailto.php?email=fhcrehfre@qbjaznvy.eh">email</a> Как приедешь назад, напиши мне как провел отпуск...

То есть, каждый найденный email мы шифруем, при этом шифр должно быстро и однозначно преобразовываться к исходному состоянию. Сложность алгоритма шифрования ограничен только интеллектуальными способностями разработчика ))) В принципе можно воспользоваться стандартной php функцией str_rot13(). Она просто сдвигает каждый символ в строке на 13 позиций, неалфавитные символы остаются без изменений. Единственный минус от ее повсеместного использования может заключаться в том, что зная что за преобразование используется на сайте можно легко его обойти. То есть спаммер соберет зашифрованные емайлы, а потом запустит простейший скрипт на PHP, который произведет обратное преобразование. Поэтому, если вам кажется, что данная функция не обеспечивает достаточного уровня защиты адресов, пишите свою. Но в нашем примере будет использоваться именно она.
Что же происходит дальше? А ничего сложного, Если пользователь захочет написать письмо своему знакомому, в своей любимой почтовой программе, то он инстинктивно "кликнет" на нашей ссылке email. Таким образом значение переменной email будет передано в скрипт mailto.php . В нем произойдет процесс обратного преобразования емайла, с помощью все той же функции str_rot13(). Далее в скрипте mailto.php происходит вызов функции Header("Location: mailto: ::."); Где после mailto: будет стоять тот самый адрес который и нужен посетителю. Получив этот заголовок, любой нормальный браузер передаст управление стандартной почтовой программе. В которой счастливый пользователь и напишет столь желанное письмо.
Если у вас осталось некоторое непонимание или возникли вопросы по реализации, то могу предложить вам рабочую версию примера. Конечно, он далек от того, чтобы его повсеместно использовать, так как я его намеренно упростил. Но он развеет все ваши остаточные неясности, и вы поймете, о чем это я так долго тут рассказываю.
    В примере есть три файла:
"    index.php
"    index.txt
"    mailto.php

index.php:


<?php
/*
    Основной скрипт, отображает содежимое файла index.txt, с заменой всех емайлов
*/

function hide_email($IN_TEXT) {
/*    Взрываем текст по пробелам, и результат будет в массиве $TEMP_ARR    */
    $TEMP_ARR = explode(" ",$IN_TEXT);
/*    Проходим в цикле по всему массиву (а получается что по всему тексту)    */
    for ($x=0; $x<sizeof($TEMP_ARR); $x++) {
/*        Ищем текст который очень похож на емайл    */
        if (preg_match("/^(.+)@(.+)\\.(.+)$/",$TEMP_ARR[$x])) {
/*            Меняем емайл на нашу ссылку, которая в качестве параметра передает результат работы функции move_string()    */
            $OUT_TEXT .= '<a href="./mailto.php?email='.str_rot13($TEMP_ARR[$x]).'" target="mailto_frame">email</a> ';
        }
/*            Оставляем все как есть, только добавляем пробел в конец     */
        else    $OUT_TEXT .= $TEMP_ARR[$x].' ';
    }
    return $OUT_TEXT;
}

$CONTENT_TEXT = file_get_contents('index.txt');
$CONTENT_TEXT = hide_email($CONTENT_TEXT);

?>
<html>
<title>Anti spam - Пример</title>
<body bgcolor="#ccccff">
<? echo $CONTENT_TEXT; ?>
<IFRAME NAME="mailto_frame" width="0" height="0"></IFRAME>
</body>
</html>


Функция hide_email() получает текст страницы. В результате ее работы возвращается тот же текст, но все емайл адреса заменены нашими ссылками. IFRAME в данном случае используется как цель для всех ссылок с емайлами. Это нужно для того чтобы не открывалось еще одно окно, из за функции Header(), при работе файла mailto.php

index.txt:


Текст содержащий электронные адреса. Текст user@coolmail.ru содержащий электронные адреса. <br>
Текст содержащий электронные адреса. Текст содержащий электронные адреса. lamer@fatbox.com <br>


В файле index.txt просто какой-то текст, который содержит адреса электронной почты.

mailto.php:


<?php
/*
    Обратное преобразование емайла, и отправка его браузеру
*/

if (isset($_GET['email'])) {
    Header("Location: mailto:".str_rot13($_GET['email']));
}
?>


В mailto.php приходит переменная $email, через GET запрос. Она содержит зашифрованный вариант адреса. Мы ее преобразуем в исходное состояние и отдаем браузеру.

В заключении хочу сказать, этот материал не содержит ничего существенно нового. Здесь описан метод который просто аккумулирует в себе достаточно простые и в тоже время действенные технологии сокрытия емайл адресов. Это конечно на мой взгляд. Буду рад если эта статья усложнит жизнь хоть на время, хоть одному спаммеру. Оказывается, что настоящая похоть пришла к нам еще с тех времен, которая исходила от ненасытных предков.




 :::::  Предводителев Сергей пишет 14.08.2004 @ 12:38 
Достаточно оригинальный способ :)
Идея классная.
 :::::  Kai пишет 15.08.2004 @ 01:11 
Способ оригинальный, но хотелось бы ещё увидеть то ЧЕМ можно заменить шифровальную функцию... ато ведь мы, программисты, в большенстве своём ленивые... :Р
 :::::  Роман Юрьев пишет 15.08.2004 @ 11:13 
Писать сложную и навороченную функцию маскировки емайлов, наверное нет смысла. Достаточно небольших преобразований. Если спаммер будет сам вручную заниматься разбором того или иного алгоритма шифрования, то это уже значительно повысит себестоимость собранных баз. Я вот набросал функцию которая, как мне кажется, может достаточно затруднить процесс сбора адресов. Идеально, если на сайтах не будут повторяться используемые методы шифрования. Вот один из вариантов замены функции str_rot13():

// Функция маскирует строку, путем манипуляций с составляющими её символами
function MoveString($InStr='',$Code=1) { // Code=1(Кодируем) Code=0(Раскодируем)
$Step = 4;
if (!$Code) $Step = -$Step;
// Сдвигаем на определенное число символов
for ($x=0; $x<strlen($InStr); $x++) $OutStr .= chr(ord($InStr[$x]) + $Step);
// Переворачиваем куски слова, по $ReverseStep символов
$ReverseStep = 3;
$count_all = strlen($OutStr);
for ($x=0; $x<$count_all; $x+=$ReverseStep) {
if ($x > $count_all) $ReverseStep = $x - $count_all;
for ($y=$ReverseStep-1; $y>=0; $y--) $OutStr1 .= $OutStr[$x+$y];
}
return $OutStr1;
}
 :::::  Eddy пишет 16.08.2004 @ 12:11 
Спамер может для расшифровки использовать саму функцию расшифровки - собрать зашифрованные ссылки, написать скрипт, который будет вызывать в цикле mailto.php и ловить расшифрованные адреса.
Так что надо еще дополнительно поставить защиту от слишком частых обращений к mailto.php
 :::::  Роман Юрьев пишет 16.08.2004 @ 13:07 
согласен, но в общем случае, ему неоткуда узнать что за функцию я использую. Ведь на реальном сайте я не буду использовать эти функции шифрования. А буду использовать другие, или измененные эти.
Насчет блокировки частых обращений, тоже согласен. А еще можно делать ловушки: сделать невидимую ссылку а-ля <a href="mailto_lock.php"></a> Обычный посетитель ее даже не увидит, а спамм-раббер или просто качалка, пойдет по ней так же как по обычной ссылке. А мы в этом скрипте просто баним всех кто туда обратился. хотя бы на время. А чтобы туда не попадали нормальные индексаторы каталого-поисковиков, запрещаем туда доступ в файле robots.txt Приличные роботы всегда туда заглядывают.
Еще можно выставлять Куки, и на каждой странице проверять их налицие, не все майл-грабберы могут эмулировать работу кук.
 :::::  Eddy пишет 16.08.2004 @ 15:21 
так ему и не нужно знать что за функцию вы используете для шифровки, ему достаточно знать что скрипт mailto.php расшифровывает мыло
 :::::  AliMamed пишет 18.08.2004 @ 00:21 
я не понял что мешает роботу пройти по этим ссылкам и получить заголовок с реальным адресом из файла mailto.php.
 :::::  Роман Юрьев пишет 18.08.2004 @ 07:51 
Если он умеет это делать, то ничего не мешает
 :::::  Бондарев Александр пишет 18.08.2004 @ 16:11 
Неужели, по-вашему, разработчики роботов-сборщиков адресов не учитывают заголовок Location:? Ведь по-любому они проходят по каждой ссылке... Если бы такого робота писал я, я бы делал это так:

1) брал бы адрес из базы не помеченный как проверенный и не начинающийся с mailto:;
если не получилось - stop!
2) Посылал бы HTTP запрос
3) если натыкался бы на Location:, забивал бы его в базу, иначе (если 200 Ok) - вырезал бы все ссылки, забивал бы их в ту же базу;
4) помечал бы адрес как проверенный;
5) goto 1;

Потом бы забирал из базы все ссылки, начинающиеся с mailto: и слал бы по ним спам.

И это, вроде, самый разумный алгоритм, и он учитывает ваш прием, причем специально для этого ничего не делается.

Я бы остановился все-таки на форме. Можно изменить mailto.php, чтобы он выводил форму для отправки сообщения. Вот тут уж бот ничего не поделает.
 :::::  Роман Юрьев пишет 19.08.2004 @ 06:24 
В итоге я тоже пришел к тому что в данном подходе надо менять содержимое файла mailto.php. Если он будет обеспечивать отправку писем через форму по адресу который на него передан в зашифрованном виде, то это действительно 100 процентная защита. Спаммеры - отдыхают.

А то что предложил я, тоже работает, но наверное только против начинающих спамеров ))) Мы нашли проги для сбора мыл, и натравили на сайт, где работали эти скрипты. Проги ничего не смогли собрать. Просто в них все ссылки используются для перехода, и не анализируется куда они ведут и что там в заголовках приходит. )))
 :::::  tristram пишет 30.08.2004 @ 23:27 
100% защита существует! просто поюзать gzip-сжатие паги, броузер автоматом декодит его, а вот скрипт который будет индексировать странички обломается и получит не понятные ему символы.
 :::::  Ant пишет 02.09.2004 @ 16:10 
100% способ в действительности не существует. И Gzip тут вообще не при чём (как я понимаю, браузер для того чтобы получить данные, которые сжаты с помощью Gzip-алгоритма, должен послать соответствующий заголовок серверу; а всегда отдавать данные в Gzip'е — это очень не вежливо — пользователь сам может этого не хотеть).

На Xpoint, например, есть очень хороший способ — выдавать картинки, на которых изображён адрес. Всё очень просто и красиво.
 :::::  ВикторСимон пишет 26.10.2004 @ 04:10 
Здравствуйте!
В первые учавствую в вашем разговоре...

Что касается защиты от спама - сразу пришла в голову программа, которую обойти вообще невозможно - спамеры обломаются.

На странице вставляем код: <a href="mail.php?mail=2&sub=mail_from_site_www.site.ru">пишите письма</a>

Создаем Файл mail.php
----------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head>
<META http-equiv=Content-Type content="text/html; charset=windows-1251">
</head><body>
<?
//Защита от спама - скрипт отправки почты, автор Симон Виктор (прямо сейчас и "накатал").
//В данном примере примитивная реализация для новичков, но при небольших требованиях сгодится,
//А при необходимости, не сложно использовать текстовую или (лучше) бинарную базу данных, а можно и базу MySql, хотя не советую, не для этого она предназначена.
//Если есть переменные mail и text - определяем кому отправлять письмо,
if(@!$from){$from="sender@adresa.net";}//если нет адреса, так и пишем адресату,
if(@!$sub){$sub="Нет темы";}//если нет темы письма, так и пишем адресату,
if(@$mail=="1" && @$text){//если mail равно 1 вызываем функцию outmail и передаем ей параметр mail@engend.net - как вы поняли, необходимый электронный адрес
outmail("mail@engend.net",$sub,$text,$from);//а так же передаем ей переменную sub в которой будет тема письма, text где будет текст письма и from - адрес отправителя.
}elseif(@$mail=="2" && @$text){//то же самое, только другое значение переменной mail и соответственно другой адрес получателя.
outmail("myadress@mail.ru",$sub,$text,$from);
}elseif(@$mail=="3" && @$text){//третий адрес (можно сделать хоть тысячу адресов, хотя тогда лучше использовать базу данных)
outmail("admin@site.ru",$sub,$text,$from);
}elseif(@$mail&&@!$text){//ВАЖНО, если указан адресат (если есть переменная mail) но нет текста (например при ссылке с сайта)
//Выводим форму, в которой можно написать текст, тему и адрес отправителя и отправить письмо
echo '
<form action="mail.php" method="post">
<input type="hidden" name="mail" value="1">
От кого письмо? <input type="text" name="from"><br>
Тема письма <input type="text" name="sub"><br>
<textarea name="text" cols="" rows="">
Здесь пишите текст письма
</textarea><br>
<input type="submit" value="Отправить письмо">
</form>
';
}else{
//если нет переменной mail (адресата)
//По желанию, например можно вывести сообщение об ошибке или вот такую форму:
echo '
<form action="mail.php" method="post">
Кому писать?<select name="mail">
<option value="1">Английская королева</option>
<option value="2">Ваш адресат</option>
<option value="3">Администрация сайта</option>
<!--ну и так далее, смысл вы поняли-->
</select><br>
От кого письмо? <input type="text" name="from"><br>
Тема письма <input type="text" name="sub"><br>
<textarea name="text" cols="" rows="">
Здесь пишите текст письма
</textarea><br>
<input type="submit" value="Отправить письмо">
</form>
';
}//А вот и функция outmail
function outmail($adr,$sub,$text,$from){//Получаем переменные - адрес,тема,текст_письма,от_кого_письмо.
$fr = 'From: '.$from.'
Content-type: text/plain; charset="windows-1251"';//устанавлеваем адрес отправителя и нормальную кодировку (у новичков масса приятных эмоций, когда их первый почтовый скрипт выдает им околесицу вместо текста).
mail ($adr,$sub,$text,$fr);//отправляем письмо стандартной функцией, думаю значение понятно.
echo 'Ваше сообщение отправлено';//надо объяснять смысл?
}
//Поскольку реальные почтовые адреса нигде не фигурируют в выводимом пользователю (или спамботу), невозможно их узнать.
//Простое и эффективное решение.
?>
</body></html>
-----------------------
Хочу предупредить, что этот код я только-что придумал, написал и не тестировал, но должно работать.

 :::::  Angel07 пишет 17.11.2004 @ 15:50 
Хорошее решение!
Адрес получателя вообще не фигурирует в открытых данных! И использовать почтовую форму понадобится только один раз - если получатель сочтет нужным ответить на письмо, то переписка пойдет обычным образом.

Единственный способ взломать эту защиту - подобрать FTP-пароль к сайту!
 :::::  Антон пишет 30.12.2004 @ 21:30 
Метод правильный, только реализация хромает. Нужно делать через JavaScript, тогда робот обломается, не имея встроенного интерпретатора JavaScript :) И всего делов.
 :::::  MortalMan пишет 06.02.2007 @ 14:25 
Предложеный автором вариант не очень хорош - если бот перейдет по адресу, за которым скрыт емайл, то он (бот) этот емайл и получит. Вариант, при котором емайл вообще скрыт - не очень. Во-первых, не всегда посетитель оставляет свой реальный емайл, а во-вторых посетитель должен видеть контактную информацию владельца ресурса, а не форму обратной связи, сообщение из которой может и не дойти до адресата. Есть еще один вариант - генерация и вывод емайла в виде рисунка, вот его сейчас я и использую...
 :::::  Дмитрий Рассанов пишет 27.10.2007 @ 05:35 
Виктор Симон предлагает по сути отправку писем через web форму.
Но что мешает спам-роботу использовать Вашу форму для рассылки спама?
Просто спам будет рассылаться через Ваш сайт, что не радует. Конечно можно в какой-то мере защитить и web форму, используя JavaScript и рисунки, но насколько мне известно - это слабая защита.
Вот способ, предлагаемый MortalMan - генерация емейла в виде рисунка, мне лично нравится гораздо больше.
Но мне кажется, что если на сайте будет много мейлов, то спамеры вскроют и это тоже.
К сожалению своего варианта защиты предложить не могу.
 :::::  max пишет 18.01.2008 @ 08:31 
<script>
function decode(code){
var request = new ActiveXObject("Microsoft.XMLHTTP");
request.open("GET", 'http://somesite/decode.php?'+code, false);
request.send();
dec=request.responseText;
return 'mailto:'+dec;
}
</script>
вы можете написать мне письмо <a name=VasyaPupkin: href=1 onmouseover=href=decode(name)>ПисьмоМне</a>
вы можете написать мне письмо <a name=PetyaShlupkin: href=1 onmouseover=href=decode(name)>ПисьмоМне</a>

функцию декодирования можно реализовать как на аяксе с обращением к серверу, так и на яваскрипте непосредственно исполняемому в браузере.
 :::::  ZeLiK пишет 11.02.2008 @ 21:38 
День добрый уважаемые!
Бурное обсуждение, но я к сожелению новичок и не всё понимаю, но суть вопроса понятна будет всем: Окончательная версия или новая версия статьи ожидается? Смотрю много предположений и предложений, у меня к Вам просьба, написать новую версию статьи, или просто несколько готовых вариантов. Признаюсь что хочу использовать вашу идею, надеюсь вы не будете против, копирайт и контакты с вами как разработчиками будут обязательно.
 :::::  MortalMan пишет 12.03.2008 @ 05:48 
max, а пользователям *nix предлагаете идти лесом?

Дмитрий Рассанов, преобразование e-mail'а в графику пока единственный вменяемый способ защиты от ботов. СПАМеры конечно будут пытаться на него реагировать, но распознать e-mail'ы на и без того заваленных графикой сайты - дело безперспективное.
 :::::  Виктор Симон пишет 17.08.2008 @ 02:43 
Вернувшись через 4 года... посмотревши на собственный пост и на комменты... Ну могу сказать, что на момент написания, спам-боты небыли настолько умны. А сейчас, параноикам - использовать веб-форму (как в предложенном мной варианте) с каптчей, либо вариант сокрытия адреса емайл в яваскрипте (запутать бота массивом содержащим куски реального емайла и разбавляющий мусор очень просто).
А вывод емайла картинкой - наименее подходящий способ имхо (вот сам очень не люблю такие вещи, приходится тупо перепечатывать емайл, занятие не приятное - напрягать посетителя сайта дело последнее).
 :::::  Леонид Евстигнеев пишет 11.04.2009 @ 12:19 
А почему все используют <a>?
можно же просто помесить скрипт на картинку.
<img src="mail.gif" onclick="document.getElementById('mailto_frame').src='http://'+'url_for_decode_mail'" />
</address>
<iframe id="mailto_frame" width="0" height="0" frameborder="0"></iframe>

Боту для на хождения такой ссылки придётся прощёлкать все картинки. :)
Можно ведь и картинку задним фоном назначить для любого другого элемента назначить.
 :::::  Юрьев Роман пишет 05.05.2009 @ 08:58 
в настоящее время предложенный метод требует небольшой доработки, чтобы быть неуязвимым от роботов. Слабое место у него в том, что при переходе по ссылке через Location сразу отдается секретное мыло. Вот это место и надо изменить. В итоге алгоритм получается следующий:
1) обрабатываем страницу перед отдачей клиенту и заменяем в ней все емайлы на ссылки с зашифрованными емайлами.
2) при клике по такой ссылке, для пользователя открывается маленькое окошечко, где его просят ввести Капчу (контрольный текст с картинки)
3) только в случае успешного ввода, доказав что пользователь не является ботом, ему отдается Header("Location: mailto:".decrypt_email($_GET['email'])); с уже дешифрованным мылом.

спаммеры нервно курят ) занавес )
Имя:
Email:
URL

Введите сумму двух чисел девять и одинн (девять+одинн=?)
Запомнить мою информацию

* Html запрещен* Ваш E-mail опубликован не будет.

Copyright © 2000-2001 WebScript.Ru nas@webscript.ru
Design © 2001 by Parallax Design Studio (aka Spectator.ru)
Все торговые марки и авторские права на эту страницу принадлежат их соответствующим владельцам.
Сгенерировано за: 0.0245929