网络安全 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 = "没有为此文档授权";
}
return $doc;
像这样的漏洞很容易发现,因为你只需更改一个简单的数字,看看你是否可以访问其他人的数据。首先检查用户是否已授权可以防止此漏洞。
避免“魔数”
应用程序希望在引用数据时避免使用数字序列。在 IDOR 示例中,文档的标识符从 1000 到 1002。有时这些数字被称为“魔数”,因为它们直接指向服务器上的资源(例如,通过数据库),并且所有值都可以轻松枚举。例如,攻击者可以检查从 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;
}
为了让攻击者利用这一点,他们只需针对目标域构建一个包含攻击的 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 找到漏洞,然后向毫无戒心的用户发送包含攻击的链接,让他们点击该链接。该链接包含攻击,并使 Web 服务器将攻击返回给点击链接的受害者。
此背后的代码可能与以下伪代码示例一样简单
$nickname = etNickName();
echo "Greeting $nickname, nice to meet you!";
另一种 XSS 称为存储型 XSS 攻击。在存储型 XSS 攻击中,攻击者能够保存网页上的内容,这些内容在任何访问网站的人每次访问时都会被反映出来。它并不一定要求人们点击链接。
此图形描述了 Eve 如何能够存储恶意 JavaScript,以便在任何访问该资源的人的浏览器中执行
XSS 攻击可以完成许多事情,例如
- 窃取可用于身份验证的 cookie
- 破坏网站,呈现 Web 服务器不打算呈现的内容
- 诱骗用户在虚假登录表单中留下凭据
为了防御 XSS,有一些最佳实践需要遵循
- 让 Web 服务器返回 CSP(“内容安全策略”)标头,该标头严格决定从哪里以及如何执行 JavaScript
- 安全地对 Web 服务器返回给用户的输出进行编码,有效地将 HTML 字符转换为编码的安全字符
HTML 编码
HTML 编码允许 Web 应用程序以安全的方式返回通常不安全的字符。例如,以下特殊字符可以编码成它们各自的对应字符
特殊字符 | HTML 实体 |
---|---|
< | < |
> | > |
" | " |
& | & |
' | ' |
这会生成可以安全显示的输出。然后,我们可以使用客户端的 JavaScript 将 HTML 实体安全地转换为值。
CSP(“内容安全策略”)
Web 服务器可以控制允许在网站上运行哪些 JavaScript。这并不能消除漏洞,但会在存在未知漏洞时增加纵深防御。
一个常见且严格的 CSP 是为 Web 应用程序的用户提供所有可接受的 JavaScript 源文件列表。
此外,CSP 通常会阻止执行内联 JavaScript。
为了便于实施和检测正在进行的攻击,CSP 允许客户端将 CSP 违规报告到服务器提供的 URL
网页应用程序扫描
市场上存在许多网页应用程序扫描器。这些扫描器可以用于扫描应用程序中的漏洞,例如 SQL 注入和 XSS。与网络漏洞扫描器不同,网页应用程序扫描器通常基于启发式算法,而不是签名和已知漏洞列表。
网页应用程序扫描器非常有用,尤其是在开发流程(如 CI(持续集成)和 CD(持续交付))中集成使用。