《开放平台第三方应用安全开发指南》给出常见开发场景下,帮助开发人员完善应用安全性的开发建议,同时也对常见的安全漏洞进行描述,并提供对应的修复方案。
敏感信息指用户的 身份证号、银行卡号、手机号 等身份信息。重要敏感信息的脱敏规范如下。
敏感信息类型 | 展示规范 |
---|---|
身份证 | 显示前 1 位 + *(实际位数) + 后 1 位,如: 3****************3 |
银行卡 | 显示前 6 位 + *(实际位数) + 后 4 位,如:622575******1496 |
手机号 | 显示前 3 位 + **** + 后 4 位,如:137****9050 |
1.1.1. 敏感信息用于展示的场景
1.1.2. 敏感信息用于身份校验的场景
HttpOnly
属性为 true
HttpOnly
为 true,将可以禁止 JavaScript 读取页面 Cookie 信息,一定程度上防范 XSS 攻击。secure
属性为 true
secure
为 true,Cookie 信息将不会在 HTTP 连接中传输,一定程度上防范 XSS 攻击。Content-Type
为 application/json;charset=utf-8
POST
方式提交表单
[a-zA-Z0-9_-.]+
字符。1.7.1. JSONP 跨域
Content-Type
为 application/javascript;charset=utf-8
1.7.2. CORS 跨域
Access-Control-Allow-Origin
必须使用白名单验证,禁止直接返回*
不同场景使用的加密算法请参考下表。
场景 | 算法 |
---|---|
加密场景 | AES128 |
摘要场景 | SHA256 |
签名场景 | RSA2048 |
漏洞描述
跨站脚本攻击(Cross Site Scripting, XSS)发生在客户端,可被用于进行窃取隐私、钓鱼欺骗、偷取密码、传播恶意代码等攻击行为。 恶意的攻击者将对客户端有危害的代码放到服务器上作为一个网页内容, 使得其他网站用户在观看此网页时,这些代码注入到了用户的浏览器中执行,使用户受到攻击。一般而言,利用跨站脚本攻击,攻击者可窃会话 Cookie 从而窃取网站用户的隐私。
漏洞危害
解决方案
代码示例
ASP 问题示例代码
<% Dim param Set param=Request.QueryString("dd") response.write param %>
ASP 修复示例
<% Dim param Set param=Request.QueryString("dd") response.write Server.HTMLEnCode(param) %>
PHP 问题代码示例
<?php $aa=$_GET['dd']; echo $aa."123"; ?>
PHP 修复示例
<?php $aa=$_GET['dd']; echo htmlspecialchars($aa)."123"; ?>
漏洞描述
跨站请求伪造(Cross-Site Request Forgery, CSRF),恶意网站通过脚本向当前用户浏览器打开的其它页面的 URL 发起恶意请求,由于同一浏览器进程下 Cookie 可见性,导致用户身份被盗用,完成恶意网站脚本中指定的操作。
漏洞危害
解决方案
CSRF漏洞修复方案主要思路有两类:
漏洞描述
Web 程序代码中把用户提交的参数未做过滤就直接输出到 HTTP 响应头中,导致攻击者可以利用该漏洞来注入到 HTTP 响应头中实现攻击。
解决方案
%0d%0a、%0D%0A
字符。漏洞描述
目录遍历是由于 Web 服务器或 Web 应用程序对用户输入文件名称的安全性验证不足而导致的一种安全漏洞,使得攻击者通过 HTTP 请求和利用一些特殊字符就可以绕过服务器的安全限制,访问任意受限的文件(可以是 Web 根目录以外的文件),甚至执行系统命令。
解决方案
漏洞描述
SQL 注入攻击(SQL Injection),被广泛用于非法获取网站控制权,是发生在应用程序的数据库层上的安全漏洞。 在设计不良的程序当中,忽略了对输入字符串中夹带的 SQL 指令的检查,那么这些夹带进去的指令就会被数据库误认为是正常的 SQL 指令而运行,从而使数据库受到攻击,可能导致数据被窃取、更改、删除,以及进一步导致网站被嵌入恶意代码、被植入后门程序等危害。
漏洞危害
解决方案
'"\<>&*;
等进行转义处理,或编码转换。代码示例
ASP 漏洞代码示例
<% Dim oComm, oRs Set id = Request.QueryString("d") Set oConn = Server.CreateObject("ADODB.Connection") oConn.Open "Provider=MSDAORA;Password=sth;Persist Security Info=True;User ID=whats;Data Source=mescp" Set oComm = CreateObject("ADODB.Command") oComm.ActiveConnection = oConn oComm.CommandType = 1 oComm.CommandText = "select * from all_objects where rownum ="& id Set oRs = oComm.Execute %>
ASP 修复示例
<% Dim oComm, oRs Set oConn = Server.CreateObject("ADODB.Connection") oConn.Open "Provider=MSDAORA;Password=sth;Persist Security Info=True;User ID=whats;Data Source=mescp" Set oComm = CreateObject("ADODB.Command") oComm.ActiveConnection = oConn oComm.CommandType = 1 oComm.CommandText = "select * from all_objects where rownum = ? " oComm.Parameters.Append oComm.CreateParameter("v1",3,1,4,100) Set oRs = oComm.Execute %>
PHP 漏洞代码示例
<?php $id=$_GET['id']; $conn = mysql_connect("localhost","root","") or die ("wrong!"); $sel=mysql_select_db("mydb",$conn); $sql="select * from user where id = ".id $que=mysql_query($sql,$conn); ?>
PHP 修复示例
<?php $id=$_GET['id']; $conn = mysql_connect("localhost","root","") or die ("wrong!"); $sel=mysql_select_db("mydb",$conn); $sql="select * from user where id = :id" $stmt = $conn->prepare($sql); $stmt->execute(array(':id'=>$id)); ?>
JAVA 漏洞代码示例
JdbcConnection conn = new JdbcConnection(); final String sql = "select * from product where pname like '%" + request.getParameter("pname") + "%'"; conn.execqueryResultSet(sql);
JAVA 修复示例
JdbcConnection conn = new JdbcConnection(); PreparedStatement pstmt = conn.prepareStatement("select * from product where pname like ?"; pstmt.setString(1, “%”+ request.getParameter("pname")+”%”); pstmt.execute();
漏洞描述
Web 应用程序在处理文件下载时,接受用户指定的路径和文件名进行下载,攻击者利用此漏洞来下载服务器的其它文件甚至任意文件(源代码、数据库甚至 passwd 等)。
解决方案
漏洞描述
文件上传的 Web 程序未对文件类型和格式做合法性校验,导致攻击者可以上传 Webshell 或者非期望格式的文件。
解决方案
代码示例
PHP 问题代码示例
if ($_FILES["file"]["error"] > 0) echo "Error: " . $_FILES["file"]["error"] . "<br />"; else move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
PHP 修复示例
<if ((($_FILES["file"]["type"] == "image/gif") || ($_FILES["file"]["type"] == "image/jpeg") || ($_FILES["file"]["type"] == "image/pjpeg")) && ($_FILES["file"]["size"] < 20000)) { if ($_FILES["file"]["error"] > 0) echo "Error: " . $_FILES["file"]["error"] . "<br />"; else move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); } else echo "Invalid file";