1 前言
现在一般的web开发框架安全已经做的挺好的了,比如大家常用的django,但是一些不规范的开发方式还是会导致一些常用的安全问题,下面就针对这些常用问题做一些总结。代码审计准备部分见《php代码审计》,这篇文档主要讲述各种常用错误场景,基本上都是咱们自己的开发人员犯的错误,敏感信息已经去除。
2 XSS
未对输入和输出做过滤,场景:
def xss_test(request):
name = request.GET['name']
return HttpResponse('hello %s' %(name))
在代码中一搜,发现有大量地方使用,比较正确的使用方式如下:
def xss_test(request):
name = request.GET['name']
#return HttpResponse('hello %s' %(name))
return render_to_response('hello.html', {'name':name})
更好的就是对输入做限制,比如说一个正则范围,输出使用正确的api或者做好过滤。
3 CSRF
对系统中一些重要的操作要做CSRF防护,比如登录,关机,扫描等。django 提供CSRF中间件django.middleware.csrf.CsrfViewMiddleware,写入到settings.py的中间件即可。另外再在函数前加上@csrf_exempt修饰器。
4 命令注入
审计代码过程中发现了一些编写代码的不好的习惯,体现最严重的就是在命令注入方面,本来python自身的一些函数库就能完成的功能,偏偏要调用os.system来通过shell 命令执行来完成,老实说最烦这种写代码的啦。下面举个简单的例子:
def myserve(request, filename, dirname):
re = serve(request=request,path=filename,document_root=dirname,show_indexes=True)
filestr='authExport.dat'
re['Content-Disposition'] = 'attachment; filename="' + urlquote(filestr) +'"'fullname=os.path.join(dirname,filename)
os.system('sudo rm -f %s'%fullname)
return re
很显然这段代码是存在问题的,因为fullname是用户可控的。正确的做法是不使用os.system接口,改成python自有的库函数,这样就能避免命令注入。python的三种删除文件方式:
(1)shutil.rmtree 删除一个文件夹及所有文件
(2)os.rmdir 删除一个空目录
(3)os.remove,unlink 删除一个文件
使用了上述接口之后还得注意不能穿越目录,不然整个系统都有可能被删除了。常见的存在命令执行风险的函数如下:
os.system,os.popen,os.spaw*,os.exec*,os.open,os.popen*,commands.call,commands.getoutput,Popen*
推荐使用subprocess模块,同时确保shell=True未设置,否则也是存在注入风险的。