Python网站的漏洞检查

幸运草 2020年5月21日22:35:05安全防范评论阅读模式

流量劫持:到底是谁在耍流氓?

最近我们的一个测试问是否有针对Python代码的静态分析工具。他正在评审一个用python编写的网站应用,试图找出其中是否有高风险的问题。我不确定是否有方便使用并专注于python代码安全性的分析工具,因为大多数可用的工具都是专注于语法编译而不是安全性,也有一些专注于安全性的工具,如Fortity,非常昂贵。不过,我可以给他一个高风险问题的列表,这些问题都可以通过人工评审很容易地被发现。通过这份列表可以让他检查出很多我们标准网站应用检查表中的高风险问题。

SQL注入

查找所有含有SQL查询的文件,你要找到使用和下面语法类似的查询语句:

stmt = "SELECT * FROM table WHERE id=?" connection.execute(stmt, (value,))

这意味着应用程序是使用参数化的查询。你不能找到以下任何一个的查询:

"SELECT * FROM table WHERE id=" + value

"SELECT * FROM table WHERE id=%s" % value

"SELECT * FROM table WHERE id={0}".format(value)

如果没有其他合适的处理这些都会导致SQL注入,最好还是使用参数化的形式。

命令注入

查找所有含有导入OS模块的文件。仔细检查这些文件确保没有不可接受的用户输入传递给os.popen*, os.spawn*, os.fork, os.system, 或者 os.exec* 。同时也要检查任何popen2模块和commands模块的调用。记住,除了os.exec*和os.spawn*,以上其他的方法和模块都不赞成使用,从Python2.6开始使用subprocess模块。任何还在使用这些方法或者包的应用都应修改为使用subprocess模块。虽然不反对,还是建议使用subprocess替换os.spawn*。

查找含有导入subprocess模块的文件,确保没有不可接受的用户输入传递给保重的任何方法。默认情况下所有的subprocess方法会将shell参数设定为False,以防止shell特殊字符被解释。这可以防止典型的命令注入攻击。如果需要将shell参数设置为True,那么根据你的python版本使用pipes.quete()和shlex.quote()函数先审查用户输入。

不能有以下调用方式:

subprocess.call("cat " + user_input, shell=True)

subprocess.call("cat %s" % user_input, shell=True)

subprocess.call("cat {0}".format(user_input), shell=True)

如果shell=True 是必须的那么请这样调用:

subprocess.call("cat " + pipes.quote(user_input), shell=True)

subprocess.call("cat %s" % pipes.quote(user_input), shell=True)

subprocess.call("cat {0}".format(pipes.quote(user_input)), shell=True)

如果shell=True不是必须的那么这样的调用已经足够,但是我还是建议对用户输入信息进行检查:

subprocess.call("cat " + user_input)

subprocess.call("cat %s" % user_input)

subprocess.call("cat {0}".format(user_input))

目录穿越漏洞

查找使用open()语句或者调用os.fdopen()方法的文件,确保没有不可接受用户输入传递给这些方法。

避免出现如下形式的调用:

open(user_input)

os.fdopen(user_input)

在打开一个文件前,先检查用户的输入,然后确定这个文件打开是否安全。这里有一个很好的例子:https://security.openstack.org/guidelines/dg_using-file-paths.html:

Python网站的漏洞检查
这将获得用户输入的绝对路径,并确保它从当前的工作目录开始,如以下:

Python网站的漏洞检查
根据python代码的结构,可以不适用当前的工作目录。任务目录路径都是可以用的。

跨站脚本

这个程序没有使用模板语言,因此需要在所有文件中查找使用cgi模块的文件,确保所有用户提供的输入都会使用cgi.escape()写回浏览器。cgi.escape()会将<,>,和&替换成HTML中的对应的符号。cgi.escape()的第一个参数是需要转换的字符串。第二个参数默认值为False,可以用来判断是否将双引号也进行转换。如果用户输入将在内部属性中使用,那么双引号也应该被转换。

CGI脚本使用简单的打印语句来创建从网站服务器返回给网页浏览器的页面。如下形式的调用应当避免:

print(user_input)

应当使用下面的:

print(cgi.escape(user_input))

两者间的差异可以在下面的例子中清除的看到:

Python网站的漏洞检查
下面一个例子展示了将双引号替换的理由。在第一个打印语句中用户输入增加了一个新的属性,在第二个将引号替换防止用户输入插入一个新的属性。

Python网站的漏洞检查
异常处理

审查应用程序,确保适当的异常处理和日志记录。具体地说,寻找try/except子句,并确保捕获的异常记录在日志中和得到适当的处理。在Python中一个常见的模式是使用如下所示的try/except子句:

Python网站的漏洞检查
这种模式捕获所有的异常,并简单地忽略它们,而不是记录和处理它们。一个更合适的模式应该是这样的:

Python网站的漏洞检查
思考

在这种特殊的情况下,用python写Web应用没有使用框架(框架常常可以保护开发者避免犯上面提到的最基本的错误)。如果你要写一个基于Python的web应用,我建议你使用一个好的框架,像Flask,CherryPy,Web2P或者Django。使用框架不能保证你不会遇到这些基本的问题带来的麻烦,但如果使用恰当,可以防止大多数问题的发生。

另一件事要记住,上面列出一些安全问题及其修复建议并不局限于Web应用。在生产环境中使用的任何Python脚本都应该检查这些问题。

特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

如何以安全服务增强企业网络安全

网络罪犯不断地改变其攻击和方法,以保持领先于企业的安全措施。这种持续的威胁演变迫使企业持续地准备防御新的攻击手段。企业能否成功防御依赖于如何预测下一种威胁,减小与网络攻击者的差距并及时修补漏洞。 企业的困难在于:网络、设备和以前所未有的速率添加到网络中的应用程…

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
幸运草

发表评论