Магически кавички - общи питания

sizif

Registered
Здравейте!

Каня се да стартирам нов проект и обмислям дали да не сменя маниера си на работа относно магическите кавички и търся мнения.

Стойността на сървъра за get_magic_quotes_gpc() -> on, т.е. екранирането е включено.

Обмислям дали да не го изключа и да се грижа за екранирането на символите сам. И тук възникват няколко въпроса:

Дали да използвам addslashes(); или мога да разчитам на htmlspecialchars(); с допълнителния параметър ENT_QUOTES (т.е. преобразува всички кавички)?

Как да направя изключването на автоматичното екраниране: с директива в .htaccess в главната директория или с ini_set(); във всеки скрипт?

Ако запазя екранирането, как ще се държи парсера при преобразуване на единичните кавички с htmlspecialchars(); и стойност ENT_QUOTES?

Моля за сериозни отговори. Обичайните общи приказки могат да бъдат прочетени във всяка трета тема във форума и не ми вършат работа.

Благодаря предварително!
 
Според мен най-добрия метод е да изключиш магическите кавички и всичко да си го правиш собственоръчно.

Първо, че ще си е по-сигурно, второ май няма :D

Така... addslashes, htmlspecialchars, htmlentities си имат различни предназначения. Трябва да си сигурен за къде ще се ползва. Дали ще вадиш данни или ще вкарваш данни в SQL, дали ще пращаш стойности до друга страница и т.н.

Против SQL Injection аз правя така... всяка заявка(само която получава данни от POST или GET) я обработвам със sprintf(); и чак тогава изпълнявам.

1. При текстови данни ти препоръчвам да си ползваш mysql_real_escape_string();
2. При числови данни си ползваш %d в sprintf(); - всякакви знаци различни от число ги превръща на 0, което е невалидна стойност за заявката, но ако мислиш, че ще е несигурно си правиш една проверка. Примерно

Код:
if(printf("%d", $_GET['id']) == 0){
       print "Невалидна стойност!";
}
else{
       $query = sprintf("SELECT * FROM `table` WHERE `id` = '%d'", $_GET['id']);
       //изпълняваш
}

няма начин някой да ти извелче по този начин инфомация от базата данни. При текстовите стойности като ползваш mysql_real_escape_string() си пак достатъчно защитен.


Против XSS можеш да ползваш htmlspecialchars() или htmlentities(.., ENT_QUOTES).

Друго не се сещам какво да ти кажа.
 
Здравей, relax!

Благодаря за отговора, но се надявах на повече конкретика по моите питания.

Познавам всяка една от функциите, които си изброил. Следя типа на данните от входа до изхода (принтирането на резултата) и знам какви промени ще претърпят и вземам съответните мерки за защита. Въпросите ми бяха конкретно за магическите кавички.

Числовите стойности се валидират лесно: intval(); floatval(); и още дузина функции за работа с числови данни.
PHP сменя динамично типовете, но не бих ти препоръчал sprintf(); за обработка на числови стойности - функцията връща низова стойност и в някои ситуации това може да доведе до подвеждащи резултати.

mysql_real_escape_string(); при get_magic_quotes_gpc() -> on би означавало двойно екраниране. Същото би се получило при изключени магически кавички и посрещане на входния низ с addslashes();
От друга страна не бих си позволил да разкарвам из скрипта потенциално рисков низ (далеч преди да се стигне до заявката към БД) без да го екранирам, което означава, че mysql_real_escape_string(); ще се окаже дублираща функция, а ми се вижда малко безсмислено да прекарвам през stripslashes(); за да ползвам mysql_real_escape_string();

Изпозлването на функции на килограм не ми изглежда много добро решение и ми се струва, че въпросът с магическите кавички не е толкова прост, колкото изглежда на пръв поглед.

Този въпрс ме интересува сериозно:

как ще се държи парсера при преобразуване на единичните кавички с htmlspecialchars(); и стойност ENT_QUOTES?
... съответно при включено и изключено екраниране.

Правих тестове, но мога да изгубя цяла година в опити без да изчерпя всички възможности, а в някаква ситуация при реален скрипт да се стигне до грешка.

Как да направя изключването на автоматичното екраниране: с директива в .htaccess в главната директория или с ini_set(); във всеки скрипт?

