Php 需要从用户提交的数据中筛选哪些文本?

Php 需要从用户提交的数据中筛选哪些文本?,php,mysql,forms,input,filter,Php,Mysql,Forms,Input,Filter,我正在尝试组合一些PHP验证函数,以筛选用户提交的表单数据中的任何字符或字符串,这将是潜在的安全风险。我已经采取了我知道的步骤,如下所列,但我希望确保我没有忽视任何事情 用户提供的数据过滤如下: 对于整数,我检查ctype_digit()是真还是假 对于其他可能包含小数的数字,我使用is_numeric() 对于电子邮件,我使用filter\u var()和filter\u VALIDATE\u EMAIL 对于IP地址,我使用filter\u var()和filter\u VALIDATE\

我正在尝试组合一些PHP验证函数,以筛选用户提交的表单数据中的任何字符或字符串,这将是潜在的安全风险。我已经采取了我知道的步骤,如下所列,但我希望确保我没有忽视任何事情

用户提供的数据过滤如下:

  • 对于整数,我检查ctype_digit()是真还是假
  • 对于其他可能包含小数的数字,我使用is_numeric()
  • 对于电子邮件,我使用filter\u var()和filter\u VALIDATE\u EMAIL
  • 对于IP地址,我使用filter\u var()和filter\u VALIDATE\u IP
  • 对于URL,我使用filter\u var()和filter\u VALIDATE\u URL
  • 对于HTML代码,我使用strip_标记(),同时允许:p、a、b、br、font、h1、h2、h3、h4、h5、h6、I、li、ol、span、ul、strong、div、img、article、section、header、footer、side、details、figcaption、figure、main、mark、nav、summary、time、pre、hr、style、svg、path
  • 对于RGBA,我使用filter_var()和filter_VALIDATE_REGEXP以及以下正则表达式:'/^([0-9]|[1-9][0-9]| 1[0-9][0-9]| 2[0-4][0-9]| 25[0-5]),{3}(0[0-9]+)?| 1.0+$/'
  • 为了验证时间戳,我检查它是否为整数,如果是,则将其传递给date()。如果它不是整数,我看DateTime::createFromFormat()是否可以解释它
使用准备好的语句将所有数据插入/更新到MySql。用户提交的所有非数字数据都使用htmlentities($val,ENT_引号,'UTF-8')输出到浏览器

目前为止,用户提交的文本可以包括姓名、地址、电子邮件、URL、电话号码、rgba值,也可以包括可能包含html格式的段落,例如

标题

某些段落文本……可以包括:标点符号(甚至括号)!

在我看来,我缺少的是过滤用户提交的常规文本中任何不安全的字符或字符串……但我不确定它们会是什么。使用预先准备好的语句/htmlentities是否足够?或者我是否应该做其他事情?另外-我当前的任何过滤器是否不正确

更新::

现在,我决定将filter\u var()与filter\u VALIDATE\u REGEXP一起用于所有其他尚未使用上述过滤器处理的文本。正则表达式允许我合理地认为在段落中使用的任何标点符号。据我所知,使用预先准备好的语句和htmlentities可以缓解我在使用引号、斜杠等字符时遇到的任何问题——所以我希望这是好的?任何反馈都很好。对于任何发现这一点的人来说都是值得的,我还使用preg_replace吐出一个违反正则表达式的字符列表——这样我就可以让用户知道哪些字符是无效的。我还使用了一些数组函数来过滤重复字符。代码是:

$rgx='[a-zA-Z0-9!#%&:;=@~"\'\/\\\^\*\-\_\.\?\+\(\)\$\s]';
  if(!filter_var($val,FILTER_VALIDATE_REGEXP,array('options'=>array('regexp'=>'/^'.$rgx.'+$/'))))
{

return'Error! May not contain '.implode(' ',array_unique(str_split(preg_replace('/'.$rgx.'/','',$val))));

}
对于您要查找的内容,没有“通用筛选/验证方法”。您必须始终在使用数据的特定上下文中验证和转义数据

重要提示:不要使用筛选,而是使用显式验证和白名单

示例:

  • 您将数据输入数据库,使用(正如您已经做的那样)准备好的语句(这是最好的…好吧,或者至少转义它们)
  • 再次将用户输入输出为HTML输出,请使用
    htmlentites()
    (防止XSS攻击)
  • 调用shell命令(例如,用于压缩图像或处理特定的csv文件),然后使用
    escapeshellcmd()
    escapeshellarg()
  • 如果要验证电子邮件地址是否正确,请不要编写自己的正则表达式,而是使用现有的验证类。 等等
对于您要查找的内容,没有“通用筛选/验证方法”。您必须始终在使用数据的特定上下文中验证和转义数据

重要提示:不要使用筛选,而是使用显式验证和白名单

示例:

  • 您将数据输入数据库,使用(正如您已经做的那样)准备好的语句(这是最好的…好吧,或者至少转义它们)
  • 再次将用户输入输出为HTML输出,请使用
    htmlentites()
    (防止XSS攻击)
  • 调用shell命令(例如,用于压缩图像或处理特定的csv文件),然后使用
    escapeshellcmd()
    escapeshellarg()
  • 如果要验证电子邮件地址是否正确,请不要编写自己的正则表达式,而是使用现有的验证类。 等等

这完全取决于上下文。如果您在一个html上下文中,您需要确保您已经将所有有意义的特殊字符转换为html实体;如果要在属性或js var等中输出某些内容,则需要考虑其他因素;使用预先准备好的语句,而不是仅仅转义内容并将其放入查询中,这很好-其余部分取决于您的应用程序需要(即,在存储之前,您希望确保用户的电子邮件确实是电子邮件,或者其生日不落在用户提供的empy字符串“”上,等等),据我所知,使用filter\u var()和filter\u VALIDATE\u EMAIL应该确保电子邮件的格式至少是正确的——我认为通过date()和DateTime::createFromFormat()传递日期应该确保它们是有效的日期。我相信,正如我所提到的,以htmlentities($val,entu QUOTES,'UTF-8')格式输出文本涵盖了“所有对HTML实体有意义的特殊字符”-对吗?数据由用户通过我们网站上的表单提交,用PHP处理,存储在MySql数据库中,使用PHP检索,并可能在用户帐户的不同位置显示,或