Php 使用filter\u input和filter\u SANITIZE\u NUMBER\u INT清理GET

Php 使用filter\u input和filter\u SANITIZE\u NUMBER\u INT清理GET,php,validation,Php,Validation,我有一个主键为ID的表。ID将被传递到页面,如下所示: testpage.php?ID=123. 如果我使用: $sanitized_id = filter_input(INPUT_GET, 'ID', FILTER_SANITIZE_NUMBER_INT) $sanitized\u id可以安全地用于查询吗?它即将就绪。虽然SQL注入应该通过预先准备好的语句来防止,但是仍然需要严格且干净的URL。对于这个目的,你的代码是不够的。例如,T中的FILTER\u SANITIZE\u NUMB

我有一个主键为ID的表。ID将被传递到页面,如下所示:

testpage.php?ID=123.
如果我使用:

$sanitized_id = filter_input(INPUT_GET, 'ID', FILTER_SANITIZE_NUMBER_INT) 

$sanitized\u id可以安全地用于查询吗?

它即将就绪。虽然SQL注入应该通过预先准备好的语句来防止,但是仍然需要严格且干净的URL。对于这个目的,你的代码是不够的。例如,T中的
FILTER\u SANITIZE\u NUMBER\u不会删除减号

下面是我使用的一些代码。我几乎只是从我现有的一个项目中复制并粘贴了它。我刚换了身份证,放了回音

if (empty($_GET['ID'])) {
    echo('ID is empty');
    exit;
}

$sanitized_id = filter_input(INPUT_GET, 'ID', FILTER_SANITIZE_NUMBER_INT);
$sanitized_id = str_replace('-', '', $sanitized_id); //Get rid of any - signs
if (($sanitized_id != $_GET['ID']) || (strlen($sanitized_id) != strlen($_GET['ID']))) {
    //strlen catches if + signs are included, I'm really strict at what I allow on the URL
    echo('Invalid url');
    exit;
}

echo('The sanitized ID is: ' . $sanitized_id);

快准备好了。虽然SQL注入应该通过预先准备好的语句来防止,但是仍然需要严格且干净的URL。对于这个目的,你的代码是不够的。例如,
T中的
FILTER\u SANITIZE\u NUMBER\u不会删除减号

下面是我使用的一些代码。我几乎只是从我现有的一个项目中复制并粘贴了它。我刚换了身份证,放了回音

if (empty($_GET['ID'])) {
    echo('ID is empty');
    exit;
}

$sanitized_id = filter_input(INPUT_GET, 'ID', FILTER_SANITIZE_NUMBER_INT);
$sanitized_id = str_replace('-', '', $sanitized_id); //Get rid of any - signs
if (($sanitized_id != $_GET['ID']) || (strlen($sanitized_id) != strlen($_GET['ID']))) {
    //strlen catches if + signs are included, I'm really strict at what I allow on the URL
    echo('Invalid url');
    exit;
}

echo('The sanitized ID is: ' . $sanitized_id);

有两种非常简单的方法可以确保条目为整数:

铸造:

$myInt = (int) $_GET['ID'];
使用
intval()

$myInt = intval($_GET['ID']);

filter\u input()
函数有很好的过滤器,特别是用于清理电子邮件、URL或IP地址,但实际上,使用它来清理整数太过分了。

有两种非常简单的方法来确保条目为整数:

铸造:

$myInt = (int) $_GET['ID'];
使用
intval()

$myInt = intval($_GET['ID']);

filter\u input()
函数有很好的过滤器,特别是用于清理电子邮件、URL或IP地址,但实际上,使用它清理整数太过分了。

我建议进一步清理并执行验证:

$id = filter_input(INPUT_GET, 'ID', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
if ($id === null) {
    die("Die, evil request, die!");
}
// post: $id is a valid integer

最重要的是,无论如何,我还是会去的;在这段代码中,很明显ID必须是有效的整数,但一旦数据库代码与请求处理进一步分离,您将需要一些保证。

我建议进一步执行验证,而不是清除:

$id = filter_input(INPUT_GET, 'ID', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
if ($id === null) {
    die("Die, evil request, die!");
}
// post: $id is a valid integer
最重要的是,无论如何,我还是会去的;在这段代码中,ID显然必须是有效的整数,但一旦数据库代码与请求处理进一步分离,您将需要一些保证

$sanitized_id可以安全地用于查询吗

没有

无论输入验证是什么,都与“在查询中使用数据”无关

在一个设计合理的应用程序中,这些层(输入验证和数据库交互)应该分开,并且彼此距离太远。数据库层应该完全不知道数据的来源、来源、性质或任何验证

因此,无论在入口点执行哪种验证,在数据库级别都必须使用准备好的语句

$sanitized_id可以安全地用于查询吗

没有

无论输入验证是什么,都与“在查询中使用数据”无关

在一个设计合理的应用程序中,这些层(输入验证和数据库交互)应该分开,并且彼此距离太远。数据库层应该完全不知道数据的来源、来源、性质或任何验证


因此,无论您在入口点执行何种验证,在数据库级别,您都必须使用准备好的语句。

--
将被允许通过。我宁愿将其转换为int:
$sanitized\u id=(int)$\u GET['id']为什么不使用参数化查询并停止担心所有这些?您可以使用
过滤器\u验证\u INT
而不是使用消毒过滤器;这将产生
false
(或null)或有效整数。@Shankar,我不认为在这种情况下仅使用参数化查询就足够了。我仍然需要ID为整数。如果ID=abc-12/3,它将不起作用。@如果它起作用,参数化查询将产生净效果,即
ID=0
--
将被允许通过。我宁愿将其转换为int:
$sanitized\u id=(int)$\u GET['id']为什么不使用参数化查询并停止担心所有这些?您可以使用
过滤器\u验证\u INT
而不是使用消毒过滤器;这将产生
false
(或null)或有效整数。@Shankar,我不认为在这种情况下仅使用参数化查询就足够了。我仍然需要ID为整数。如果ID=abc-12/3,它将不起作用。@TimT它将起作用,参数化查询将产生
ID=0
的净效果。我真的不知道为什么好的答案永远不会被选中?我真的不知道为什么好的答案永远不会被选中?所有这些乱七八糟的东西都是无用的。众所周知,PHP用户习惯于无中生有地编写大量代码,但这只是一个无用工作的典范。@Your,我同意,在这种情况下,这是过火了。我昨晚真的想过了。我认为演员阵容可能足以满足他的需要。这个问题的一个原始标签是sql注入,所以即使问题中没有说明,他也会想到它。我在我的两个页面上使用了一些类似的代码,这两个页面受到sql注入尝试的沉重打击。我的apache日志文件显示了所有类型的攻击这些页面的尝试,包括随机放置加号的尝试。继续…继续。。。如果其中一个页面需要一个整数,而它得到了其他任何东西,我认为这是一个格式错误的URL,我不想浪费更多的资源来显示实际的页面。同时,我正在记录一些信息,以确保URL不是来自需要修复的其他页面的合法请求。到目前为止,所有格式错误的URL都是假的。所以在我的例子中,代码并不是无用的。仍然有两个不同的问题——输入验证和sql注入保护。关键是,前者