简体   繁体   English

PHP 输入 GET 变量清理

[英]PHP input GET vars sanitizing

For my application, written in PHP 5+, I have a common.php which is included from all other pages.对于我用 PHP 5+ 编写的应用程序,我有一个common.php ,它包含在所有其他页面中。 Within that I have an include sanitize.php which aims to sanitise any input vars used in the URL.其中我有一个include sanitize.php ,它旨在清理 URL 中使用的任何输入变量。 So, targetting $_GET[] values.因此,针对$_GET[]值。

This is just to have one place where I can tidy any vars, if used, and use them in the code later.这只是为了让我可以整理任何变量(如果使用)的地方,并在以后的代码中使用它们。

There seems to be no tidy way, I've seen, to sanitise based on expected/desired inputs.我见过,似乎没有一种整洁的方法可以根据预期/所需的输入进行消毒。 The method I initially looked at was this sanitize.php having a foreach to loop through any vars, lookup the type of sanitization required, and then add the cleaned vars to a separate array for use within my code.我最初看到的方法是这个sanitize.php有一个 foreach 来循环遍历任何变量,查找所需的清理类型,然后将清理过的变量添加到一个单独的数组中以在我的代码中使用。

Instead of using PHP sanitization filters, to keep it standard, I thought I'd use regex.为了保持标准,我想我会使用正则表达式,而不是使用 PHP 消毒过滤器。 Types I want are alphaonly , alphanumeric , email , password .我想要的类型是alphaonlyalphanumericemailpassword Although "password" would allow some special chars, I want to remove or even escape potentially "hazardous" ones like ' " to then be included into a mysql DB. We have a european userbase so different locales are possible, but I'm hoping that won't be too much of an issue.虽然“密码”会允许一些特殊字符,但我想删除甚至转义潜在的“危险”字符,例如' " ,然后将其包含到 mysql 数据库中。我们有一个欧洲用户群,因此可以使用不同的语言环境,但我希望那不会有太大问题。

Would this be a "good" solution to start from, or am I trying to reinvent the wheel?这是一个“好的”解决方案,还是我试图重新发明轮子?

Random Page随机页面

/mypage.php?c=userid&p=lkasjdlakjsdlakj&z=....
(use SANITIZED_SAFE_INPUT_VARS variable only)

sanitize.php消毒.php

var aryAllowedGetParamNames = array(
    "c" => "alphaonly",         //login
    "p" => "alphaemail",        //password
    "e" => "email"              //email
    //...
);

var sanitizeTypes = array (
    "alphaonly" => "[a-zA-Z]",
    "alphanumeric" => "[a-zA-Z0-9]",
    "email" => "[a-zA-Z0-9]...etc"
);

var SANITIZED_SAFE_INPUT_VARS = array();

foreach ($_GET as $key => $value) { 
    //apply regex and add value to SANITIZED_SAFE_INPUT_VARS 
}

EDIT编辑

There seems to be some opinion about the use of passwords in the URL.似乎有一些关于在 URL 中使用密码的意见。 I'll explain in a little more detail.我会更详细地解释一下。 Instead of using a POST login prompt with username and password, I am using an ajax async call to _db_tryLogin.php with parameters for userid and password.我没有使用带有用户名和密码的 POST 登录提示,而是使用对_db_tryLogin.php的 ajax 异步调用以及用户 ID 和密码的参数。 The username is ALWAYS a 6-ALPHA-only text string, and the password is an md5 of what was typed.用户名总是一个只有 6 个字母的文本字符串,密码是输入的 md5。 I'm aware of the opinions on MD5 not being "safe enough".我知道关于 MD5 的意见“不够安全”。

The JS currently MD5s the password and sends that to the _db_tryLogin.php . JS 当前对密码进行 MD5s 并将其发送到_db_tryLogin.php

-> async : _db_login.php?c=ABCDEF&p=SLKDauwfLKASFUWPOjkjafkKoAWOIFHF2733287

This will return an async response of "1" or "0".这将返回“1”或“0”的异步响应。 Both will cause the page to refresh, but if the _db_tryLogin.php page detects the password and userid matches one DB record, then session variables are set and the site knows the user is logged in.两者都会导致页面刷新,但如果_db_tryLogin.php页面检测到密码和用户 ID 与一条 DB 记录匹配,则设置会话变量并且站点知道用户已登录。

I used MD5 for the async request just to quickly hash the password so it's not transmitted in plaintext.我将 MD5 用于异步请求只是为了快速散列密码,因此它不会以明文形式传输。

The _db_tryLogin.php takes the password, which is md5(plainpass) adds a SALT and MD5s again, and then this is what is compared against the usertable in the DB. _db_tryLogin.php获取密码,即md5(plainpass)再次添加 SALT 和md5(plainpass) ,然后将其与 DB 中的 usertable 进行比较。

DB password stored = md5(SALT.md5(plainpass))存储的数据库密码 = md5(SALT.md5(plainpass))

What are you sanitising against?你在消毒什么? If you're [only] trying to protect your SQL database you're doing it wrong, and should be looking into Prepared Statements .如果您 [仅] 试图保护您的 SQL 数据库,那么您就做错了,应该查看Prepared Statements

