开头先说明这次分享的主题不是教人怎么打而是围绕一款老牌开源内容管理系统下面统一用“老系统”代称反复被通报的 XSS 问题聊聊这些漏洞为什么总也修不完、它们和后台被写入文件之间到底是什么关系以及我作为防守方在一次内部自查里具体是怎么走的整套流程。核心关键词就三个XSS 防护、CMS 安全加固、漏洞排查。不管你是刚接手一套存量站点的运维还是需要做代码审计的安全岗或者只是给自己维护的小站做个体检下面这些内容都能直接拿去用。我不打算给你们任何可以直接复制粘贴去攻击别人站点的东西那既没意义也不负责。真正有价值的是搞清楚机制为什么一个看起来“只是弹个框”的脚本注入放在后台场景里就会被放大成文件落地为什么有些过滤函数写了等于没写为什么同一个输入点在 Chrome 里人畜无害换个老内核就出事。搞明白这些你排查自己的系统时才有方向感。1. 老牌内容管理系统为何常年出现在漏洞通报里1.1 十几年前的架构选择决定了今天的攻击面这类系统的骨架大多成型于 PC 互联网时代那时候的设计目标是“让不懂代码的人也能建站”于是催生了一套非常激进的机制模板标签直接写在 HTML 里后台可以提供在线编辑模板、在线修改栏目、在线装插件。这套机制对使用者极其友好代价是把大量本该在编译期确定的东西推迟到了运行期而运行期意味着用户输入可以参与到模板解析、文件生成这些高权限动作里。我见过不少二次开发过的站点模板目录是 777插件目录里躺着十年前没人维护的第三方代码后台入口改了个名字就当防护了。这种环境下任何一个输出点漏了转义影响的都不只是“页面上多一段脚本”而是可能顺着后台功能一路走到文件系统。这是理解后面所有内容的前提风险不是单点的是链式的。1.2 从“页面执行脚本”到“服务器写入文件”中间隔着什么很多人对 XSS 的理解停留在“弹窗”“盗 Cookie”觉得危害有限。放在普通访客身上确实如此但放在管理员会话上性质就变了。老系统后台往往同时具备几类高危能力模板文件在线编辑、数据库备份与恢复、附件上传、插件安装、缓存清理。这些功能本身是正常需求问题在于它们的入口往往依赖“管理员已登录”这一个判断而不校验请求来源和操作意图。于是攻击路径就变成了这样一条逻辑链先在某个前台输入点植入脚本等管理员访问后台或相关页面时脚本执行脚本以管理员的身份和权限发起后台操作请求后台功能把数据写成文件。整条链里XSS 是入口后台功能是放大器最终落点才是文件。所以加固的时候不能只盯着“过滤尖括号”必须同时管住会话、管住后台操作的请求校验、管住写文件这条路径。这三处任何一处断了链子就接不上。1.3 存量站点的现实补丁永远打不完理论上官方出了修复版本升级一下就行。实际运维里我遇到的情况要复杂得多站点做过深度二次开发核心文件被改过几十处直接覆盖升级会导致功能崩掉有些站点跑在很老的语言版本上新版本的代码根本跑不起来还有些是外包做的交付之后原班人马早就联系不上了。这就导致一个结果大量站点长期停留在“知道有风险但不敢动”的状态。我的建议是不要指望一次性升级解决问题而是把工作拆成两层——应急层用配置和网关兜底工程层逐步做代码改造。后面第 6 节会给出具体的分层方案。2. XSS 在这类系统里的三类典型落点2.1 存储型内容字段和富文本过滤器存储型是最常见也最麻烦的一类因为脚本被存进数据库每次有人访问对应页面都会触发。老系统里最容易出问题的字段通常是这几类文章标题、文章摘要、栏目描述、自定义表单提交内容、评论、友情链接名称。按理说这些字段都应该在输出时做 HTML 实体编码但实际情况是很多模板里写的是类似“直接输出原始内容”的标签开发者为了让摘要能带格式主动关掉了转义。还有一种更隐蔽的情况字段在入库时做了过滤在输出时又做了一次“反转义”或者“HTML 还原”等于把前面的过滤全废了。判断一个字段是不是存储型风险的落点我的做法是看三件事这个字段在后台编辑页是不是富文本编辑器、在模板里是用转义标签输出还是原始标签输出、数据库里存的是原文还是编码后的实体。三件事里只要“富文本 原始输出”同时出现基本可以确定这个点需要重点验证。2.2 反射型搜索框、跳转参数和错误回显反射型一般不需要落库参数带在 URL 里页面直接把参数拼进 HTML 返回。老系统里高发的几个位置站内搜索结果页关键词回显、登录后的跳转提示页、404 和错误提示页、分页参数回显。这类漏洞有个特点很多开发者觉得“要用户点特定链接才触发危害低”于是长期不修。但从社工角度看一条精心构造的站内链接发给管理员成功率并不低尤其是在“系统升级通知”“异常登录提醒”这类场景包装下。我个人的定级习惯是如果反射点位于后台域或者能触达管理员会话一律按高危处理不按低危放过。验证的时候不需要构造复杂载荷我就看一个最简单的判断标准——在参数里输入带有特殊字符的普通文本比如包含、、、的一串字符然后查看返回的 HTML 源码看这些字符是被原样输出还是被编码成了实体。原样输出就是问题编码了就没问题。这个方法不涉及任何攻击代码纯看渲染行为非常适合自查。2.3 DOM 型前端拼接与旧内核兼容DOM 型的问题不在服务端在浏览器里由 JavaScript 完成。老系统里常见于搜索结果高亮、评论楼层跳转、前端模板渲染、URL 参数直接写进innerHTML。这类点用抓包工具看不出来因为请求和响应都是干净的脚本是在浏览器端拼出来的。排查方法得换一套把页面里所有读取 URL 参数、读取location、读取document.referrer的代码位置找出来看这些值最终流向哪里。流向innerHTML、document.write、eval这类危险汇点的就要重点看。还有一个容易被忽略的维度老系统往往会兼容很旧的浏览器内核而这些内核里存在一些非常规的解析行为导致某些在主流浏览器里被正常处理的字符序列在老内核里会被重新解释成标签。我的做法是这类站点一律把安全基线按“最差的那个客户端”来定不做兼容性妥协。类型触发方式排查入口加固重点存储型访问含恶意内容的页面富文本字段、自定义表单、评论输出编码、富文本白名单反射型诱导点击特定链接搜索、跳转、错误页参数编码、错误页统一处理DOM 型前端脚本拼接URL 参数读取点、前端模板安全 API 替换、CSP3. 一次内部自查的完整排查链路3.1 从攻击面清单开始而不是从载荷开始很多人做安全测试的习惯是打开工具就开始扫扫出一堆报告再慢慢看。我在做存量系统自查时反过来先花半天时间把攻击面清单列出来再逐个验证。清单怎么列按“数据从哪进、经过哪、最后到哪”这条线来。入口包括URL 查询参数、表单字段、文件上传、HTTP 请求头Referer、User-Agent 这些也会被记录并回显、Cookie。中间处理包括过滤函数、模板渲染、JSON 输出。出口包括HTML 页面、JSON 接口、文件、数据库。列完这张表你会发现真正需要人肉看的地方其实不多通常集中在十几到几十个关键文件。比如模板渲染相关的一批文件、表单处理的一批文件、后台功能入口的一批文件。把范围收敛到这些文件之后不管是人工读代码还是用工具做污点分析效率都会高很多。这一步的另一个价值是它帮你建立“哪些点是别人也可能踩过的”这种直觉。同一个开源项目被曝过的位置往往和它的架构强相关同类位置大概率还有没被公开的类似问题。3.2 用“编码前后对比”判断真实风险确认一个点是否存在风险我用的是最朴素的对比法同一个输入在页面上原样输出还是在源码里被编码。具体操作是在输入框里填一段包含特殊字符的文本包含尖括号、双引号、单引号、反斜杠、符号提交后查看页面渲染结果和页面源码。如果渲染结果里这些字符被当成 HTML 结构的一部分解析了比如尖括号变成了实际标签说明没编码如果源码里看到的是lt;、quot;这类实体说明编码是生效的。这个方法的妙处在于它完全不需要构造攻击载荷也不会触发任何告警非常适合在授权的自查场景里使用。我在给团队做培训时一直强调安全验证的目的是确认“数据被当成了代码还是被当成了数据”只要搞清楚这一点不需要真的去执行什么。顺带说一个判断技巧很多系统会对输入做“黑名单替换”把尖括号删掉。这种情况下你输入特殊字符输出里会发现字符凭空消失了。这看起来像“修好了”其实是坏味道——黑名单永远有绕法尤其在不同字符集、不同编码转换的场景下。看到“字符消失”这种现象我反而会把风险等级往上提因为它说明防护思路是错的。3.3 复现、定级、修复、回归的闭环确认问题之后流程要闭环否则修完还是心里没底。复现环节把触发条件写成最小步骤包括需要什么权限、访问哪个地址、参数怎么带。这一步是为了让开发和运维能独立理解和验证而不是只看到一句“这里有 XSS”。定级环节我一般看三个维度——需要什么权限触发、能影响到哪些角色、能不能和其他问题组合。如果触发需要管理员权限看起来低但如果触点是“管理员查看某列表”这种高频动作实际风险就高如果单纯是一个普通访客自己给自己弹窗那确实可以降级。修复环节优先在输出层修而不是在输入层修。原因很简单输入层的黑名单思路迟早被绕过而输出层的编码是数学上确定的。如果确实需要在输入层清洗 比如富文本那也必须配合输出层白名单。回归环节修完必须重新走一遍 3.2 的对比法并且要测边界情况——同一个字段在列表页、详情页、搜索页、RSS 输出、移动端接口可能走的是不同的输出路径只修一处等于没修。我踩过的坑就在这儿某次只在主模板里加了编码结果站点的 WAP 版模板用的是另一套渲染逻辑问题原封不动地留着。4. 转义防线怎么落到代码里4.1 上下文决定编码方式这是铁律XSS 防护最核心的一句话是编码方式由输出上下文决定不是由输入内容决定。同一个用户输入输出到 HTML 文本里、输出到 HTML 属性里、输出到 JavaScript 字符串里、输出到 CSS 里、输出到 URL 参数里需要的处理方式完全不同。举个具体的输出到 HTML 文本节点需要把、、、、编码成实体输出到属性值里除了上面的还要保证属性值整体被引号包裹输出到script块内的字符串变量里需要用 JSON 序列化而不是 HTML 实体编码因为 HTML 实体在 JS 字符串里不会被解码反而可能因为/script提前闭合标签而出问题输出到href、src这类 URL 属性里还要校验协议只允许 http、https、相对路径。我在评审代码时最常看到的错误就是“一招鲜”全站所有输出统一调一个htmlspecialchars然后觉得万事大吉。在大多数场景下这么做确实能挡住大部分问题但在 JS 上下文里它是无效的在 URL 上下文里也不够。所以正确做法是先按上下文给输出点分类再给每一类配一个固定的编码函数。4.2 模板引擎的自动转义以及关掉它的代价现代模板引擎基本都提供自动转义问题往往出在“为了显示格式而关掉转义”这个动作上。老系统里这种关闭转义的写法非常普遍而且经常是分散在各个模板文件里没有任何标记。我的处理原则是默认全部开启转义任何一处关闭都必须有明确注释和对应字段的白名单说明。具体落地可以这样做——把“原始输出”这个动作集中封装成一个函数函数内部做三件事检查传入字段是否在允许的白名单里、如果不在就记一条日志、对白名单内内容执行一遍富文本清洗后再输出。这样一来所有“危险动作”都有统一的出入口审计的时候只需要 grep 一个函数名。?php // 统一的安全输出封装示意 function safe_html($value) { return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, UTF-8); } // 富文本输出必须走白名单清洗不接受裸输出 function safe_rich($value) { $allowed pbrstrongemulolliaimg; $clean strip_tags((string)$value, $allowed); // 仍需处理属性层面的危险值例如事件属性、危险协议 return $clean; }上面这段只是示意真实项目里富文本清洗建议直接用成熟的白名单库不要自己写正则。我见过太多自研过滤器写了几百行正则最后被一个属性里的特殊写法绕过去。4.3 富文本白名单拦什么、留什么富文本是这块最难的地方因为业务要求“能带格式”而格式本身就是 HTML。我的思路是把白名单拆成三层分别控制。第一层是标签白名单只允许排版类标签把表单、脚本、框架、样式块全部排除。第二层是属性白名单每个标签只允许它该有的属性比如链接只允许href和title图片只允许src、alt、width、height。凡是on开头的事件属性一律不进入白名单。第三层是值校验href和src这类要检查协议style属性如果允许必须再走一次 CSS 值过滤因为 CSS 里也存在能执行脚本的历史写法。还有一个容易被忽略的点富文本内容在“编辑回填”时也要按同样的规则处理。有些系统只做了保存时的清洗编辑页把内容回填到 textarea 里时直接原始输出结果编辑页本身就成了反射点。4.4 CSP 和 Cookie 属性作为兜底代码改造是个长期活改造期间需要有兜底手段。两个最有效的兜底是内容安全策略和 Cookie 属性。内容安全策略的作用是告诉浏览器“只允许加载哪些来源的脚本”。配置得当的话即使某处漏了转义注入的脚本也执行不了。落地时要注意不要一上来就用最严格的模式老系统里内联脚本、内联事件处理器到处都是直接上严格模式会把站点搞挂。我的建议是先用“报告模式”跑一两周收集违规日志看清楚站点到底依赖哪些内联脚本再逐步收敛。收敛的顺序可以是先禁掉外部未知域再处理内联脚本改成 nonce 或 hash最后处理内联事件。Cookie 属性这块后台会话 Cookie 一定要加HttpOnly这样即使脚本执行了也读不到会话凭证。同时加Secure如果全站 https和SameSiteLax或Strict。SameSite这个属性对前面提到的那条“脚本以管理员身份发起后台请求”的链路有直接的阻断作用成本极低性价比很高。# 响应头示意 Content-Security-Policy: default-src self; script-src self nonce-随机值; object-src none; base-uri self Set-Cookie: SESSIONIDxxx; Path/; HttpOnly; Secure; SameSiteLax5. 后台侧的文件写入路径必须单独收口5.1 后台功能点本身就是最高危攻击面前面反复提到XSS 本身只是入口真正造成严重后果的是后台那些“能写文件”的功能。所以加固的重心必须往后台移。我梳理过这类系统的后台功能高危程度从高到低大致是模板在线编辑、数据库备份与恢复、插件与应用安装、附件上传、缓存与静态页生成、站点配置修改。这些功能的共同点是最终都会在服务器上产生或修改文件。只要其中任何一个的入口校验不严前面的 XSS 就有了实际落点。5.2 三处最该改的地方第一处是模板编辑。这个功能的设计初衷是方便但它的本质是“通过浏览器写任意文件”。加固思路默认关闭需要时临时开启编辑范围限制在指定目录保存时校验文件扩展名和路径禁止..穿越对写入内容做基本的语法检查避免写入可执行代码。第二处是上传。老系统上传点通常只校验扩展名而扩展名校验又有各种绕过方式。我的做法是三重校验服务端读取文件真实类型、白名单限定允许的类型、上传目录禁止脚本执行通过 Web 服务器配置实现这是最有效的一层。第三处是备份恢复。备份文件如果落在 Web 可访问目录且扩展名可控风险极高。加固方式是备份目录放在站点根目录之外文件名使用随机串恢复操作要求二次确认并记录操作日志。5.3 权限分层与最小化技术手段之外权限设计是最容易被低估的一环。很多站点所有管理员共用一个超级账号一旦这个会话被利用全线失守。我建议至少做三层内容编辑只能写文章不能碰模板和插件、站点管理员能改配置不能碰服务器文件、系统管理员能装插件、改模板且这个账号平时不登录需要时临时启用。配合操作日志任何一次模板修改、插件安装都能追溯到人和时间。这套东西落地之后即使某天真的出现了会话被利用的情况损失范围也是可控的。另外提醒一句运行环境层面的事Web 进程的运行账号不要有整站目录的写权限只给必要的几个目录上传目录、缓存目录、日志目录写权限。这一条配置下去很多“写入文件”的路径直接就断了成本几乎为零收益极大。6. 存量系统的加固路线与可执行清单6.1 一周内能做完的应急动作不要一上来就排几个月的改造计划先把能立刻降低风险的做了。第一后台入口做访问控制限制来源 IP 或者加一层额外的认证至少不要让后台登录页暴露在公网随便访问。第二给所有会话 Cookie 加HttpOnly、Secure、SameSite。第三关闭后台的模板在线编辑和插件在线安装功能需要时再临时开。第四上传目录加上禁止脚本执行的配置。第五把内容安全策略以报告模式上线先收集数据。这五件事基本都是一两个小时的配置量但对前面那条攻击链的阻断效果非常明显。6.2 一个月内推进的工程改造应急动作做完开始动代码。优先级我一般这样排先做输出层的统一封装把所有模板里的原始输出改成统一函数这一步工作量最大但收益最高。再做富文本白名单替换把自研过滤器换成成熟库。然后补后台操作的请求来源校验所有写操作必须是 POST 且带一次性令牌。最后清理无用的插件和旧文件很多老站点根目录下躺着一堆十年前的上传木马和测试文件这些是最容易被忽视的后门。6.3 一份可以直接照着做的检查表检查项判断标准不达标的处理输出是否统一编码模板中不存在裸输出替换为安全输出函数富文本是否白名单标签、属性、协议三层控制换成熟白名单库会话 Cookie 属性HttpOnly Secure SameSite改配置立即生效上传目录执行权限目录内脚本不可执行改 Web 服务器配置后台写操作校验POST 一次性令牌补校验逻辑模板编辑功能默认关闭关闭或加二次确认数据库账号权限仅业务库必要权限收权限目录写权限仅上传/缓存/日志可写调整属主与权限插件与遗留文件无未知来源文件清理并记录这份表我一般会打印出来贴在工位上逐项打勾。它的好处是不依赖任何工具任何人拿着都能查。最后分享一点我自己的体会。这类老系统的安全问题本质上不是某一个函数写错了而是“方便”和“安全”在设计阶段就被放在了天平的两端而当年的天平是偏向方便的。你今天去补不可能把天平整个翻过来只能一处一处地加约束。所以我做这类项目时从不追求“彻底解决”而是追求“把攻击链上最便宜的那几刀砍断”。把会话保护好、把写文件的路堵上、把输出统一编码这三件事做完绝大部分公开的利用手法就失效了。剩下的交给持续的巡检和日志告警去兜。
企业数字化 ERP 产品动态
相关推荐
HarmonyOS自定义背景二维码生成技术解析 1. 项目背景与核心需求 在移动应用开发中,二维码功能已经成为连接线上线下场景的重要桥梁。传统二维码往往只包含简单的黑白方块图案,缺乏视觉吸引力和品牌辨识度。这次我们要实现的是在HarmonyOS应用开发中生成带有自定义背景图片的二维码,这… · 2026/11/6 13:56:30
LTC681X工业级AFE驱动深度解析:时序校准、分层架构与功能安全集成 简介:本资源为ADI公司LTC681X系列高精度电池管理芯片(AFE)的官方驱动源码实现,面向嵌入式BMS开发工程师、电动汽车与储能系统硬件开发者及高校电力电子方向研究者,解决多节串联电池电压采集、寄存器配置、SPI通信与CRC… · 2026/11/6 13:55:28
企业级防火墙配置备份与还原:通道选择、风险控制与版本处理 边界设备的管理工作里,配置备份与还原是最不起眼、也最容易在关键时刻掉链子的一环。我在多个项目现场见过同样的剧本:设备跑了两三年没动过,某天要升级固件、要更换出口链路、要调整双机热备,动之前谁也没想起来导一份配置文件&a… · 2026/11/6 13:55:27
高效查找第K大元素:排序、堆与快速选择算法对比 1. 问题描述与核心挑战 给定整数数组 nums 和整数 k,我们需要找到数组中第 k 个最大的元素。请注意,这里要求的是排序后的第 k 个最大元素,而不是第 k 个不同的元素。 这个问题看似简单,但隐藏着几个关键挑战: 当数组… · 2026/11/6 15:05:13
企业设备数字化管理:易点易动系统实践指南 1. 设备管理在企业数字化转型中的核心价值 设备管理作为企业资产管理的重要组成部分,正在经历从传统人工记录向数字化、智能化管理的转变。在制造业、医疗、教育等行业,设备资产往往占据企业总资产的60%以上,其管理效率直接影响企业运营成本和… · 2026/11/6 15:05:13
企业元宇宙治理框架:技术实现与合规路径 1. 企业元宇宙治理框架的核心逻辑 企业元宇宙作为数字化转型的新阶段,其治理框架需要兼顾技术创新与合规要求。从技术架构角度看,企业元宇宙本质上是一个由数字孪生、区块链、人工智能等技术构成的复杂系统。这个系统需要解决三个核心问题:如… · 2026/11/6 14:59:51
基于CDC的MySQL实时数据同步方案实践 1. 项目背景与核心价值 在数据驱动的业务场景中,数据库表间数据同步是个高频需求。我最近在电商订单系统中就遇到了这个问题:订单主表数据变更后,需要实时同步到统计分析表和风控表。传统的手动同步或定时任务方式存在延迟高、易出错的问题&a… · 2026/11/6 14:00:34
JSP农贸交易系统开发与智能撮合算法实践 ## 1. 项目概述与核心价值农贸产品交易系统是连接农产品生产端与消费端的重要数字化桥梁。这个基于JSP技术的交易平台(项目编号g3608)完整包含了程序源码、数据库设计、部署指南和开发环境配置,是一套开箱即用的农产品B2B解决方案。我在参与某… · 2026/11/6 14:00:34
2025年3D建模工具选型实战指南:按工作流断点匹配生产力 1. 这不是选软件,是选你未来三年的“数字手”——为什么2025年建模工具选择比以往任何时候都更关键 2025年做3D建模,你面对的早已不是“用哪个软件画个模型”这么简单的事。它直接决定你能不能接单、能不能按时交付、能不能把想法一秒变现实、甚至决定你… · 2026/11/6 14:00:34
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 10:29:23
三菱PLC数据采集到数据库的时序设计:Python+MC协议实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11
ASIC主模式RTL设计:状态机与三态驱动的流片级实现 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11
STM32嵌入式C++开发:GDB调试与Renode仿真实战指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 10:29:23