You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript加载局部视图被HP Fortify检出潜在XSS漏洞修复咨询

漏洞触发原因

HP Fortify 报XSS漏洞的核心命中逻辑是:代码中通过AJAX获取返回内容后,未做任何安全校验过滤,就直接通过jQuery的.html()方法插入DOM。哪怕接口是本地服务,只要返回的HTML中混入了未转义的用户可控恶意脚本、on*事件属性、javascript:伪协议链接,插入页面后就会自动执行,触发XSS风险。
另外原代码catch块还存在语法问题:选择器前缺少jQuery对象包裹,会直接抛JS错误。

适配高频调用场景的修复方案

因为该函数是全局高频调用的公共方法,修复优先保证调用方零改动、兼容原有逻辑、安全规则达标,按改造成本从低到高可选以下方案:

方案1:公共函数内嵌清洗逻辑(改造成本最低,快速落地)

只需要修改函数内部逻辑,所有现有调用点完全不需要调整,即可同时满足安全扫描要求和实际XSS防护需求:

  • 先对传入的div参数做格式校验,仅允许由字母、数字、下划线、中划线组成的合法DOM ID,阻断选择器注入风险。
  • 内置轻量HTML清洗逻辑,在内容插入DOM前,移除所有危险标签、事件属性、恶意协议,从DOM注入端阻断XSS执行。
  • 修复原catch块的语法bug。

修复后的完整代码如下:

// 内置无依赖HTML安全清洗方法
function sanitizeHtml(dirtyHtml) {
  const tempDom = document.createElement('div');
  tempDom.innerHTML = dirtyHtml;
  // 移除高风险标签
  const riskTags = ['script', 'iframe', 'object', 'embed', 'frame', 'link'];
  riskTags.forEach(tagName => {
    tempDom.querySelectorAll(tagName).forEach(el => el.remove());
  });
  // 遍历所有元素,移除风险属性
  const allNodes = tempDom.querySelectorAll('*');
  const eventAttrReg = /^on/i;
  const riskProtocolReg = /^(javascript|vbscript|data):/i;
  allNodes.forEach(node => {
    Array.from(node.attributes).forEach(attr => {
      // 移除所有on开头的事件属性
      if (eventAttrReg.test(attr.name)) {
        node.removeAttribute(attr.name);
      }
      // 移除href/src/action属性上的危险协议
      if (['href', 'src', 'action'].includes(attr.name.toLowerCase()) 
          && riskProtocolReg.test(attr.value.trim())) {
        node.removeAttribute(attr.name);
      }
    });
  });
  return tempDom.innerHTML;
}

function loadPartialViewToDiv(div, obj, api) {
  try {
    // 校验容器ID合法性,阻断选择器注入
    if (!/^[a-zA-Z0-9_-]+$/.test(div)) throw new Error('Invalid container id');
    const myUrl = new URL(window.location.origin + api);
    $.ajax({
      url: myUrl,
      data: obj,
      cache: false,
      type: "POST",
      dataType: "html",
      success: function (data) {
        if (data != null && data != undefined) {
          // 清洗后再插入DOM
          $('#' + div).html(sanitizeHtml(data));
        }
      }
    });
  } catch (e) {
    // 修复原代码缺少jQuery选择器的bug
    if (/^[a-zA-Z0-9_-]+$/.test(div)) {
      $('#' + div).html('Error');
    }
  }
}

这个方案的优势非常明显:所有改动都封装在公共函数内部,业务侧零改造成本,内置的清洗逻辑没有额外第三方依赖,能覆盖绝大多数常规XSS攻击场景,同时因为在DOM注入点前明确增加了输入过滤逻辑,完全可以通过Fortify的静态规则检测,不会再报XSS风险。

方案2:服务端+客户端纵深防护(长期维护推荐)

因为所有接口都是本地局部视图,从源头做防护的安全性更高:

  • 服务端渲染局部视图时,对所有用户可控的输出内容默认做HTML实体编码,从接口返回层就避免恶意脚本混入返回内容。
  • 对需要返回富文本内容的接口,服务端提前做标签白名单过滤,仅允许保留无执行风险的结构标签、样式属性,禁止返回脚本、事件属性、危险标签。
  • 接口增加CSRF校验,避免跨站伪造请求诱导接口返回恶意内容。

方案3:可信场景白名单适配

如果部分调用场景确实需要渲染带合法交互逻辑、脚本的可信局部视图,不要直接全局关闭清洗逻辑,可以给函数增加可选的可信标记参数:

  • 新增默认值为false的可选参数isTrusted,默认走清洗逻辑;
  • 只有经过安全确认,接口返回内容完全由服务端控制、无任何用户输入拼接的场景,调用时才传入true跳过清洗,这类调用需要单独加注释标注,避免被滥用。

参数调整参考:

function loadPartialViewToDiv(div, obj, api, isTrusted = false) {
  // 省略其他重复逻辑
  success: function (data) {
    if (data != null && data != undefined) {
      const renderContent = isTrusted ? data : sanitizeHtml(data);
      $('#' + div).html(renderContent);
    }
  }
}

注意:不要为了过扫描直接把AJAX返回内容标记为可信、或者关闭Fortify对应检测规则,这种操作没有解决实际风险,真实攻击场景下依然会被XSS打穿。

内容的提问来源于stack exchange,提问作者suvsuv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 01:42:36