USER SUBMITTED DATA SHOULD NEVER BE TRUSTED.用户提交的数据应该是可信的。 Accepted, yes, trusted - No.接受,是,信任 - 否。

Rather than going through a long tedious process of allowing certain chararacters, simply disallow (ie remove) characters you don't want to accept, such as non-alphanumeric or backtick characters etc. It may also save you a lot of efforts to use the PHP strip_tags() function.与其经历一个冗长乏味的允许某些字符的过程,不如简单地禁止(即删除)您不想接受的字符,例如非字母数字或反引号字符等。使用PHP strip_tags()函数。

1) Create your function in your include file. 1) 在你的包含文件中创建你的函数。 I would recommend creating it in an abstract Static Class , but that's a little beyond the scope of this answer.我建议在一个抽象的 Static Class 中创建它,但这有点超出了这个答案的范围。

2) Within this function/class method add your definitions for what bad characters you're looking for, and the data that these checks would apply to. 2) 在这个函数/类方法中,添加你要查找的坏字符的定义,以及这些检查将适用的数据。 You seem to have a good idea of your logic process, but be aware that there is no definitively correct code answer, as each programmers' needs from a string are different.您似乎对自己的逻辑过程很了解,但请注意,没有绝对正确的代码答案,因为每个程序员对字符串的需求各不相同。

3) using the criteria defined in (2) you can then use the Regex to remove non-valid characters to return a "safe" set of variables. 3) 使用 (2) 中定义的标准,然后您可以使用 Regex 删除无效字符以返回一组“安全”变量。

example:例子:

   // Remove backtick, single and double quotes from a variable.  
   // using PCRE Regex.
   $data = preg_relace("/[`"']/","",$data);

4) Use the PHP function strip_tags() to do just that and remove HTML and PHP code from a string. 4) 使用 PHP 函数strip_tags()执行此操作并从字符串中删除 HTML 和 PHP 代码。

5) For email validation use the PHP $email = filter_var($data, FILTER_SANITIZE_EMAIL); 5) 对于电子邮件验证,使用 PHP $email = filter_var($data, FILTER_SANITIZE_EMAIL); function, it will be far better than your own simple regex.功能,它会比你自己的简单正则表达式好得多。 Use PHP Filter Validations they are intended exactly for your sort of situation.使用PHP 过滤器验证,它们完全适用于您的情况。

6) NEVER trust the output data, even if it passes all the checks and regexes you can give it, something may still get through. 6)永远不要相信输出数据,即使它通过了您可以提供的所有检查和正则表达式,但仍有一些事情可能会通过。 ALWAYS be VERY wary of user submitted data.始终非常警惕用户提交的数据。 NEVER trust it.永远不要相信它。

7) Use Prepared Statements for your SQL interactions. 7) 为您的 SQL 交互使用准备好的语句。

8) As a shortcut for number types (int / float) you can use PHP type-casting to force a given varibles to being a certain type and destroying any chance of it being anything else: 8) 作为数字类型 (int / float) 的快捷方式,您可以使用 PHP 类型转换来强制给定变量成为某种类型并破坏它成为其他任何类型的机会:

$number = $_GET['number']; //can be anything.
$number = (int)$_GET['number']; //must be an integer or zero.

Notes:笔记:

  • Passwords should not be az only, but should be as many characters as you are able to choose from, the more the better.密码应该只是az ,而应该是您可以选择的字符数,越多越好。

  • If the efforts you are actioning here are for the case of protecting database security and integrity, you're doing it wrong, and should be using Prepared Statements for your MySQL interactions.如果您在此处采取的措施是为了保护数据库的安全性和完整性,那么您就做错了,应该在 MySQL 交互中使用Prepared Statements

  • Stop using var to declare variables as this is from PHP4 and is VERY old , it is far better to use the Variable preconditional $ (such as $variable = true; ) .停止使用var来声明变量,因为它来自 PHP4 并且非常旧,使用变量前置条件$ (例如$variable = true; )要好得多。

  • You state:你说:

    We have a european userbase so different locales are possible我们有一个欧洲用户群,因此可以使用不同的语言环境

    To which I would highly recommend exploring PHP mb_string functions because natively PHP is not mutlibyte safe.我强烈建议您探索PHP mb_string函数,因为 PHP 本身并不是多字节安全的。

I would to start just regex each variable , apply null if it doesn't match the requirements.我只想开始正则表达式每个变量,如果它不符合要求,则应用 null。 Either test what it SHOULD have only, or what it shouldn't have, whichever is smaller:要么测试它应该只有什么,或者它不应该有什么,以较小者为准:

$safeValue = (preg_match('/^[a-zA-Z0-9]{0,5}$/',$value) ? $value : "");

ALONG with prepared statements with parameter input aka ALONG 带有参数输入的预准备语句又名

$query = "SELECT x FROM table WHERE id=?";
bind_param("si",$var,$var)

PHP also comes in with built filters, such as email and others). PHP 还带有内置过滤器,例如电子邮件和其他过滤器)。 Example: filter_var($data, FILTER_SANITIZE_EMAIL)示例: filter_var($data, FILTER_SANITIZE_EMAIL)

http://php.net/manual/en/filter.filters.sanitize.php http://php.net/manual/en/filter.filters.sanitize.php

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

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