前端安全:CSRF 和 XSS 攻击介绍 以及 如何解决

CSRF (Cross-Site Request Forgery)

介绍: 跨站请求伪造(CSRF)是一种攻击方式,攻击者诱导用户在已认证的应用中执行未授权的操作。通常,攻击者会通过伪造的请求在受害者不知情的情况下执行这些操作。

解决方案:

  1. 使用CSRF令牌:服务器生成一个唯一的令牌,将其嵌入到每个表单或AJAX请求中,并在提交时进行验证。

    javascript复制代码// 在表单中嵌入CSRF令牌
    <form action="/submit" method="POST">
        <input type="hidden" name="csrf_token" value="token_value_here">
        <!-- 其他表单元素 -->
    </form>
  2. SameSite Cookie属性:设置SameSite属性为StrictLax,限制第三方网站发送的跨站请求。

    http
    复制代码
    Set-Cookie: sessionId=abc123; SameSite=Strict; HttpOnly; Secure
  3. 验证Referer和Origin头:服务器可以检查HTTP头中的RefererOrigin字段,确保请求来源于合法的域名。

XSS (Cross-Site Scripting)

介绍: 跨站脚本攻击(XSS)是指攻击者在网页中注入恶意脚本,这些脚本在其他用户的浏览器中执行,从而窃取信息、劫持会话等。

解决方案:

  1. 输入验证和过滤:在服务器端和客户端对所有用户输入进行验证和过滤,移除或转义特殊字符。

    javascript复制代码// 转义用户输入
    function sanitize(input) {
        return input.replace(/&/g, '&amp;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .replace(/"/g, '&quot;')
                    .replace(/'/g, '&#039;');
    }
  2. 输出编码:在将用户输入输出到HTML页面时进行编码,防止脚本注入。

    javascript复制代码// 使用库例如DOMPurify进行输出编码
    import DOMPurify from 'dompurify';
    const safeHTML = DOMPurify.sanitize(userInput);
  3. 使用CSP(内容安全策略):通过设置CSP头来限制页面能够加载的资源,从而减少XSS攻击的风险。

    http
    复制代码
    Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com

手写:格式化Query字符串

需求:将URL中的查询字符串转换为对象,考虑到同名key的情况。

javascript复制代码function parseQueryString(queryString) {
    // 去掉前面的问号
    const query = queryString.startsWith('?') ? queryString.slice(1) : queryString;
    const params = query.split('&');
    const result = {};
​
    params.forEach(param => {
        const [key, value] = param.split('=');
        const decodedKey = decodeURIComponent(key);
        const decodedValue = decodeURIComponent(value);
​
        if (result.hasOwnProperty(decodedKey)) {
            if (Array.isArray(result[decodedKey])) {
                result[decodedKey].push(decodedValue);
            } else {
                result[decodedKey] = [result[decodedKey], decodedValue];
            }
        } else {
            result[decodedKey] = decodedValue;
        }
    });
​
    return result;
}
​
// 测试
const queryString = '?a=1&a=2&b=3';
console.log(parseQueryString(queryString)); 
// { a: ['1', '2'], b: '3' }

这个函数通过解析查询字符串,将其转换为对象。如果一个键有多个值,它会将这些值存储在数组中。

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光影少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值