单击超链接时发送隐藏变量,保护sql

时间:2012-11-22 11:21:31

标签: php mysql

我想先用$ _POST传递隐藏变量,但我已经意识到用户可以像$ _GET一样轻松地更改$ _POST。有可能以某种方式限制这种能力,还是有另一种方法来做到这一点?另外,在下面的这个简单示例中,您似乎无法使用$ _POST?:

的index.php

    <a href="test.php?variable=<?php echo $row['recipe_id'];?>"><view recipe</a>

test.php的

    $variable = $_GET['variable'];
    $query = $database->query("SELECT name, description, date_added from recipe where recipe_id = $variable");

(编辑:我确实检查输入确实是一个整数,虽然我跳过了上面这个以最小化示例的代码。我应该先说清楚)。 我想用户可以在这里做的唯一边界“恶意”事情是循环通过recipe_id:s来查找数据库中有多少食谱,甚至是通过更改$变量添加的第一个食谱。并不是我在这种特殊情况下关心,但我确定在涉及其他例子时我会这样做。我意识到我想提供信息,我只是想让它通过“正确的渠道”我想。这只是事情的方式,还是我错过了重要的事情?

人们总是写“验证你的输入”之类的东西。我同意这一点。但在这种情况下,它只是用户“输入”的一个整数。除了验证之外还可以做些什么?再次,我慢慢地进步/学习这个,所以请耐心等待,如果我似乎犯了简单的错误。

(使用PHP,PDO,Mysql) 谢谢!

5 个答案:

答案 0 :(得分:1)

关于HTTP requests的全部内容。浏览器通过HTTP请求与服务器通信。这些完全透明给用户,但是你看一下。在浏览器(或Firebug,或Fiddler或其他任何东西)中打开 Web Inspector 并检查原始HTTP请求。任何人都可以随时将这些请求发送到您的服务器,包含任何数据。

理解这个概念,很重要。在服务器和客户端(来自客户端的POV)之间的通信中没有“秘密”信息。 您无法控制服务器的输入。也无法“隐藏”从客户端到服务器的任何数据。

HTTP请求表示数据或某些操作的请求。服务器应该尽最大努力提供请求。如果请求无效,则服务器必须拒绝它。服务器应该独立于每个其他请求判断每个请求的有效性,它应该是无状态的。服务器无法在不验证任何请求的情况下设定其有效性。它应该只输出不安全敏感的信息,并将所有传入数据视为可疑数据。这就是生活中的事实。

答案 1 :(得分:0)

如果您不希望用户看到可以轻松修改的增量配方ID,则生成用于识别配方的唯一随机字符串。这将阻止用户在GET或POST数据中使用配方ID。

他们仍然可以修改它,但是他们需要获取随机字符串以便提取食谱。

答案 2 :(得分:0)

“变量”不限于代码中的整数。恶意用户可能会将“变量”的值更改为“';截断配方; - ”。执行这个并且呐喊......所有的食谱都消失了。

始终确保您使用正确的验证。在interwebs中搜索“sql注入”并查看mysql_real_escape_string等函数(以及它的文档)。

答案 3 :(得分:0)

请求字段的内容,无论是$_POST还是$_GET,都不会输入。它只是简单的字符串,这意味着它几乎是客户端的“开放游戏”。这就是我们不断重复客户端输入无法信任的原因,并且必须在服务器端进行验证。

关于您的第二个问题:回想一下$_GET将使用获取 method包含表单的结果,而$_POST将包含来自发布 method表单。 $_GET目的是包含url参数(如果存在)(确切地说, get method表单将通过url传递其所有参数)。

另一方面,我还应该告诉你,你不应该使用一个动词作为另一个动词,每个动词都是一个特定目的。 get method是关于获取数据而非更新数据,而发布 put delete 是关于更新数据。这意味着您的示例遵循这些规则,并且不应尝试使用 post 表单(尽管这在技术上是可行的,您只需要用表单替换链接标记)。

请参阅the HTTP specs此事。

答案 4 :(得分:-1)

您可以创建基于会话的权限系统:

当用户访问您的网站,并且他/她的浏览器呈现链接时,在该php中,您为该链接设置会话变量,

$_SESSION["permitted_recipe_id"] = $row['recipe_id'];

现在你知道用户可以点击什么食谱ID,

用这个检查:

$variable = $_GET['variable'];
if($variable != @$_SESSION["permitted_recipe_id"]){
   exit("error you do not access to this result");
}

 $query = $database->query("SELECT name, description, date_added from recipe where recipe_id = $variable");

这将确保用户在发送请求之前访问了该页面。该解决方案将阻止连续的POST请求获取所有网站数据,

如果您显示用户可以单击的多个链接,则必须将$ _SESSION [“allowed_recipe_id”]实现为包含作为链接发送给用户的所有ID的数组。

但请注意,多标签体验可能会为此解决方案带来错误。这是一个想法,你必须仔细研究它以获得相关的环境解决方案。