加强JavaScript安全性

每种编程语言都有其自己的安全漏洞,JavaScript也不例外。利用JavaScript漏洞可能导致数据篡改、会话劫持、未经授权的数据访问等问题。尽管通常与客户端功能相关联,JavaScript安全风险在服务器端环境中也可能构成重大威胁。

对于任何应用程序,客户信任至关重要。保持这种信任需要保护客户数据并确保应用程序的安全性。幸运的是,实施适当的防护措施可以减轻这些风险并增强应用程序的安全性。

在本文中,我们将探讨一些最常见的JavaScript安全威胁,并讨论保护应用程序免受潜在攻击的有效工具和策略。

跨站脚本攻击

跨站脚本攻击(XSS)是一种安全漏洞,允许攻击者将恶意的客户端代码注入网站。根据2021年开放网络应用安全项目(OWASP)十大安全漏洞,XSS排名第三。

如何减轻XSS

输入验证

确保用户输入符合预期的数据类型、格式和范围。剥离或转义可能有害的字符以防止注入。

JavaScript

 

function validateInput(input) {
  return input.replace(/[^a-zA-Z0-9]/g, ''); // Allow only alphanumeric characters
}

输出编码

将输出中的特殊字符转换为它们的HTML实体等效项,以中和可能恶意脚本,在渲染之前。

JavaScript

 

