简体   繁体   English

PHP表单输入过滤

[英]PHP Form Input Filtering

I am a PHP newbie and am working on a basic form validation script. 我是PHP新手,正在研究基本的表单验证脚本。 I understand that input filtering and output escaping are both vital for security reasons. 我知道,出于安全考虑,输入过滤和输出转义都至关重要。 My question is whether or not the code I have written below is adequately secure? 我的问题是我下面编写的代码是否足够安全? A few clarifying notes first. 首先要澄清一些注意事项。

  1. I understand there is a difference between sanitizing and validating. 我了解消毒与验证之间是有区别的。 In the example field below, the field is plain text, so all I need to do is sanitize it. 在下面的示例字段中,该字段为纯文本,因此我需要做的是清理它。
  2. $clean['myfield'] is the value I would send to a MySQL database. $ clean ['myfield']是我要发送到MySQL数据库的值。 I am using prepared statements for my database interaction. 我正在使用准备好的语句进行数据库交互。
  3. $html['myfield'] is the value I am sending back to the client so that when s/he submits the form with invalid/incomplete data, the sanitized fields that have data in them will be repopulated so they don't have to type everything in from scratch. $ html ['myfield']是我发送回客户端的值,以便当他/她提交包含无效/不完整数据的表单时,将重新填充其中包含数据的已清理字段,因此他们不必从头开始输入所有内容。

Here is the (slightly cleaned up) code: 这是(稍作清理)的代码:

$clean = array();
$html = array();
$_POST['fname'] = filter_var($_POST['fname'], FILTER_SANITIZE_STRING);
$clean['fname'] = $_POST['fname'];
$html['fname'] = htmlentities($clean['fname'], ENT_QUOTES, 'UTF-8');
if ($_POST['fname'] == "") {
    $formerrors .= 'Please enter a valid first name.<br/><br/>';
}
else {
    $formerrors .= 'Name is valid!<br/><br/>';
}

Thanks for your help! 谢谢你的帮助!

~Jared 〜贾里德

I understand that input filtering and output escaping are both vital for security reasons. 我知道,出于安全考虑,输入过滤和输出转义都至关重要。

I'd say rather that output escaping is vital for security and correctness reasons, and input filtering is potentially-useful measure for defence-in-depth and to enforce specific application rules. 我要说的是,出于安全性和正确性的原因,输出转义至关重要,而输入过滤对于深度防御和实施特定的应用程序规则可能是有用的措施。

The input filtering step and the output escaping step are necessarily separate concerns, and cannot be combined into one step, not least because there are many different types of output escaping, and the right one has to be chosen for each output context (eg HTML-escaping in a page, URL-escaping to make a link, SQL-escaping, and so on). 输入过滤步骤和输出转义步骤必定是单独的关注点,不能合并为一个步骤,不仅因为存在许多不同类型的输出转义,而且必须为每个输出上下文选择正确的转义(例如HTML-在页面中转义,在URL中转义以创建链接,在SQL中转义等)。

Unfortunately PHP is traditionally very hazy on these issues and so offers a bunch of mixed-message functions that are likely to mislead you. 不幸的是,PHP通常在这些问题上都很模糊,因此提供了很多混合消息功能,这些功能可能会误导您。

In the example field below, the field is plain text, so all I need to do is sanitize it. 在下面的示例字段中,该字段为纯文本,因此我需要做的是清理它。

Yes. 是。 Alas, FILTER_SANITIZE_STRING is not in any way a sane sanitiser. las, FILTER_SANITIZE_STRING绝对不是理智的解决方案。 It completely removes some content ( strip_tags , which is itself highly non-sensible) whilst HTML-escaping other content. 它完全删除了某些内容( strip_tags ,这本身是非常不明智的),而HTML则转义了其他内容。 eg quotes turn into &#34; 例如,引号变成&#34; . This is a nonsense. 这是胡说八道。

Instead, for input sanitisation, look at: 相反,要进行输入卫生检查,请查看:

  • checking it's a valid string for the encoding you're using (hopefully UTF-8; see eg this regex for that); 检查它是您正在使用的编码的有效字符串(希望是UTF-8;有关此信息 ,请参见此正则表达式 );

  • removing control characters, U+0000–U+001F and U+007F–U+009F. 删除控制字符U + 0000–U + 001F和U + 007F–U + 009F。 Allow the newline through only on deliberate multi-line text fields; 只允许在故意的多行文本字段中使用换行符;

  • removing the characters that are not suitable for use in markup ; 删除不适合在标记中使用的字符;

  • validating the input conforms to application requirements on a field-by-field basis, for data whose content model is more specific than arbitrary text strings. 对于内容模型比任意文本字符串更具体的数据,验证输入符合每个字段的应用程序要求。 Although your escaping should handle a < character correctly, it's probably a good idea to get rid of it early in fields where it makes no sense to have one. 尽管转义应正确处理<字符,但在没有意义的领域中尽早删除它可能是一个好主意。

For the output escaping step I'd generally prefer htmlspecialchars() to htmlentities() , though your correct use of the UTF-8 argument stops the latter function breaking in the way it usually does. 对于输出转义步骤,我通常更喜欢htmlspecialchars()而不是htmlentities() ,尽管您正确使用UTF-8参数可以阻止后者以通常的方式破坏。

Depending on what you want to secure, the filter you call might be overactive (see comments). 根据您要保护的内容,您调用的过滤器可能会处于活动状态 (请参阅注释)。 Injectionwise you should be safe since you're using Prepared Statements (see this answer ) 注射方式,您应该很安全,因为您正在使用预处理语句(请参阅此答案

On a design note you might want to filter first, then check for empty values. 在设计说明上,您可能要先过滤,然后检查空值。 Doing that you can shorten your code ;) 这样做可以缩短代码;)

I understand that input filtering ... is vital for security reasons. 我了解输入过滤...出于安全原因至关重要。

This is wrong statement. 这是错误的陈述。
Although it can be right in some circumstances, in such a generalised form it can do no good but false feeling of safety. 尽管在某些情况下可能是正确的,但以这种概括的形式,它只能带来良好的安全感,而不会带来错误的安全感。

all I need to do is sanitize it. 我需要做的就是消毒它。

There is no such thing like " general sanitizing ". 没有像“ 一般消毒 ”这样的东西。 You have to understand each particular case and it's limitations. 您必须了解每个特定案例及其局限性。 For example, for the database you need to use several different sanitization techniques, not one. 例如,对于数据库,您需要使用几种不同的清理技术,而不是一种。 While for the filenames it is going to be completely different one. 虽然文件名将完全不同。

I am using prepared statements for my database interaction. 我正在使用准备好的语句进行数据库交互。

Thus, you should not touch the data at all. 因此,您根本不应触摸数据。 Just leave it as is. 保持原样。

Here is the (slightly cleaned up) code: 这是(稍作清理)的代码:

It seems there is some overkill in your code. 看来您的代码有些过高。
you are cleaning your HTML data twice while it is possible that you won't need it at all. 您将清理两次HTML数据,而有可能根本不需要它。 and for some reason you are raising an error on success. 由于某种原因,您在成功时提出了错误。

I'd make it rather this way 我宁愿这样

$formerrors = '';
if ($_POST['fname'] == "") {
    $formerrors .= 'Please enter a valid first name.<br/><br/>';
}

if (!$formerrors) {
  $html = array();
  foreach ($_POST as $key => $val) {
    $html[$key] = htmlspecialchars($val,ENT_QUOTES);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM