SELECT SQL_CACHE *
Присоединяюсь, это фигня, а не кеш... Работать не будет.
Методы
fetch_array
fetch_row
getCountQueries
getInstance
loadEngine
num_rows
query
reset_pointer
startTransaction
stopTransaction
Вы уж определитесь - либо отстойные подчеркивания, либо нормальный CamelCase
******************************************************
---------------
Защита GET-запросов
Если пользователю доступно выполнение некоторого действия, например, голосование или удаление статьи, где параметры (id и т.д.) передаются через GET, то для предотвращения CSRF-атак рекомендуется пользоваться следующим приемом. К запросу добавлять GET-параметр с названием scode, значение которого - это сессионный защитный ключ пользователя (он передается в XML-таблице ответа модуля в значении атрибута scode тега data, см. XML-таблицы ответов модулей). Затем в вызываемом методе модуля добавить строчку $this->expectSecureGET(); (желательно в начале метода). Теперь метод модуля стработает только при правильном значении GET-параметра scode.
Обратите внимание, что таким образом следует защищать только GET-запросы, в результате которых выполняется удаление, добавление или изменение объектов (особенно это критично дейсвий в панели администратора).
----------
Еще один детский сад. Эта проблема решается так:
1. Гетом только нормальные запросы, которые ничего не делают. Проверять их не нужно.
2. Все пост запросы САМИ вставляют че надо в форму и потом это проверяют. Без участия программера. Заодно и дубли постов не проходят. (Отключается - по запросу, а по-умолчанию - всключено во всех формах)
-~{}~ 28.08.09 23:06:
******************************************************
Берем первый попавшийся странный код, смахивающий на ...
PHP:
function is_true_float($val){
if(is_float($val) || ((float) $val > (int) $val || strlen($val) != strlen((int) $val)) && (int) $val != 0) {
return true;
}
else {
return false;
}
}
Т.к. понять, че тут делается нельзя, ищем вызов функции по всему коду. Опа, а нигде и не используется. Тока в закомментированном блоке:
PHP:
/*case 'float' : {
if (!is_true_float ($fieldValue)) {
$aErrors[$fieldName] = lang ('validation_error_value_float',__CLASS__);
}
break;
}*/
Блок, похоже, проверяет валидность полей из веб-формы. Афтар... Скока можно рассказывать - из $_REQUEST не может придти ни INT, ни DOUBLE ни вообще нихрена, кроме STRING (или массива строк).
-~{}~ 28.08.09 23:15:
******************************************************
Хахаха, вот это жесть:
PHP:
/**
* Удаляет из строки все теги кроме разрешенных и потенциально-опасные параметры тегов типа onclick, onload и т.п.
* @param string $string
* @return string
*/
function cmsStripTags ($string) {
$allowedTags = array ('a','img','p','br','ul','ol','li','strong','b',
'em','i','strike','s','del','table','tr','td',
'abbr','blockquote','quote','pre','code','sub',
'sup','acronym','u','cut','video','user','font');
$sTags = '';
foreach ($allowedTags as $tag) {
$sTags .= '<' . $tag . '>';
}
$string = strip_tags ($string, $sTags);
$string = preg_replace ("#onclick=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onmouseover=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onmouseout=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onmousedown=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onmouseup=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onselect=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onfocus=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onblur=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onload=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onkeydown=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onkeyup=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#ondblclick=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onunload=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onmouseup=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onsubmit=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#onerror=[\"|\'](.+?)[\"|\']#iu", '', $string);
$string = preg_replace ("#style=[\"|\'](.+?)[\"|\']#iu", '', $string);
return ($string);
}
Естественно, эта детская поделка ничего не удалит. Даже школьник допрет, куда вставить явакод помимо вырезанных тегов (кроме этих событий, есть еще много других мест).
Полнейшая бредятина с регами. Ну, понятно, их нужно объединить до одного, чтобы зря процессор не гоянть:
PHP:
$string = preg_replace ("#(onclick|onmouseover| ... )=[\"|\'](.+?)[\"|\']#iu", '', $string);
Но этот рег не найдет даже такой примитив в ONCLICK, который проверяется
Код:
<a onclick = alert(& quot;Hello & quot;)> test </a> (между & и q удалить пробел - особенности форума)
Короче, защита крутая, от таких же писателей говноцмс
-~{}~ 28.08.09 23:17:
******************************************************
PHP:
/**
* Преобразует символы строки в нижний регистр, заменяет русские буквы на созвучные латинские и экранирует/заменяет некоторые знаки препинания
* @param string $string
* @return string
*/
function translit ($string) {
$aFrom = array ('й','ц','у','к','е','н','г','ш', 'щ', 'з','х','ъ','ф','ы','в','а','п','р','о','л','д','ж','э','я', 'ч', 'с','м','и','т','ь','б','ю', 'ё');
$aTo = array ('y','c','u','k','e','n','g','sh','sh','z','h','', 'f','i','v','a','p','r','o','l','d','j','e','ya','ch','s','m','i','t','', 'b','yu','e');
$string = preg_replace ($aFrom, $aTo, $string);
return $string;
}
Про функцию strtr() афтар конечно не вкурсах.
-~{}~ 28.08.09 23:25:
******************************************************
Встречается 3 забавных места
PHP:
1. eval ('$oCron->' . $callMethod . ' ();');
2. /*if ($realModuleName == $moduleName) {
eval ('$oResponse = $this->modules[\'' . $moduleName . '\'][\'object\']->' . $method . ' (' . $sParams . ');');
} else {
$oResponse = $this->modules[$moduleName]['object']->__call ($method, $aParams);
}*/
//$oResponse = $this->modules[$moduleName]['object']->execute ($method, $sParams);
eval ('$oResponse = $this->modules[\'' . $moduleName . '\'][\'object\']->' . $method . ' (' . $sParams . ');');
3. eval ('$response = self::$subObjects[$this->moduleName][\'' . $className . '\']->' . $method . ' (' . $sParams . ');');
Во 2 и 3 месте параметры $sParams никак не проверяются и берутся, скорее всего, из УРЛ.
Т.е. запостить туда прямиком свой код не составляется труда:
eval('$this->modules(' ..... " ); $HACK; die( " .... ');');
Воспроизвести дыру не смог из-за банальной до ужаса причины - явно дырявые блоки нигде не вызываются

