网络安全 Web 应用程序攻击
Web 应用程序如今无处不在,它们被用来控制几乎所有你能想象到的东西。 在本节中,我们将研究 Web 应用程序攻击和安全性。
IDOR("不安全的直接对象引用")
IDOR 漏洞发生在开发人员未实现访问资源的授权要求时。
Eve,只需更改标识符即可,例如 文档 Rest 参数,她可以访问 Alice 的文档。
当 Web 应用程序未在对象之间强制授权时会发生这种情况,从而允许攻击者枚举值并测试对其他数据点的访问。
例如,我们可能有以下伪代码显示没有授权迹象:
$id = getInputFromUser();
$doc = getDocument($id);
return $doc;
上面的代码要求用户输入,不执行验证或清理,然后直接使用 getDocument 函数执行查找并返回有问题的文档。
更好的实现是检查权限:
$id = getInputFromUser();
$user = findUsername();
$doc = "";
if (hasAccessToDocument($user, $id)) {
$doc = getDocument($id);
} else {
$doc = "Not authorized for this document";
}
return $doc;
此类漏洞很容易找到,因为您只需更改一个简单的数字即可查看您是否可以访问其他人的数据。 首先检查用户是否被授权可以防止这个漏洞。
避免"Magic Numbers"
应用程序希望在引用数据时避免使用数字序列。 在 IDOR 示例中,文档的标识符从 1000 到 1002。有时这些数字被称为"Magic Numbers",因为它们直接指向服务器上的资源,例如 通过数据库,可以轻松枚举所有值。 例如,攻击者可以检查从 0 一直到 10000 的所有文档标识符,并记录任何提供数据访问权限的结果。
虽然应正确实施授权,但在引用数据时使用 GUID("全局唯一标识符")或 UUID("通用唯一标识符")也很有帮助。 由于数字生成的内置熵,这些标识符被设计为全球唯一且无法枚举。
这就是 GUID 的样子:
- 3377d5a6-236e-4d68-be9c-e91b22afd216
SQL 注入
许多 Web 应用程序都连接到数据库。 该数据库包含 Web 应用程序希望存储和使用的所有信息。
SQL 注入是一种允许攻击者操纵 Web 应用程序开发人员正在使用的 SQL("结构化查询语言")的技术。 这通常是由于缺乏数据清理而发生的。 开发人员经常使用 SQL 来访问数据库资源。
在上图中 Eve 提出的请求中,我们看到她输入了值:1000' OR '1'='1
这会导致生成的 SQL 查询返回表的所有行,因为数据库将语句评估为始终为真。 想一想:数据库收到一个请求,其值可以是 1000 或 1 等于 1; 每次都会返回一个值! 我们可以使用许多不同的 SQL 函数和操作来操纵语法,这个例子只是众多例子之一。
下面是一个包含 SQL 注入漏洞的伪代码示例。
$username = getUserName();
$pw = getPassword();
$user = mysql_query("SELECT * FROM userTable WHERE username = $username AND password = $pw");
if ($user) {
$loggedIn = True;
} else {
$loggedIn = False;
}
我们可以看到用户名和密码变量都没有进行清理; 相反,它们直接在导致漏洞发生的 SQL 中使用。 如果查询返回任何内容,该代码允许设置 $loggedIn 变量。
为了让攻击者利用这一点,他们可以简单地针对目标域制作一个 URL,其中包含攻击,如下所示:
/login?username=admin&password=password' OR '1'='1
密码变量设置为包含 SQL 字符,导致生成的 SQL 字符串返回一行,即使我们不知道密码。 生成的 SQL 查询将是:
SELECT * FROM userTable WHERE username = 'admin' AND password = 'password' OR '1'='1'
参数化查询是击败 SQL 注入的推荐解决方案。 在参数化查询中,开发人员仔细确保查询的每个输入都定义为特定的值和类型。 这是上面代码中的一个示例,它被认为是安全的实现:
$username = getUserName();
$pw = getPassword();
$parameterizedQuery = prepare_query("SELECT * FROM userTable where username = ? and password = ?");
$parameterizedQuery.setString(1, $username)
$parameterizedQuery.setString(2, $password)
$user = parameterizedQuery.execute();
if ($user) {
$loggedIn = True;
} else {
$loggedIn = False;
}
在上面的例子中,开发者小心翼翼地说 参数1 应该是一个字符串,并且在第2个参数中包含用户名和密码。
XSS("跨站脚本")
XSS 使用服务器攻击服务器的访问者。 攻击的目标不是服务器本身,而是用户。
服务器仅用于反映攻击者的值,通常是 JavaScript,以针对然后在自己的浏览器中运行攻击者数据的访问者。 攻击者必须制作服务器不清理和清理的输入,这样当访问者单击包含攻击者值的链接或访问攻击者在其攻击中使用的网页上的资源时,用户运行代码 攻击者提供的。
这是 Eve 向 Alice 发送包含 XSS 攻击的链接的图形示例:
这种攻击称为反射型 XSS,涉及 Eve 发现漏洞,然后将包含攻击的链接发送给毫无戒心的用户并让他们单击该链接。 该链接包含攻击,并使网络服务器将攻击返回给单击该链接的受害者。
这背后的代码可能很简单,就像这个伪代码示例:
$nickname = etNickName();
echo "Greeting $nickname, nice to meet you!";
另一种 XSS 称为存储型 XSS 攻击。 在存储型 XSS 攻击中,攻击者能够在网页上保存内容,每次有人访问该网站时都会反映出来。 它不一定要求有人点击链接。
此图描述了 Eve 如何存储恶意 JavaScript,以便在访问资源时在任何人的浏览器中执行:
XSS 攻击可以完成很多事情,例如:
- 窃取可用于身份验证的 cookie
- 破坏网站,展示网络服务器不打算展示的内容
- 钓鱼用户在虚假登录表单中留下凭据
要防御 XSS,有几个最佳实践可以遵循:
- 让网络服务器返回 CSP("内容安全策略")标头,该标头严格决定 JavaScript 从何处以及如何执行
- 对网络服务器返回给用户的输出进行安全编码,有效地将 HTML 字符转换为编码的安全字符
HTML 编码
HTML 编码允许 Web 应用程序以安全的方式返回通常不安全的字符。 例如,可以将以下特殊字符编码为它们各自的对应字符:
特殊字符 | HTML 实体 |
---|---|
< | < |
> | > |
" | " |
& | & |
' | ' |
这会产生可以安全显示的输出。 然后,我们可以在客户端使用 JavaScript 将 HTML 实体安全地转换为值。
CSP("内容安全政策")
网络服务器可以控制允许在网站上运行哪种 JavaScript。 这不会消除漏洞,但会增加 在存在未知漏洞时进行深度防御。
一个常见且严格的 CSP 是为 Web 应用程序的用户提供所有接受的 JavaScript 源文件的列表。
此外,CSP 通常会阻止内嵌 JavaScript 的执行。
为了更轻松地实施和检测正在进行的攻击,CSP 允许客户端向服务器提供的 URL 报告 CSP 违规
网络应用扫描
那里有许多 Web 应用程序扫描仪。 这些允许扫描应用程序以查找 SQL 注入和 XSS 等漏洞。 与网络漏洞扫描器相反,Web 应用程序扫描器通常基于启发式而不是签名和已知漏洞列表。
Web 应用程序扫描器很有用,尤其是在构建到 CI("持续集成")和 CD("持续交付")等开发流程中时