0

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

索引.php

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

测试.php

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

(编辑:我确实检查了输入确实是一个整数,尽管我在上面跳过了这个以最小化示例的代码。我应该早点说清楚)。我想用户在这里可以做的唯一边缘“恶意”事情是循环通过 recipe_id:s 来找出数据库中有多少食谱,甚至是通过更改 $variable 添加的第一个食谱。并不是说我在乎这种特殊情况,但我确信在涉及其他示例时我会。我意识到我想让信息可用,我只是想让它通过我猜的“适当渠道”。这只是事情的方式还是我错过了一些重要的事情?

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

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

4

5 回答 5

1

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

Understand this concept, it is important. There's no such thing as "secret" information in the communication between your server and the client (from the POV of the client). You do not control the input to your server. Neither can you "hide" any data that is going from the client to your server.

An HTTP request represents a, well, request for data or for some action. The server should, well, serve the request to the best of its abilities. If a request is invalid, the server must reject it. The server should judge the validity of each request independently of every other request, it should be stateless. The server cannot presume the validity of any request without validating it. It should only ever output information which is not security sensitive and treat all incoming data as suspicious. That's the fact of life.

于 2012-11-22T11:26:10.490 回答
0

If you don't want users to see an incremental recipe ID that they can easily modify, then generate a unique random string to use to identify recipes. This will stop users from being able to play with the recipe ID in the GET or POST data.

They can still modify it but they will need to obtain the random string in order to pull out a recipe.

于 2012-11-22T11:26:38.583 回答
0

The "variable" isn't restricted to be an integer at all in your code. An evil user could probably change the value of "variable" to "';truncate recipe;--". Execute this and whoops ... all recipes are gone.

always ensure that you use proper validation. search the interwebs for "sql injection" and have a look at functions like mysql_real_escape_string (and it's documentation).

于 2012-11-22T11:27:54.290 回答
0

The content of request fields, whether $_POST or $_GET, is not typed. It is just plain strings, which means that it's pretty much "open game" on the client side. It's the very reason we keep repeating that client input cannot be trusted, and must be validated on the server side.

Regarding your second question: recall that $_GET will contain the result of a form using the get method, while $_POST will contain data from post method forms. $_GET purpose is to contain url parameters, if they exist (to be precise, a get method form will pass all its parameters via the url).

On a side note, I should also tell you that you shouldn't use one verb for another, each one as a specific purpose. The get method is about getting data, not updating it, while post, put, delete are about updating data. This means that your example is following these rules, and should not try to use a post form instead (although this is technically feasible, you would just need to replace your link tags with forms).

see the HTTP specs on this matter.

于 2012-11-22T12:04:46.223 回答
-1

you may create a session based permission system that:

when user visited your site, and his/her browser rendered the link, in that php, you set a session variable for that link,

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

Now you know exacly what recipe id that user can click,

with this check:

$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");

This will ensure that user visited the page before it send a request. This solution will prevent consecutive POST requests to fetch all website data,

if you show multiple links that user can click, you must implement $_SESSION["permitted_recipe_id"] as an array containing all ids' that send to user as links.

but beware, multi tab experiences may create bugs for this solution. This is the idea, you have to carefully work it out for a relase enviroment solution.

于 2012-11-22T11:29:03.700 回答