Дали да използвам addslashes(); или мога да разчитам на htmlspecialchars(); с допълнителния параметър ENT_QUOTES (т.е. преобразува всички кавички)?


Моля за още отговори!
 
но не бих ти препоръчал sprintf(); за обработка на числови стойности - функцията връща низова стойност и в някои ситуации това може да доведе до подвеждащи резултати.

тука си грешка. %d си връща числова стойност. При низ в съответния ГЕТ ще получиш 0(което пак казвам е невалидна стойност за една заявка(важното е ти да си го направиш да не е валидна)).



как ще се държи парсера при преобразуване на единичните кавички с htmlspecialchars(); и стойност ENT_QUOTES?

Първо, че htmlspecialchars няма как да ти преобразува единичните кавички. Може да ти преобразува само двойните. За държане не знам как ще се държи.

Как да направя изключването на автоматичното екраниране: с директива в .htaccess в главната директория или с ini_set(); във всеки скрипт?

магическите кавички няма как да ги спреш чрез ini_set(); нито чрез .htaccess. Трябва ти да ги управляваш. Когато качваш сайта на хостинга просто пускаш един код за проверка дали магическите кавички са пуснати или не и според това си оправяш кода.



Дали да използвам addslashes(); или мога да разчитам на htmlspecialchars(); с допълнителния параметър ENT_QUOTES (т.е. преобразува всички кавички)?

htmlspecialchars(); няма да ти помогне. За ескейпване се ползва addslashes()(ти сам каза, че знаеш как се ползват функциите). При SQL заявка пак ти препоръчвам да си ползваш mysql_real_escape_string()(като преди това провериш дали са спрени магическите кавички).

Май пак не дадох нужните отговори за теб, ама ти ще кажеш.
 
Здравей!

Не искам да се заяждам за sprintf(); но лесно можеш да провериш:

$num=12345;
echo (sprintf("%d", $num) === intval($num)) ? "Число" : "Низ";

Ако досега не си се сблъсквал с грешка, то е заради динамичната смяна на типовете, която съществува в РНР.

За htmlspecialchars(); също не си прав:

$niz="abc'def";
echo htmlspecialchars($niz, ENT_QUOTES); //виж сорса

...макра да не съм сигурен, доколко функционално е при сложни операции и затова търсех съвет.

По другия въпрос си прав отчасти - с ini_set(); няма да стане, но с директива в .htaccess би трябвало да сработи:

php_flag magic_quotes_gpc Off

Тъй като ini_set(); отпада, този въпрос отпада :)

При включени кавички (или посрещане с addslashes(); ) използването на mysql_real_escape_string(); би трябвало да изглежда така:

mysql_real_escape_string(stripslashes($niz));

... в което няма много логика.
 
Еми ако това с htaccess проработи то тогава няма да имаш проблем, иначе колко ти е да напишеш 5 реда код за една функция, която проверява дали са пуснати или не и според това им слагаш stripslashes()(ако са пуснати).

Това за sprintf() не съм го пробвал, но и не мисля, че точно това ще ми прави проблем.

За htmlspecialchars() и аз го пробвах, но при мен нямаше разлика.

Все пак не искам аз само да си давам мнения. Нека още някой да ни светне.
 
relax,

благодаря че се включи по темата.

Мога ли да разчитам на още мнения?
 
магическите кавички няма как да ги спреш чрез ini_set(); нито чрез .htaccess. Трябва ти да ги управляваш. Когато качваш сайта на хостинга просто пускаш един код за проверка дали магическите кавички са пуснати или не и според това си оправяш кода.

Пробвал съм и двата начина и работят. И с ini_set и с .htaccess. Лично аз си предпочитам .htaccess начина

Аз ползвам htmlspecialchars(addslashes($string), ENT_NOQUOTES) при изключен magic_quotes
И преди това проверявай дали е число, иначе това ще го обърне на низ и после is_numeric и приятели няма да работят както трябва.
 
sizif каза:
Здравейте!

Каня се да стартирам нов проект и обмислям дали да не сменя маниера си на работа относно магическите кавички и търся мнения.

Стойността на сървъра за get_magic_quotes_gpc() -> on, т.е. екранирането е включено.

