安全编码指南

cybozu发表于:2016年08月24日 13:08:43更新于:2020年08月13日 12:21:41

Index

概要

使用API时,便利的同时也伴随着下述的风险。

  • 发生安全性上的问题

  • cybozu.cn的服务无法正常运行

这个页面将对使用API编码的注意事项进行说明。

防止跨站脚本攻击

跨站脚本攻击是什么?

跨站脚本攻击(Cross-site scripting,通常简称为XSS)是一种网站应用程序的安全漏洞攻击。通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。

可能发生的威胁

如果运行带有XSS脆弱性的程序,可能发生下面这样的情况。

  • kintone数据泄露

  • 显示虚假页面

  • web浏览器端储存带有恶意的Cookie

带有脆弱性的代码例子

var text1 = document.getElementById('text1');
var div1 = document.getElementById('div1');
div1.innerHTML = '<input type="text" value="' + text1.value + '" />';

这个代码,是将输入框text1 的值显示出来。如果在输入框text1 里输入下面这样的值,将会执行与当初开发者的设想完全不一样的代码。

"onclick="alert(1)

对策

对所有要输出的元素进行转义处理

外部输入递交给程序的字符串里,针对含有特殊意义的文字( < 、> 、”)做转义处理。但是,针对HTML元素进行恰当的转义处理,需要掌握很多的知识。因此,建议尽可能地避免使用document.write和 innerHTML来动态生成HTML。当然,使用innerText来代替innerHTML,也能防止大多数的XSS。

要输出的URL必须以 http://  或 https://  开头

当基于外部的输入,需要动态生成 a 标签 href 属性和 img 标签 src 属性的URL时,输入以javascript: 开头的字符串可能会嵌入脚本代码。为了防止这个,可以只输出以 http:// 和 https:// 开头的URL。

避免使用外部输入值来生成元素

不可使用下面的这种编码方式。

var tag = document.createElement("script");
tag.innerText = untrusted;

避免使用外部输入值来生成样式表

在样式表里,可以使用expression()来嵌入脚本。
因此,像下面这样的程序存在脆弱性问题。

var tag = document.createElement("div");
/* untrusted = "{ left:expression( alert('xss') )" 像这样就造成了XSS */
tag.style.cssText = untrusted;

不调用可疑的外部网站里的JavaScript 和 CSS

由于脚本是可以更改的,很有可能链接的外部网站脚本,某天会忽然变成盗取数据的程序。因此,在确定调用外部脚本的时候,请仔细斟酌被调用的网站是否是可靠的。

防止跨站请求伪造

什么是跨站请求伪造?

跨站请求伪造(Cross-Site Request Forgeries 以下CSRF)是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些攻击操作。

当针对cybozu.cn进行这种攻击的时候,就会模拟登录的用户发送请求,并执行这些请求。

可能发生的威胁

可能会执行一些非cybozu.cn用户本意的操作。

针对CSRF做的限制

在cybozu.cn 上,对于CSRF采取了下面的一些对策。

  • 只接受POST方法提交的请求

  • 只接受带有单独session的令牌的请求

因此,不使用API,直接对cybozu.cn发送请求是行不通的。

使用JavaScript 自定义时的注意点

因为针对CSRF对策有了以上的一些限制,在kintone的JavaScript自定义功能里调用的程序,事件的获取和请求的发送,需要使用本网站里的JavaScript API。

使用kintone REST API 时的注意点

因为针对CSRF对策有了以上的一些限制、不使用本网站里的kintone REST API 发送请求的话将无法从外部运行。
另外、基于API的请求,还需要包含认证信息。如何在请求里包含认证信息,请参考本网站的说明、kintone SDK和范例。

使用HTTPS进行通信

通信方法的限制

cybozu.cn的服务,根据HTTPS对客户的Web浏览器通信进行了加密。因此使用API的通信,也要使用HTTPS。

使用JavaScript 自定义时的注意点

通过kintone的JavaScript自定义功能里调用的程序导入外部网站的内容(JavaScript、CSS等)时,需要使用HTTPS进行通信。

