针对无效 post 进行保护
表单欺骗是指有人把 post 从某个不恰当的位置发到您的表单中。欺骗表单的最简单方法就是创建一个通过提交至表单来传递所有值的 Web 页面。由于 Web 应用程序是没有状态的,因此没有一种绝对可行的方法可以确保所发布数据来自指定位置。从 IP 地址到主机名,所有内容都是可以欺骗的。清单 13 显示了允许输入信息的典型表单。
清单 13. 处理文本的表单
以下为引用的内容: <html> <head> <title>Form spoofing example</title> </head> <body> <?php if ($_POST['submit'] == 'Save') { echo("<p>I am processing your text: "); echo($_POST['myText']); echo("</p>"); } ?> </body> </html> |
清单 14 显示了将发布到清单 13 所示表单中的表单。要尝试此操作,您可以把该表单放到 Web 站点中,然后把清单 14 中的代码另存为桌面上的 HTML 文档。在保存表单后,在浏览器中打开该表单。然后可以填写数据并提交表单,从而观察如何处理数据。
清单 14. 收集数据的表单
以下为引用的内容: <html> <head> <title>Collecting your data</title> </head> <body> <form action="processStuff.php" method="post"> <select name="answer"> <option value="Yes">Yes</option> <option value="No">No</option> </select> <input type="submit" value="Save" name="submit" /> </form> </body> </html> |
表单欺骗的潜在影响是,如果拥有含下拉框、单选按钮、复选框或其他限制输入的表单,则当表单被欺骗时这些限制没有任何意义。考虑清单 15 中的代码,其中包含带有无效数据的表单。
清单 15. 带有无效数据的表单
以下为引用的内容: <html> <head> <title>Collecting your data</title> </head> <body> <form action="http://path.example.com/processStuff.php" method="post"><input type="text" name="answer" value="There is no way this is a valid response to a yes/no answer..." /> <input type="submit" value="Save" name="submit" /> </form> </body> </html> |
思考一下:如果拥有限制用户输入量的下拉框或单选按钮,您可能会认为不用担心验证输入的问题。毕竟,输入表单将确保用户只能输入某些数据,对吧?要限制表单欺骗,需要进行验证以确保发布者的身份是真实的。您可以使用一种一次性使用标记,虽然这种技术仍然不能确保表单绝对安全,但是会使表单欺骗更加困难。由于在每次调用表单时都会更改标记,因此想要成为攻击者就必须获得发送表单的实例,去掉标记,并把它放到假表单中。使用这项技术可以阻止恶意用户构建持久的 Web 表单来向应用程序发布不适当的请求。清单 16 提供了一种表单标记示例。
清单 16. 使用一次性表单标记
以下为引用的内容: <?php session_start(); ?> <html> <head> <title>SQL Injection Test</title> </head> <body> <?php echo 'Session token=' . $_SESSION['token']; echo '<br />'; echo 'Token from form=' . $_POST['token']; echo '<br />'; if ($_SESSION['token'] == $_POST['token']) { /* cool, it's all good... create another one */ } else { echo '<h1>Go away!</h1>'; } $token = md5(uniqid(rand(), true)); $_SESSION['token'] = $token; ?> <form id="myFrom" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> <div><input type="hidden" name="token" value="<?php echo $token; ?>" /> <input type="text" name="myText" value="<?php echo(isset($_POST['myText']) ? $_POST['myText'] : ''); ?>" /> <input type="submit" value="Save" name="submit" /></div> </form> </body> </html> |