Обмислям дали да не го изключа и да се грижа за екранирането на символите сам. И тук възникват няколко въпроса:

Дали да използвам addslashes(); или мога да разчитам на htmlspecialchars(); с допълнителния параметър ENT_QUOTES (т.е. преобразува всички кавички)?

Как да направя изключването на автоматичното екраниране: с директива в .htaccess в главната директория или с ini_set(); във всеки скрипт?

Ако запазя екранирането, как ще се държи парсера при преобразуване на единичните кавички с htmlspecialchars(); и стойност ENT_QUOTES?

Моля за сериозни отговори. Обичайните общи приказки могат да бъдат прочетени във всяка трета тема във форума и не ми вършат работа.

Благодаря предварително!

Аз ти препоръчвам да изключиш "магическите" кавички и да се грижиш за екранирането сам.
За стойности, който записваш в базата данни ти препоръчвам да ползваш само mysql_real_escape_string().С изключени маг. кавички, тази функция е перфектна за работа с дб.
Няма смисъл от htmlspecialchars и после да се записва в дб, защото ' се преобразува до " което заема пъти по-голямо място в дб.
След като инфото е записано в дб, при изкарването му можеш да го минеш през htmlspecialchars() и stripslashes().
Попринцип е по-добре да изключиш кавичките с htaccess, но е забранен на някой кекави хостинги, затова ако не става давай ръчно с ini_set().
Ако запазиш екранирането, низът asd'asd да речем се преобразува автоматично до asd\'asd, и после с htmlspecialchars() до asd\"asd и става мазало.

Поне така правя аз, и всичко е точно.

:)
 
StormBreaker,

питам само за низовите стойности, тяхната валидация е проблемът.

Този израз:

htmlspecialchars(addslashes($string), ENT_NOQUOTES);

няма ли да доведе до нещо такова:

asd\"asd

Около подобна конструкция ми се въртят идеите (със или без addslashes(); ), но ме притесняват евентуални непредвидени ефекти.

Да речем не използвам addslashes(); а с:
htmlspecialchars($niz, ENT_NOQUOTES);

...преобразувам единичните кавички. Дотук ОК, но обратните наклонени черти остават непокрити. Ако използвам addslashes(); се стига до описания по-горе ефект.


FestarBG,

ако правилно разбирам, това:

За стойности, който записваш в базата данни ти препоръчвам да ползваш само mysql_real_escape_string().С изключени маг. кавички, тази функция е перфектна за работа с дб.

...би трябвало да означава, че не ползваш екраниране преди да стигнеш до записа или директно посрещаш с mysql_real_escape_string(); ?


***

Неприятното е, че при принтиране парсерът премахва обратните наклонени черти и с тестове е трудно да се хванат етапите през които преминава даден низ докато се върти из скрипта или влиза и излиза от БД. Затова и пуснах тази тема, за да видя мнения.
 
Прав си, не гледам :))

Значи изключваш преобразуването на всички кавички? Не ти ли дава проблем при принтиране на стойности в темплейта да речем при тази ситуация:

<BUTTON NAME="$val">

Как постъпваш при принтиране на стойностите?
 
sizif каза:
Прав си, не гледам :))

Значи изключваш преобразуването на всички кавички? Не ти ли дава проблем при принтиране на стойности в темплейта да речем при тази ситуация:

<BUTTON NAME="$val">

Как постъпваш при принтиране на стойностите?

Изключвам htmlspec... да не ги преобразува, а addslashes си ги преобразува.
При принтиране един stripslashes(...)
 
Следя няколко теми и май луднах.
Ще помисля една нощ и ще видя на кого да дам точката.

Благодаря за отговорите!
 
Код:
<?php
function htmlspecialchars_m($s)
{
 $s=trim($s);
 if(get_magic_quotes_gpc())
 {
  if(ini_get('magic_quotes_sybase')=='1')
  return htmlspecialchars($s,ENT_QUOTES);
  else 
  return htmlspecialchars(stripslashes($s),ENT_QUOTES);
 }
 else 
 return htmlspecialchars($s,ENT_QUOTES); 
}
?>
 
Благодаря на всички, че се включихте с мнения!
Точката отива при jooorooo
 

Горе