使用JavaScript进行安全编码时需要注意的事

cybozu发表于:2016年12月09日 18:05:20更新于:2021年04月20日 15:13:22

kintone可以使用Javascript自由地自定义。

用自定义可以构筑独立而丰富的UI,也可以追加新的功能,但是如果不安全编码的话,就有可能会出现难以抵御跨站脚本攻击,系统稳定性下降的危险。

这一篇为大家讲解的是在Javascript安全地进行编码的注意事项。

主要原因

容易存在脆弱性一个最主要的原因是,动态生成元素。特别是,记录信息等需要用户输入值来生成元素的时候,特别容易发生脆弱性。

对策

使用document.write()element.innerHTML生成元素的时候,作为内容的字符串请一定用HTML来escape。

以下,是使用HTML escape的范例。

function escapeHtml(str) {
    str = str.replace(/&/g, '&');
    str = str.replace(/</g, '&lt;');
    str = str.replace(/>/g, '&gt;');
    str = str.replace(/"/g, '&quot;');
    str = str.replace(/'/g, '&#39;');
    return str;
}

以下是使用的范例。

// 不好的例子
element.innerHTML = '<span class="foo">' + value + '</span>';
// 好的例子
element.innerHTML = '<span class="foo">' + escapeHtml(value) + '</span>';

大原则是妥当地进行HTML escape,除此之外还整理了下面这些需要注意的点。

应该注意的地方

不从不可靠的外部网站获取数据

使用JSONP或kintone.proxy()从外部网站获取数据的时候,请确认一下数据的提供源是否可靠。

另外,以下的情形,也请一定确认下提供来源。

  • 设定img标签或者script标签的src属性时

  • 使用外部网站提供的JavaScript或者CSS的时候

不动态生成JavaScript代码

eval("...")<span onclick="...">这样,希望能够避免字符串的方式来写JavaScript代码。这样会带来代码可读性下降,破坏代码范围,无法进行妥当地escape这样的风险。

JSON的路径里使用JSON.parse()

使用kintone.api()之类获取到的JSON对象的路径里,要使用JSON.parse()。JSON作为JavaScript的对象,虽然可以使用eval()new Function(),但是很有可能会导致无法escape和XSS的漏洞,所以请不要使用。

URL的加密使用encodeURIComponent()

设置a标签的href属性(链接目的地),替换location.href的情形之类的,请一定使用encodeURIComponent()来escape。

// 不好的例子
location.href = '/k/1234/show?param=' + param;
// 好的例子
location.href = '/k/1234/show?param=' + encodeURIComponent(param);

不保存存有用户相关信息的cookie或者localStorage

为了防止将数据持续留存在浏览器上,无意间泄漏给第三方的情况发生,用户的个人信息或者输入的数据,请避免保存在客户端的存储设备里。

比如,像下面这些数据。

  • 登录ID, 简介

  • 记录信息

  • 访问权限

使用最新版本的第三方库

根据版本库,有些特定的版本可能存在脆弱性,光是读入的话就可能招致攻击。为防止由于库的版本原因而导致的脆弱性,请经常保持使用最新的版本。

危险的数据来源

基本上无论什么样的元素生成,都需要escape处理。以下的数据特别容易导致脆弱性,需要注意。

  • 记录信息(用户的输入值)

  • 从外部获取的数据(从第三方拿到的数据)

  • URL参数(用户的输入值)

从用location.hreflocation.hash获取到的URL信息里提取出特定的参数,这样的处理经常会有。URL里用户可以任意地输入值,所以有必要和记录信息之类的用户输入值做同样的处理。

危险的操作

下面举一些特别容易引起脆弱性的JavaScript的代码范例。使用这些的时候,必须要妥当地进行escape。

// 生成元素
document.write("...")
element.innerHTML = "..."
// 设置属性
element.setAttribute(name, value)
element.someAttribute = "..." // someAttribute是指href,onclick,style,src之类
// URL操作
location.href = "..."

另外,URL操作时需要做加密处理,并保证链接目标的网站是可靠的。

其他需注意的点

尽量不要使用同步的XMLHttpRequest

同步XMLHttpRequest会导致通信中的浏览器停滞之类的性能问题,而且Firefox也不推荐使用(英文),所以请尽量不要使用同步XMLHttpRequest。

使用第三方库时的注意点

以jQuery为代表的运行DOM操作的库,因为用户看不到在内部操作的DOM API,有时不知不觉就进行了上述的危险操作。

比如,jQuery的html()方法在内部与innerHTML是一样的,所以很容易将传递的字符串就这样作为HTML打开。为此,内容部分有必要使用text()进行escape操作等对策。

// 不好的例子
$(el).html($('<span class="foo">' + value + '</span>');
// 好的例子
$(el).html($('<span class="foo">').text(value));

使用库的时候,和平时一样需要注意escape。

结束语

此篇为大家说明了为在Javascript里进行安全编码的注意事项。希望对于大家在作成可以放心使用的Javascript自定义时会有所帮助。

也请大家参考一下安全编码指南