使用REST API时的注意点

使用kintone REST API 通信的时候,需要使用HTTPS。cybozu.cn上发行的Cookie,因为加了secure属性,因此需要用HTTPS通信。另外,通信时使用“SecureAccess”时,需要使用客户证书来认证。使用客户端证书来验证的编码,可以参考kintone SDK 或者范例程序。

妥善处理验证信息

与第三方服务整合时,需要将第三方服务的验证信息保存在某个地方。

由于保存不当可能导致验证信息泄露,因此请务必慎重考虑验证信息的保存场所(限制验证信息的查看权限)。
特别是在进行JavaScript自定义时,往往容易将验证信息保存在一般用户也可以看到的地方。

验证信息的例子

  • 密码

  • API密钥

  • OAuth 客户端密钥/令牌

验证信息的保存场所

这里,按【仅管理员(有特定权限的人)可查看】和【一般用户也可以查看】这两类来进行介绍。
此处介绍的内容仅供参考。慎重起见,再次提醒请慎重考虑保存场所以防泄露!

推荐的保存场所

  • HttpOnly的Cookie ※2

※1: 通过插件来进行kintone自定义的话,可以使用Proxy来限制仅应用的管理员可查看验证信息。
详情请参考“kintone插件开发入门【Part2: 信息的隐藏方法篇】”。

※2: HttpOnly 的 Cookie可以防止来自JavaScript的访问。

不推荐的保存场所

作为比较常见的验证信息保存场所之一的Web Storage,可通过任意的JavaScript对其进行访问。
另外,kintone插件的设置以及非HttpOnly 的 Cookie也可以通过JavaScript访问。
因此,当访问带有恶意的网站时,验证信息可能会被非法使用。


妥善保存获取的数据

从cybozu.cn那取得的数据,可能包含了个人信息和机密信息。如这些信息要保存在外部应用里,请将这点考虑到程序设计及后续的运营里,避免由于数据的泄漏而造成的损失。 

利用JavaScript进行自定义时其他需要注意的地方

跨域限制

由于跨域限制、使用了XHR(XMLHttpReuest) 的cybozu.cn和外部网站无法通信。在头部里无法添加Access-Control-Allow-Origin 。

使用JavaScript取得Cookie

cybozu.cn的Cookie里由于附加了httponly属性,因此无法用JavaScript来取得cybozu.cn的Cookie 。

重定向到外部网站

基于外部输入值动态生成的URL赋值给以下对象时,请核实该URL,在确认的基础上编码。

  • location.href

  • document.location

  • window.open

使用严格(strict)模式

使用JavaScript的严格(strict)模式,就可以防止编码上的失误,制作出安全的东西。详细的严格(strict)模式说明可以参考 MDN文档

严格(strict)模式主要的特征

  • 只能赋值给事先声明过的变量

  • eval函数里定义的变量的作用域,只在这个函数内有效

  • 不支持arguments.calee

"use strict";
mistypedVaraible = 17; // throws a ReferenceError

考虑对服务的影响

对于一些有问题的程序,可能发生服务低下和无法使用的情况。

避免在短时间内发送大量的请求

自动发送大量请求的程序或并行同时执行大量请求的程序,往往是导致使服务质量变差的原因,比如响应速度下降。请注意:对那些会造成服务器高负荷,或消耗大量资源的请求,我们对此做了访问限制。

请在多个Web浏览器里确认运行状况

如果加载的JavaScript程序有问题的话,kintone的功能可能会无法正常运行。请仔细确认,您自定义的kintone功能是否符合您的意愿正常运行。
有时也有因为Web浏览器的种类和版本的差异,而发生问题的情况。推荐多使用几个Web浏览器,来确认运行正确与否。

设置合理的用户代理

为了能够判断是哪个服务或工具发来的请求,请设置合理的用户代理(User-Agent头)。

关于用户代理的指南,请参考以下的RFC 7231的"User-Agent"项。

    注意:贴代码时请注意格式并使用"代码语言",与本文无关的问题请至“讨论社区”提问。
    您需要登录后才可以回复