我想知道在直接使用GET和POST变量时,不进行修剪、添加斜杠函数和mysql转义字符串等操作会有什么漏洞。
我的问题是
在处理GET和POST时,还需要注意哪些方面。
有哪些类型的攻击,例如SQL注入?
一般而言,不仅限于 GET 和 POST,也包括系统外部的任何数据(包括 Web 应用程序中的 cookie):
几乎所有漏洞都可以归结为“用户可以在你传递其输入的上下文中运行任何代码”。
你需要考虑你对数据的处理方式。在世界上接受有污点输入时可能出现的问题列表中寻找可能出错的事情并不能产生详尽的列表。
顺便说一下:忘记 addslashes(它不起作用),忘记 mysql_real_escape(使用它太容易犯错误)。使用参数化查询:如何防止 PHP 中的 SQL 注入?
用极少的社交工程就能实现最简单的XSS攻击
假设您有一个简单的PHP应用程序,使用会话跟踪用户。并且它有某种管理员界面,其中具有更高权限的用户可以编辑内容。
再假设您已经作为管理员登录到该网站,并且该应用程序中有一个名为request.php的文件,其中包含以下代码片段:
echo $GET['action'];
GET和POST数据是直接由用户发送的数据。您会得到原始数据,没有在用户和您的程序之间进行任何检查或验证。即使您要验证应该产生数据的表单,攻击者也可以手动制作请求并添加任何他想要的数据。因此,您必须始终将请求数据视为不受信任的用户输入。
有许多攻击依赖于编码人员忘记请求数据是不可信的,但最著名的攻击是SQL注入。SQL注入的根本原因是手动串联字符串构建查询语句,其中一些是不受信任的用户输入。这意味着您要告诉数据库执行不受信任的用户输入。
解决SQL注入的天真解决方案是验证输入,然后将它们合并成一个查询字符串,但这也是不好的做法。您依靠验证逻辑使字符串安全,并且如果您误用它--或逻辑有缺陷--那么您再次面临攻击。
正确的解决方案是将查询与其包含的数据分开。几乎所有的数据库适配器都支持这种方法,如果您的数据库适配器由于某种原因不支持这种方法,则不适合使用。最常见的习语是(没有特定的语言):
myDB.query("select * from Stuff where id=?", [42]);
这将确保(在这样的系统中)参数不会被执行。查询字符串是由完全可信的数据构建的,而不可信的数据是隔离的。最坏的情况是,将此方法应用于不当输入可能导致不正确的数据,而不是不正确的命令。
避免SQL注入的这种方法强调了适用于所有类型请求数据攻击的核心原则:请求数据不属于你,也不安全。处理任何用户输入,包括请求数据时,始终假定它来自具有对您的系统有详细了解的攻击者。这可能看起来有点偏执,但它可以保护您的安全。
正如其他人所说,任何和所有用户输入都应被视为恶意的,无论您感觉多么安全。
开发人员在编写代码和进行修改时考虑到保护代码的安全性,而黑客则会在决定攻击代码时考虑破坏它,这可能是今天、明天或两年后。在编写代码时看似完全安全的内容,在某个时间点可能会被利用。
基本上,所有输入都应该被过滤、检查和彻底清理,无论在任何时候使用它们的目的是什么。有人可能会跳过对一段用户输入进行清理,因为“它不会被用于任何可能造成伤害的事情”,然后11个月后,团队中的某个人决定在SQL查询或系统执行调用中使用预先认为已经清理过的数据,结果整个系统崩溃了。
应该做什么:
白名单而不是黑名单 - 知道你期望的输入类型并相应地转换用户数据,ID通常是整数,因此可以将所有用户提交的ID视为整数。 - 知道何时期望少量数据,何时期望大量数据。个人姓名通常比较短且不包含数字,“1'; DROP TABLE customers;”不是真实姓名,您可以不添加反斜杠而知道它不是真实姓名。
然后再黑名单一些 - 对通过白名单的所有数据应用标准转义逻辑,以防万一。
然后进行更多的过滤和检查 - 直到您感到安全为止。
它不仅仅是“get”或“post”,而是更多。这完全取决于您编写的支持它们的编程。如果您只提供静态HTML页面,则漏洞不会太多。另一方面,如果您通过get请求设置和修改数据,则漏洞可能是无穷无尽的,只需查看谷歌机器人从使用“get”提交事物的地方清除数据的案例。
所有这些都取决于您使用数据的方式,漏洞是否受到限制。对输入进行消毒。
所有的超全局变量都可以被用户代理程序操纵。例如:$_SERVER、$_POST、$_GET等。