问题描述
我正在从事一个个人项目,除了使用准备好的语句外,我还想将每个输入都用作威胁.为此,我做了一个简单的函数.
I'm working in a personal project and besides using prepared statements, I would like to use every input as threat. For that I made a simple function.
function clean($input){
if (is_array($input)){
foreach ($input as $key => $val){
$output[$key] = clean($val);
}
}else{
$output = (string) $input;
if (get_magic_quotes_gpc()){
$output = stripslashes($output);
}
$output = htmlentities($output, ENT_QUOTES, 'UTF-8');
}
return $output;
}
这是不够的还是我应该使用以下代码?
Is this enought or should I use to the following code?
$output = mysqli_real_escape_string($base, $input);
$output = strip_tags($output);
对不起,这可能是一个愚蠢的问题,但我想避免我的代码出现任何问题:)感谢您的帮助
Sorry this could be a silly question but I would like to avoid any problem with me code :)Thanks for your help
推荐答案
我为你的努力鼓掌.友好的社区成员,您必须考虑将您的业务脱钩.
I applaud your efforts.You must, friendly community member, consider decoupling your operations.
1) 有一个过滤输入的函数/例程/类/方法 (filter_input_array()
, strip_tags()
, str_ireplace()
、trim()
等...).您可能想要创建使用循环进行过滤的函数.双重编码、一次性欺骗等技巧可以打败诸如 strip_tags()
之类的东西的单次使用.
1) Have one function/routine/class/method for filtering input (filter_input_array()
, strip_tags()
, str_ireplace()
, trim()
, etc ...). You may want to create functions that use loops to do filtering. Tricks such as double encoding, one-time-strip-spoofing, and more can defeat single usage of things like strip_tags()
.
这是我的 Sanitizer
类中的 strip_tags()
包装方法.请注意它如何将旧值与新值进行比较以查看它们是否相等.如果它们不相等,则继续使用 strip_tags()
.虽然,在执行此方法之前完成了相当多的初步 INPUT_POST/$_POST 检查.使用 trim()
的另一个版本实际上在这个版本之前执行.
Here is a strip_tags()
wrapper method from my Sanitizer
class.Notice how it compares the old value to the new value to see if they are equal. If they are not equal, it keeps on using strip_tags()
. Although, there is quite of bit of preliminary INPUT_POST / $_POST checking done before this method is executed. Another version of this using trim()
is actually executed before this one.
private function removeHtml(&$value)
{
if (is_scalar($value)) {
do {
$old = $value;
$value = strip_tags($value);
if ($value === $old) {
break;
}
} while(1);
} else if (is_array($value) && !empty($value)) {
foreach ($value as $field => &$string) {
do {
$old = $string;
$string = strip_tags($string);
if ($string === $old) {
break;
}
} while (1);
}
} else {
throw new Exception('The data being HTML sanitized is neither scalar nor in an array.');
}
return;
}
2) 还有一个用于验证输入 (filter_var_array()
, preg_match()
, mb_strlen
,等等...)
2) Have another one for validating input (filter_var_array()
, preg_match()
, mb_strlen
, etc...)
那么,当你的数据需要切换上下文时......
Then, when your data needs to switch contexts ...
A) 对于数据库,使用准备好的语句(PDO
,最好).
A) For databases, use prepared statements (PDO
, preferably).
B) 为了将用户输入返回/传输到浏览器,使用 htmlentities()
或 htmlspecialchars
对输出进行转义代码>相应地.
B) For returning / transmitting user input to the browser, escape the output with htmlentities()
or htmlspecialchars
accordingly.
就魔术引号而言,最好的做法是在 php.ini
中禁用它.
In terms of magic quotes, the best thing to do is just disable that in the php.ini
.
现在,由于这些不同的构造都有自己的职责范围,您所要做的就是管理处理程序文件中的逻辑和数据流.这包括向用户提供错误消息(必要时)和处理错误/异常.
Now, with those various constructs having their own areas of responsibility, all you have to do is manage the flow of logic and data inside of your handler file. This includes providing error messages to the user (when necessary) and handling errors/exceptions.
如果数据直接从 HTML 表单进入数据库,则无需立即使用 htmlentities()
或 htmlspecialchars
.转义数据的目的是防止将其解释为新上下文中的可执行指令.将数据传递给 SQL 查询引擎时,htmlentities()
或 htmlspecialchars
没有任何危险可以解决(这就是为什么您过滤和验证输入,并使用 (PDO
) 准备好的语句).
There is no need to use htmlentities()
or htmlspecialchars
immediately if the data is going from the HTML form directly into the database. The point of escaping data is to prevent it from being interpreted as executable instructions inside a new context. There is no danger htmlentities()
or htmlspecialchars
can resolve when passing data to a SQL query engine (that is why you filter and validate the input, and use (PDO
) prepared statements).
但是,在从数据库表和检索数据后,直接发送给浏览器,就可以了,现在使用 htmlentities()
或 htmlspecialchars
.创建一个 function
,使用 for
或 foreach
循环来处理该场景.
However, after the data is retrieved from database tables and is directly destined for the browser, ok, now use htmlentities()
or htmlspecialchars
. Create a function
that uses a for
or foreach
loop to handle that scenario.
这是我的 Escaper
类的片段
public function superHtmlSpecialChars($html)
{
return htmlspecialchars($html, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
}
public function superHtmlEntities(&$html)
{
$html = htmlentities($html, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
}
public function htmlSpecialCharsArray(array &$html)
{
foreach ($html as &$value) {
$value = $this->superHtmlSpecialChars($value);
}
unset($value);
}
public function htmlEntitiesArray(array &$html)
{
foreach ($html as &$value) {
$this->superHtmlEntities($value);
}
unset($value);
}
您必须根据自己的个人品味和情况定制代码.
You'll have to tailor your code to your own personal tastes and situation.
请注意,如果您打算在将数据发送到浏览器之前对其进行处理,请先进行处理,然后使用方便的 htmlentities()
或 htmlspecialchars
进行转义循环功能.
Note, if you plan on processing the data before sending it to the browser, do the processing first, then escape with your handy-dandy htmlentities()
or htmlspecialchars
looping function.
你可以做到!
这篇关于PHP 安全性(strip_tags、htmlentities)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!