Ну как... понятно, что написать гостебуку саму по себе никакого труда не составляет. Вся соль в нюансах. Например, забывает ли товарищ резать HTML при выводе сообщений? А если потребовать, чтобы _некоторые_ теги таки были доступны - то как он решает эту задачу? Как обходится с оченьдлиннымисловами? А со ссылками в тексте? А с кучей \n подряд? А как у него гостебука листается? А как её можно взломать? А как обстоят дела с дублями сообщений? А что она говорит, если забыть заполнить некоторые поля? А что будет, если нажать рефреш сразу после постинга? А запоминает ли она имя? А можно ли её постмодерить? А можно ли банить козлов?
А "не нравилось" мне то, что народ даже не начинал задумываться над этими вопросами. В лучшем случае ставил htmlspecialchars на выходе.
Эге! Перечисленные проблемы все мне знакомы, но вот до практического воплощения некоторых дело не дошло :-) Руки, точнее. Даже интересно пробежаться по этому экспресс-тесту :-) - теги товарищ не забывает резать. А точнее - "в лучшем случае htmlspecialchars" :-) - а вот с "некоторыми тегами" - никакого баловства. Чай, гостевая, а не мегапортал. Это, пожалуй, принцип. Если нужно будет оформление, то - псевдотеги. У хозяина есть все теги. - об очень длинных словах программа предупреждает и не дает запостить. - ссылки подсвечивает, но рег примитивный у меня - до пустого места. точку не поставить. я над этим работаю. - куча пустых строк в тексте... не задумывался. Правда, никто не помешает гаду наставит кучу не пустых, а котротких строк. вообще, от гада, если решит - сам знаешь, защититься невозможно. вот, сегодня, орел один в ru_php, открытым текстом "как мне послать пост-запрос через анонимную проксю.". Естественно - тут же набежали доброхоты, мать их... - листается пока примитивно. вот, были идеи. пока не реализовал. Думаю. - взломать - не мне судить. но писано по правилам. - защиты от спама нет, но локейшен делается. - имя запоминает. Причем! Корректно работает с мэджик квотами, которые - просто бич в куках :-) при наличии убиваются два раза - из поста и из кук. - постмодерить - можно - бан не реализован.
А посмотреть - исходник, конечно. Думаю, как из этих, набросаных навскидку, вопросов, я для себя кое-что вынес, так и скорее всего, из того, что ты скажешь по исходникам, если захочешь, вынесу.
На самом деле, идеала не бывает, и в реальной гостебуке вовсе не обязаны быть все эти фичи (да я, конечно, не все возможности перечислил - только те, что в голову пришли сразу). Но поскольку мы тогда искали именно веб-программера, то я должен был понять, осознаёт ли вообще товарищ, чем ему придётся заниматься? Понимает ли он, что его программой будут пользоваться совершенно непредсказуемым образом? Это то, что раньше называлось "защитой от дурака", только в веб-программинге это не одна из защит, а основная идеология написания. И вот чаще всего оказывалось, что человеку и в голову не могло придти, что юзер может нажать на submit, не заполнив все поля формы. Или нажать на submit не один, а два-три-четыре раза. Или в адресной строке наберёт отрицательный номер страницы. Или придёт не нормальные отзывы писать, а материться.
И, опять же, важно было не соблюдение этих требований, а отношение к ним. Например, автор гостебуки вполне мог сказать, что, поскольку гостебуку предполагается часто просматривать, то защиту от глюков форматирования (напр., \n\n\n\n\n) можно не делать - народ в гостебуке предполагается серьёзный, а ошибки исправит модератор. Но важно было, чтобы человек осознавал проблему и мог оценить риск.
То есть гостебука для таких тестов очень хороша: с одной стороны, сама по себе задачка проста, а с другой - это полноценное интерактивное приложение, со всеми вытекающими требованиями.
Кстати, требования тоже могут взаимодействовать различным образом. К примеру, защита от длинных слов (путём переноса - как в хпоинте) и автообкладывание ссылок. Вот постанул юзер ссылку, к примеру, http://msdn.microsoft.com/library/default.asp?url=/workshop/author/om/doc_object.asp. Либо в неё сначала система переносов вставит [BR], а потом система ссылок попытается из этого сделать <a href...>, либо сначала система ссылок сделает <a href...>, а потом система переносов попытается разбить получившегося монстра. И то и то не слава богу. В общем, куча мелких подзадачек.
По нашим баранам: :)
- Зашёл на phpclub и первым делом углядел отсутствие защиты от символа "|" в имени и теле сообщения:) Я понимаю, что там это далеко не финальный вариант, но всё-таки в файловой гостебуке этим надо озаботиться (отчего, кстати, не сериалайзить записи serialize-ом?).
- Псевдотеги я лично не очень люблю (смысла в них не вижу), поэтому разрешаю юзерам использовать I,B,EM,STRONG,S,U и т.п. безатрибутные теги, благо их очень просто безопасным образом отловить. Но это дело вкуса, конечно.
- По поводу ссылок, могу порекомендовать очень простой код, который вполне успешно у меня работает на многих сайтах:
А вообще, наверное, было бы интересно взглянуть на код. Глядишь, и сам чему-нибудь научусь:)
P.S. Кстати, вспомнил ещё один, очень важный пункт. В каком виде хранятся сообщения в базе - в исходном, пришедшем от юзера, или в отформатированном? Поскольку есть мнение...
Ух ты! Ну и ответ. На статью тянет. Со всем враз и не разберешься. Для начала надо себя похвалить. Тест твой я прохожу на все сто. Если даже вещь незаимплеменчена в гостевой, или заимплеменчена, но не так, как ты предлагаешь, то, во всяком случае, над каждой я задумывался и имею собственное мнение. :-)
Впрочем, не все идет от личного опыта - даром что ли я столько сижу по всяким форумам? :-)
По поводу \n. Идя домой, придумал совершенно примитивную защиту. if (substr_count($body,"\n") > $max_lines) ... То есть, не важно, пустые строки, или нет. Есть общее ограничение на их количество.
По поводу длинных слов. У меня очень хитрый поход, не такой, как перечисленные. Я ничего не меняю и не разбиваю. Не барское это дело :-) Мое дело - отловить и предупредить. А дальше - пусть сам, как хочет, правит. Отлавливаю я только идущие подряд буквы и цифры. возможно, это неправильно. В частности, от проблемы "точка после пробела" оно не спасает. В общем, защита примитивная, только чтобы тест пройти :-) но урлы она пропускает, поскольку в них есть и другие символы.
По поводу поста на пхпклубе. Про палку - это кошмар. Она там, до вяческих исправлений, точно была. Я даже искал html эквивалент в свое время для замены. Да и в старых кодах моих она есть. А тут - испарилась :-(
По поводу тегов/псевдотегов я пока не определился,если честно. И то мне не нравится, и это... Обычные теги, кроме того, что их надо фильтровать, надо еще и проверять на закрытие. А то весь дизайн поплыть может.
За рег - спасибо. Осталось только разобраться, как он работает... Начало и конец паттерна для меня - загадка...
По поводу того, как хранить данные. Мое давнее и стойкое убеждение - хранить, как есть. привожу обычно те же доводы. На случай, если остро встанет вопрос производительности, придуман ответ - хранить два варианта, исходный и обработанный. при желании, всегда можно мбудет "перекомпилировать" последний из первого по новым правилам. Классический размен - скорость на размер.
Вот исходники: http://ronet.ru/gb.zip У меня самого к ней три замечания - не все, что следовало бы, вынесено в конфиг. - не очень удачная структура приложения - надо бы сделать ее более гибкой. Админ зашит жестко, его нельзя в любом месте впихнуть, как клиентские части. - не очень оптимально сделано препарирование данных перед выводом.
Есть еще одна заноза. форма администрирования сделана отдельно. То есть, при добавлении полей, к примеру, править надо два файла. Но сделано это для того, чтобы убрать из шаблона формы лишнюю логику, которой много в админском шаблоне.
Плюсы - простота (краткость) и использование "шаблонов" для бедных. :-)
А сама тема тянет на хорошую книгу:) Только вот кто её напишет?
> По поводу \n. > Идя домой, придумал совершенно примитивную защиту. > if (substr_count($body,"\n") > $max_lines) ... > То есть, не важно, пустые строки, или нет. Есть общее ограничение на их количество.
Хым. Как-то оно мне не очевидно. В сочетании с ограничением на длину постинга, мы получаем ограничение на среднюю длину строки, причём снизу (!). А если кто-то захочет Маяковского процитировать?:)
Я обычно просто делаю: preg_replace('/\n\n+/','<br><br>', $text) - т.е. два и более последовательных перевода строки заменяю на ровно два брека. Дёшево и сердито. А возиться с полным числом переносов мне как-то лень...
> По поводу поста на пхпклубе. > Про палку - это кошмар. Она там, до вяческих исправлений, точно была.
Бывает:)
> Я даже искал html эквивалент в свое время для замены.
А зачем? Можно же любой символ использовать, только надо его правильно заслэшить в тесте (и разслэшить потом).
Н-ну, задача сортировки в ГБ не стоит, задача поиска... честно говоря, не видел ещё гостебуки с поиском. Читать глазами этот файл тоже вряд ли когда-нибудь будет нужно (а админский интерфейс на что?). Но, в принципе, мнение имеет право на жизнь, конечно.
> По поводу тегов/псевдотегов я пока не определился,если честно. И то мне не нравится, и это... > Обычные теги, кроме того, что их надо фильтровать, надо еще и проверять на закрытие. А то весь дизайн поплыть может.
А псевдотеги, что, не надо проверять на закрытие? Я имею в виду не те, что на хпоинте, а те, что обычно делают в форумах - [i]...[/i], например. Те же яйца в другом ракурсе.
Я обычно, после того как отфильтрую все опасные теги (точнее, отфильтрую все, а потом разрешу безопасные), попросту сажаю текст в контейнер из таблицы: <table><tr><td>...</td></tr></table>. Любой недозакрытый тег внутри таблицы закрывается при выходе из неё. Это, насколько я знаю, самый простой вариант борьбы с непарными тегами.
> За рег - спасибо. Осталось только разобраться, как он работает... Начало и конец паттерна для меня - загадка...
Да там просто же всё. Обычный перловый рег. Ещё можно \b поставить вначале для верности.
Можно переписать как: {((?:https?://|ftp://|www\.)\S+)(?<![.,:;!?\)\<-])}
Ссылка может начинаться с "https?://|ftp://|www.", за которым идёт какое-то количество не-пробелов (\S+). Но последний из этих непробелов не должен совпадать с определённым набором символов: (?<![...]). А именно, с ".,:;!?\)\<-" (чисто эмпирический набор). Это для того, чтобы можно было после ссылки ставить точку, запятую и т.д.
no subject
Date: 2003-11-14 03:05 am (UTC)no subject
Date: 2003-11-14 03:55 am (UTC)http://ronet.ru/gb
http://admin:admin@ronet.ru/gb/?admin
только она недописана же еще
no subject
Date: 2003-11-14 06:14 am (UTC)no subject
Date: 2003-11-14 06:22 am (UTC)только что ответил!
А как именно не работают?
no subject
Date: 2003-11-14 06:33 am (UTC)no subject
Date: 2003-11-14 03:16 am (UTC)no subject
Date: 2003-11-14 03:56 am (UTC)Ну, если что - на форуме спрошу :-)
no subject
Date: 2003-11-14 03:26 am (UTC)no subject
Date: 2003-11-14 03:56 am (UTC)no subject
Date: 2003-11-14 04:05 am (UTC)Хотя, я и так подозреваю... ;-)
no subject
Date: 2003-11-14 04:09 am (UTC)Я так подумал, что при желании вычислить несложно :-)
no subject
Date: 2003-11-14 04:24 am (UTC)Как вы постраничку делаете на шаблоне?
Все остальное я худо-бедно отделил, "шаблонами для бедных". А с выводом нафигации как быть?
Там кода раз в 5 больше, чем оформленння. что куда пихать?
no subject
Date: 2003-11-14 05:18 am (UTC)кажись, в последней, на этот момент, 5-й главе...
no subject
Date: 2003-11-14 05:27 am (UTC)Я тоже кодом сделал.
no subject
Date: 2003-11-14 05:30 am (UTC)no subject
Date: 2003-11-14 05:55 am (UTC)no subject
Date: 2003-11-14 05:59 am (UTC)no subject
Date: 2003-11-24 12:20 pm (UTC)no subject
Date: 2003-11-24 12:26 pm (UTC)Низкий уровень соискателей или просто эээ... их стиль или подход, что ли, не нравился?
мою хочешь посмотреть? :-)
no subject
Date: 2003-11-24 12:41 pm (UTC)Например, забывает ли товарищ резать HTML при выводе сообщений? А если потребовать, чтобы _некоторые_ теги таки были доступны - то как он решает эту задачу? Как обходится с оченьдлиннымисловами? А со ссылками в тексте? А с кучей \n подряд? А как у него гостебука листается? А как её можно взломать?
А как обстоят дела с дублями сообщений? А что она говорит, если забыть заполнить некоторые поля? А что будет, если нажать рефреш сразу после постинга? А запоминает ли она имя? А можно ли её постмодерить? А можно ли банить козлов?
А "не нравилось" мне то, что народ даже не начинал задумываться над этими вопросами. В лучшем случае ставил htmlspecialchars на выходе.
Посмотреть... исходник?
no subject
Date: 2003-11-24 01:04 pm (UTC)Перечисленные проблемы все мне знакомы, но вот до практического воплощения некоторых дело не дошло :-) Руки, точнее.
Даже интересно пробежаться по этому экспресс-тесту :-)
- теги товарищ не забывает резать. А точнее - "в лучшем случае htmlspecialchars" :-)
- а вот с "некоторыми тегами" - никакого баловства. Чай, гостевая, а не мегапортал. Это, пожалуй, принцип. Если нужно будет оформление, то - псевдотеги. У хозяина есть все теги.
- об очень длинных словах программа предупреждает и не дает запостить.
- ссылки подсвечивает, но рег примитивный у меня - до пустого места. точку не поставить. я над этим работаю.
- куча пустых строк в тексте... не задумывался. Правда, никто не помешает гаду наставит кучу не пустых, а котротких строк. вообще, от гада, если решит - сам знаешь, защититься невозможно. вот, сегодня, орел один в
- листается пока примитивно. вот, были идеи. пока не реализовал. Думаю.
- взломать - не мне судить. но писано по правилам.
- защиты от спама нет, но локейшен делается.
- имя запоминает. Причем! Корректно работает с мэджик квотами, которые - просто бич в куках :-) при наличии убиваются два раза - из поста и из кук.
- постмодерить - можно
- бан не реализован.
вообще, есть у меня такой хрестоматийный пост на пхпклубе :-)
рассматриваются там некоторые из поставленных вопросов
http://phpclub.net/talk/showthread.php?s=&threadid=30705
А посмотреть - исходник, конечно.
Думаю, как из этих, набросаных навскидку, вопросов, я для себя кое-что вынес, так и скорее всего, из того, что ты скажешь по исходникам, если захочешь, вынесу.
no subject
Date: 2003-11-25 03:08 am (UTC)И, опять же, важно было не соблюдение этих требований, а отношение к ним. Например, автор гостебуки вполне мог сказать, что, поскольку гостебуку предполагается часто просматривать, то защиту от глюков форматирования (напр., \n\n\n\n\n) можно не делать - народ в гостебуке предполагается серьёзный, а ошибки исправит модератор. Но важно было, чтобы человек осознавал проблему и мог оценить риск.
То есть гостебука для таких тестов очень хороша: с одной стороны, сама по себе задачка проста, а с другой - это полноценное интерактивное приложение, со всеми вытекающими требованиями.
Кстати, требования тоже могут взаимодействовать различным образом. К примеру, защита от длинных слов (путём переноса - как в хпоинте) и автообкладывание ссылок. Вот постанул юзер ссылку, к примеру, http://msdn.microsoft.com/library/default.asp?url=/workshop/author/om/doc_object.asp. Либо в неё сначала система переносов вставит [BR], а потом система ссылок попытается из этого сделать <a href...>, либо сначала система ссылок сделает <a href...>, а потом система переносов попытается разбить получившегося монстра. И то и то не слава богу. В общем, куча мелких подзадачек.
По нашим баранам: :)
- Зашёл на phpclub и первым делом углядел отсутствие защиты от символа "|" в имени и теле сообщения:) Я понимаю, что там это далеко не финальный вариант, но всё-таки в файловой гостебуке этим надо озаботиться (отчего, кстати, не сериалайзить записи serialize-ом?).
- Псевдотеги я лично не очень люблю (смысла в них не вижу), поэтому разрешаю юзерам использовать I,B,EM,STRONG,S,U и т.п. безатрибутные теги, благо их очень просто безопасным образом отловить. Но это дело вкуса, конечно.
- По поводу ссылок, могу порекомендовать очень простой код, который вполне успешно у меня работает на многих сайтах:
$Text = preg_replace('{((?:(?:https?|ftp)://|www\.)\S+)(?<![.,:;!?\)\<-])}','<a href="\1">\1</a>',$Text); $Text = preg_replace('{<a href="www\.}','<a href="http://www.',$Text);А вообще, наверное, было бы интересно взглянуть на код. Глядишь, и сам чему-нибудь научусь:)
P.S. Кстати, вспомнил ещё один, очень важный пункт. В каком виде хранятся сообщения в базе - в исходном, пришедшем от юзера, или в отформатированном? Поскольку есть мнение...
no subject
Date: 2003-11-25 04:14 am (UTC)Ну и ответ.
На статью тянет.
Со всем враз и не разберешься.
Для начала надо себя похвалить. Тест твой я прохожу на все сто. Если даже вещь незаимплеменчена в гостевой, или заимплеменчена, но не так, как ты предлагаешь, то, во всяком случае, над каждой я задумывался и имею собственное мнение. :-)
Впрочем, не все идет от личного опыта - даром что ли я столько сижу по всяким форумам? :-)
По поводу \n.
Идя домой, придумал совершенно примитивную защиту.
if (substr_count($body,"\n") > $max_lines) ...
То есть, не важно, пустые строки, или нет. Есть общее ограничение на их количество.
По поводу длинных слов. У меня очень хитрый поход, не такой, как перечисленные.
Я ничего не меняю и не разбиваю. Не барское это дело :-)
Мое дело - отловить и предупредить. А дальше - пусть сам, как хочет, правит.
Отлавливаю я только идущие подряд буквы и цифры. возможно, это неправильно. В частности, от проблемы "точка после пробела" оно не спасает.
В общем, защита примитивная, только чтобы тест пройти :-)
но урлы она пропускает, поскольку в них есть и другие символы.
По поводу поста на пхпклубе.
Про палку - это кошмар. Она там, до вяческих исправлений, точно была. Я даже искал html эквивалент в свое время для замены. Да и в старых кодах моих она есть. А тут - испарилась :-(
Почему не сериализовать? Есть у меня на этот счет мнение. Вот такое:
http://phpclub.net/talk/showthread.php?postid=195600#post195600
http://xpoint.ru/forums/programming/PHP/thread/23528.xhtml
По поводу тегов/псевдотегов я пока не определился,если честно. И то мне не нравится, и это...
Обычные теги, кроме того, что их надо фильтровать, надо еще и проверять на закрытие. А то весь дизайн поплыть может.
За рег - спасибо. Осталось только разобраться, как он работает... Начало и конец паттерна для меня - загадка...
По поводу того, как хранить данные. Мое давнее и стойкое убеждение - хранить, как есть.
привожу обычно те же доводы.
На случай, если остро встанет вопрос производительности, придуман ответ - хранить два варианта, исходный и обработанный. при желании, всегда можно мбудет "перекомпилировать" последний из первого по новым правилам. Классический размен - скорость на размер.
Вот исходники: http://ronet.ru/gb.zip
У меня самого к ней три замечания
- не все, что следовало бы, вынесено в конфиг.
- не очень удачная структура приложения - надо бы сделать ее более гибкой. Админ зашит жестко, его нельзя в любом месте впихнуть, как клиентские части.
- не очень оптимально сделано препарирование данных перед выводом.
Есть еще одна заноза. форма администрирования сделана отдельно. То есть, при добавлении полей, к примеру, править надо два файла. Но сделано это для того, чтобы убрать из шаблона формы лишнюю логику, которой много в админском шаблоне.
Плюсы - простота (краткость) и использование "шаблонов" для бедных. :-)
no subject
Date: 2003-11-25 07:38 am (UTC)> Ну и ответ.
> На статью тянет.
А сама тема тянет на хорошую книгу:) Только вот кто её напишет?
> По поводу \n.
> Идя домой, придумал совершенно примитивную защиту.
> if (substr_count($body,"\n") > $max_lines) ...
> То есть, не важно, пустые строки, или нет. Есть общее ограничение на их количество.
Хым. Как-то оно мне не очевидно. В сочетании с ограничением на длину постинга, мы получаем ограничение на среднюю длину строки, причём снизу (!). А если кто-то захочет Маяковского процитировать?:)
Я обычно просто делаю: preg_replace('/\n\n+/','<br><br>', $text) - т.е. два и более последовательных перевода строки заменяю на ровно два брека. Дёшево и сердито. А возиться с полным числом переносов мне как-то лень...
> По поводу поста на пхпклубе.
> Про палку - это кошмар. Она там, до вяческих исправлений, точно была.
Бывает:)
> Я даже искал html эквивалент в свое время для замены.
А зачем? Можно же любой символ использовать, только надо его правильно заслэшить в тесте (и разслэшить потом).
> Почему не сериализовать? Есть у меня на этот счет мнение. Вот такое:
> http://phpclub.net/talk/showthread.php?postid=195600#post195600
> http://xpoint.ru/forums/programming/PHP/thread/23528.xhtml
Н-ну, задача сортировки в ГБ не стоит, задача поиска... честно говоря, не видел ещё гостебуки с поиском. Читать глазами этот файл тоже вряд ли когда-нибудь будет нужно (а админский интерфейс на что?). Но, в принципе, мнение имеет право на жизнь, конечно.
> По поводу тегов/псевдотегов я пока не определился,если честно. И то мне не нравится, и это...
> Обычные теги, кроме того, что их надо фильтровать, надо еще и проверять на закрытие. А то весь дизайн поплыть может.
А псевдотеги, что, не надо проверять на закрытие? Я имею в виду не те, что на хпоинте, а те, что обычно делают в форумах - [i]...[/i], например. Те же яйца в другом ракурсе.
Я обычно, после того как отфильтрую все опасные теги (точнее, отфильтрую все, а потом разрешу безопасные), попросту сажаю текст в контейнер из таблицы: <table><tr><td>...</td></tr></table>. Любой недозакрытый тег внутри таблицы закрывается при выходе из неё. Это, насколько я знаю, самый простой вариант борьбы с непарными тегами.
> За рег - спасибо. Осталось только разобраться, как он работает... Начало и конец паттерна для меня - загадка...
Да там просто же всё. Обычный перловый рег. Ещё можно \b поставить вначале для верности.
{((?:(?:https?|ftp)://|www\.)\S+)(?<![.,:;!?\)\<-])}
Можно переписать как:
{((?:https?://|ftp://|www\.)\S+)(?<![.,:;!?\)\<-])}
Ссылка может начинаться с "https?://|ftp://|www.", за которым идёт какое-то количество не-пробелов (\S+). Но последний из этих непробелов не должен совпадать с определённым набором символов: (?<![...]). А именно, с ".,:;!?\)\<-" (чисто эмпирический набор). Это для того, чтобы можно было после ссылки ставить точку, запятую и т.д.
> Вот исходники: http://ronet.ru/gb.zip
Спасибо, погляжу:)
no subject
Date: 2003-11-24 01:08 pm (UTC)Контроль есть. На длину полей в обе стороны.