function encodeHTML(input) {
  return input.replace(/&/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
    .replace(/'/g, ''');
}

Clickjacking

Clickjacking是一种欺骗性攻击,诱使用户点击他们并非打算与之交互的元素。这种技术涉及在恶意网站中嵌入合法网站 —— 通常使用不可见或具有误导性定位的HTML <iframe> —— 以劫持用户操作。因此,攻击者可以窃取登录凭据,获取未经授权的权限,甚至欺骗用户无意中安装恶意软件。

实现这一点的常见方法之一是使用CSS添加一个具有 opacity 设置接近于0 的重叠按钮。这会使用户误点击一个意外的按钮或链接。

如何预防Clickjacking

X-Frame-Options 指示浏览器该网站是否可以嵌入到iframe中。它有三个选项: 

  1. DENY – 完全阻止页面在iframe中显示
  2. SAMEORIGIN – 仅允许页面在请求来源于相同域时嵌入
  3. ALLOW-FROM – 仅允许页面被特定受信任的域嵌入

在Node.js中,您可以使用 helmet 设置这些选项,如下所示:

JavaScript

 

const helmet = require("helmet");
const app = express();
app.use(
  helmet({
    xFrameOptions: { action: "sameorigin" },
  }),
);

对抗点击劫持的有效防御措施是实施内容安全策略(CSP)头部。CSP 可以对内容的嵌入方式和位置进行细粒度控制,防止未经授权的框架。

为了减轻点击劫持风险,在 CSP 头部中包含frame-ancestors 指令。例如:

HTML

 

Content-Security-Policy: frame-ancestors 'self' https://www.example.org;

此策略确保受保护的文档只能被其自身来源('self')和明确允许的域名(例如example.org)嵌入。它阻止所有未经授权的尝试对内容进行框架化,保护用户免受点击劫持攻击。

注意:如果同时设置了 frame-ancestors 和 X-Frame-Options,则支持 frame-ancestors 的浏览器将忽略 X-Frame-Options。

跨站请求伪造(CSRF)

CSRF(有时也称为 XSRF)利用网站对用户浏览器的信任,代表用户发出未经授权的请求。攻击者欺骗用户在不知情的情况下执行操作,可能导致数据泄露或未经授权的交易。一些示例包括更新受害者的个人信息、从受害者的银行账户发起资金转账,甚至将包裹递送地址重定向到不同地址。

让我们看一个具体的例子。您正在访问您银行的网站,并且已经登录。假设您收到一封假装是您银行的赠品邮件。链接会带您到一个看似无害的网页。幕后,一个POST请求被触发并发送到合法的银行应用程序。

PowerShell

 

curl --location --request POST 'https://acmebank.com/transfer?routing=852363&fromAccountNumber=123456789&toAccountNo=987654321' \
--header 'Cookie: session=acmebanksessionvalue'

在acmebank.com应用程序端,“script”标签会在用户加载页面时立即提交表单,而无需任何用户验证,用户甚至不会注意到发生了什么,如下所示。

HTML

 

<html>
  <body>
    <form action="https://acmebank.com/transfer" method="POST">
      <input type="hidden" routing="852363" fromAccountNo="123456789" toAccountNo="987654321" amount="5000" />
    </form>
    <script>
  	window.addEventListener("DOMContentLoaded", () => {
    document.querySelector("form").submit();
  	});
	</script>
  </body>
</html>

上面的表单会生成以下请求发送到实际应用程序acmebank。该请求包含合法用户的会话cookie,但包含我们的银行账号!因为您与银行的会话仍处于活动状态,如果没有其他验证,金额转账将会通过。

如何防御CSRF攻击

SameSite属性设置为Strict。这可以控制cookie是否与跨站点请求一起发送。

  • 此类会话cookie应具有较短的生命周期。要求对敏感操作进行重新验证,以减少风险。

使用CSRF会话唯一令牌。然后可以将此令牌包含在由浏览器发布的表单中。对于每个请求,服务器将客户端发送的令牌与其存储的会话值进行比较。使用库csrf-csrf来配置唯一令牌。

窃取会话数据

会话劫持发生在攻击者窃取用户的会话令牌时,使其能够冒充用户并未经授权地访问其帐户。

如何防止会话劫持

使用安全Cookie

在会话Cookie上设置SecureHttpOnly标志以防止未经授权的访问。设置Secure属性可防止会话Cookie以明文形式传输,并且只允许它在HTTPS连接上传输。设置Http-Only属性强制浏览器不允许从DOM访问Cookie 这可以防止基于客户端脚本的攻击访问这些Cookie中存储的敏感数据。

启用多因素身份验证(MFA)

为用户添加额外的安全层进行验证。这是大多数安全应用中常见的方法。您可以通过像OktaDuo这样的供应商轻松集成。

实施会话过期

自动使闲置会话过期,以减少攻击窗口。

高级安全的编码实践和工具

漏洞扫描

漏洞扫描工具可以维护应用程序的安全性。扫描库、网络、应用程序和设备有助于发现攻击者可能利用的弱点。像Snyk和Sonarqube这样的工具可以轻松集成到JavaScript代码库中。这些工具与OWASP维护的已知漏洞列表并行工作。通过作为开发过程的一部分无缝集成,这些扫描器为开发人员和安全团队提供了对代码漏洞的实时准确可见性以及解决方案。

渗透测试和评估

开发人员可以采用渗透测试实践来主动探测和利用应用程序中的潜在漏洞。道德黑客模拟真实世界的攻击,通过操纵JavaScript代码和用户交互来评估Web应用程序的安全姿态。

为了完成这一目标,开发人员可以编写自定义JS代码来模拟这些场景,或者他们可以利用专门的渗透测试工具,利用JavaScript自动化扫描常见漏洞,如XSS,使用OWASP ZAP 有关渗透测试的更多信息,请参阅OWASP官方指南

Web应用防火墙(WAF)

随着应用程序的增长,网络流量也在增加,增加了遭受攻击的风险。实施Web应用防火墙(WAF)有助于通过过滤和监控HTTP请求来防范恶意流量。这涉及与Cloudflare或AWS WAF等第三方WAF提供商集成。使用WAF,您可以定义规则,例如:

  • 请求来源的国家或地理位置。
  • 请求来源的IP地址、CIDR范围和域名。
  • 限制请求长度和查询参数以防止注入攻击。
  • 可能是恶意的SQL代码。攻击者尝试通过在Web请求中嵌入恶意SQL代码来从您的数据库提取数据。这就是所谓的SQL注入。
  • 检测并阻止可能作为XSS攻击一部分的嵌入式脚本。

WAF 还可以帮助缓解分布式拒绝服务(DDoS)攻击,确保应用程序的可用性。

保护数据完整性

在存储或访问安全信息时,实施强大的数据完整性措施至关重要。最佳做法包括:

  • 强制执行强密码策略并鼓励使用密码管理器。此外,鼓励您的用户使用密码管理器,这样他们可以使用更复杂的密码,而无需担心记住它们(使用LastPass1Password)。
  • 通过速率限制、一定次数的登录失败后锁定账户以及 CAPTCHA 挑战来保护登录页面免受暴力破解攻击。
  • 使用HTTP头部,例如:

结论

JavaScript安全是一个持续的过程,需要采取积极的方法来保护应用程序免受不断演变的威胁。实施诸如输入验证、CSP头、安全会话管理和漏洞扫描等最佳实践可以显著降低XSS、CSRF和会话劫持等攻击的风险。

此外,利用诸如WAF、渗透测试和MFA等安全工具可以增强应用程序的韧性。在开发的每个阶段优先考虑安全将使开发人员能够构建强大、用户可信赖的应用程序,从而保护其免受现代网络威胁的影响。

Source:
https://dzone.com/articles/enhancing-security-in-javascript