Ну, может плохо искал, но stream_open() не вызывается нигде, хотя и описана.
А глядя на потуги афтара с закомментированным eval, хочется порекомендовать ман на функцию call_user_func_array().
-~{}~ 28.08.09 23:43:
******************************************************
Более тонкий пример ламерства и не понимания работа файловых локов. 100% будут потери данных при нагрузке и параллельных исполнениях этого кода.
PHP:
$f = fopen ($file, 'w+');
flock ($f, LOCK_EX);
fwrite ($f, serialize ($this->aHelpers));
flock ($f, LOCK_UN);
fclose ($f);
Между 1 и 2й строкой вклинятся сотни других потоков, которые допишут иные куски данных (в файле будет невалидный мусор).
Часто, такие ошибки делают и вполне профессиональные программисты
Короче, FLOCK и "w+" - это заведомый бред. Жалко, что в доке это не написано большими буквами.
Снимать блокировку перед закрытием файла не нужно. Сам снимится на закрытии.
-~{}~ 28.08.09 23:47:
******************************************************
Думаю, КАЖДЫЙ начинающий программер хранит у себя в мега цмс подобную говнофункцию:
PHP:
private function array2PHPString (array $arr, $arrName) {
$s = <<<TEXT
<?php
\${$arrName} = array (
TEXT;
$cntElements = count ($arr);
$i = 1;
foreach ($arr as $key => $value) {
$s .= "'" . $key . "' => '" . addslashes($value) . "'";
if ($i != $cntElements) {
$s .= ",\r\n";
}
++$i;
}
$s .= ");\r\n";
return $s;
}
На самом деле, пишется это В ОДНУ СТРОКУ: file_put_contents + var_export.
Нахрена использовать бредовую инициализацию $s, вместо простого $s=" .... " - не понятно.
******************************************************
PHP:
function safeSql ($s) {
if (!get_magic_quotes_gpc()) {
if (is_string ($s)) {
$s = mysql_real_escape_string ((string) $s);
return $s;
}
elseif (is_array ($s)) {
foreach ($s as $key => $v) {
$s[$key] = mysql_real_escape_string ((string) $v);
}
return $s;
} else {
return $s;
}
}
return $s;
}
Сначала проверили, а не строка ли это? А потом еще разок, для надежности, и тип привели.
И между делом все ретурны можно выкинуть, логика не изменится.
А т.к. проект работает на UTF-8, то использовать mysql_real_escape_string не обязательно. Достаточно просто addslashes.
******************************************************
PHP:
if ($this->orderRand) {
$sSql = $sUnion . "\r\nORDER BY RAND()";
} else {
Вот так и представляю, как мега социальная сетка будет эту команду исполнять .-)
******************************************************
По всему коду маячит антипаттерн "магические числа".
******************************************************
PHP:
$size = $size > 10 ? $size : 10;
$size = $size < 40 ? $size : 40;
Этот кусок пишется так: $size=min( max(10, $size), 40);
По умному - в functions.php пишем between( $x, $min, $max).
******************************************************
Функции ajax_vote_blog и ajax_vote_post содержат ОДИНАКОВЫЙ сплошной блок кода из 27 строк.
******************************************************
В функции getTotalCount афтар демонстрирует полное незнание SQL. Функция строит некий абстрактный селект к базе, используя LIMIT и постраничную навигацию. Разумеется, хочется кроме навигации и знать ОБЩЕЕ ЧИСЛО всех полей, т.е. исполнить тут же запрос без этого LIMIT.
Че делает юзверь? Правильно: 2 запроса. Афтар поступил мудрее: второй запрос оформил через юнион
SELECT .... WHERE ... LIMIT UNION (SELECT COUNT(*), " . (++$n) . " AS '__fuckin_union__' FROM ...
Если почитать доку, можно узнать, что не нужно делать второй запрос. Можно достать общее число строк вместе с LIMIT-запросом.