【问题标题】:Is this sufficient validation/sanitization for my simple webapp?这对我的简单 web 应用程序来说是否足够验证/清理?
【发布时间】:2012-07-22 05:33:20
【问题描述】:

首先,我是 Web 开发的新手。我正在制作一个简单的 mod_wsgi webapp,它有两个文本字段来接受用户输入。

第一个输入 nnodes 必须是 0-30 之间的整数。

第二个输入,大小,必须是整数或介于 0-20 之间的浮点数。

这是迄今为止我在脚本中的验证/清理。看到我稍后在脚本中如何使用输入重定向,我希望有人可以评论我是否容易受到任何重大恶意威胁:

    nnodes = escape(nnodes)
    size = escape(size)

    if nnodes.isdigit() and int(nnodes) in range(31):
        pass
    elif nnodes=='':
        response_body=html % ' '
        status='200 OK'
        response_headers = [('Content-Type', 'text/html'),('Content-Length',str(len(response_body)))] 
        start_response(status, response_headers)
        return [response_body]
    else:
        response_body=html % 'Please enter the number of malignant nodes as a whole number between 0 and 30.'
        status='200 OK'
        response_headers = [('Content-Type', 'text/html'),('Content-Length',str(len(response_body)))] 
        start_response(status, response_headers)
        return [response_body]

###Validate that the tumorsize is a float between 0-25. 
    try:
        size=='' or float(size)
        pass
    except:
        response_body=html % 'Please enter the tumor size as a number between 0 and 25.'
        status='200 OK'
        response_headers = [('Content-Type', 'text/html'),('Content-Length',str(len(response_body)))] 
        start_response(status, response_headers)
        return [response_body]

    if 0<=float(size)<=25:
        pass
    elif size=='':
        response_body=html % ' '
        status='200 OK'
        response_headers = [('Content-Type', 'text/html'),('Content-Length',str(len(response_body)))] 
        start_response(status, response_headers)
        return [response_body]
    else:
        response_body=html % 'Please enter the tumor size as a number between 0 and 25.'
        status='200 OK'
        response_headers = [('Content-Type', 'text/html'),('Content-Length',str(len(response_body)))] 
        start_response(status, response_headers)
        return [response_body]

###After the validation, I use input redirection to pass the input to an R script.  I know this is not optimal but I can't get the Rpy2 module to work on my server.  
###I also know that input redirection can open an app up to shell injection, but that is why I am asking you all if I've done sufficient validation and sanitization.

commandString="/home/usr/bin/R --no-save --quiet --slave --args " + str(nnodes) + " " + str(size) + " </home/usr/webapps/simple/htdocs/webcalc.R"
subprocess.call(commandString,shell=True)

感谢大家提供的任何建议。

【问题讨论】:

  • 顺便说一句,您确实应该使用框架。 Flask 很好很简单,可以让你摆脱很多样板文件。如果您需要更多由数据库驱动的东西,您可以考虑使用 Django,因为它有一个很好的内置 ORM 和许多其他功能。

标签: python web-applications security


【解决方案1】:

“永远不要相信用户”就足够了。但是“永远不要相信程序员”是另一个有效的格言。即使您可能认为您的验证和清理程序是铁定的,也可能存在一个微妙的错误,可能允许恶意输入通过。安全总比后悔好。

我从手册页中找到了更多关于 R 解释器的信息。显然有一个 -f 参数可以让您指定输入文件。所以这整件事可以修复:

# Split out the filename for easier refactoring
r_script = '/home/usr/webapps/simple/htdocs/webcalc.R'
# We can give an iterable to subprocess.call()
command_args = ['/home/usr/bin/R', '-f', r_script, '--no-save', '--quiet', '--slave', '--args', str(nnodes),
    str(size)]
# And since we don't need shell features like '<', shell=True goes away!
subprocess.call(command_args)

请注意,验证和清理输入仍然非常重要。

【讨论】:

  • 非常感谢您的帮助,科林。我遇到了一个问题。由于-f 放在--args 之后,R 解释器将-f 视为命令行参数(就像str(size) 一样)。当我将 -f 放在 --args 之前时,我收到以下错误消息:ERROR: option '-f' requires an argument
  • @user1385991 我更新了我的示例。您需要在 --args 之前移动 -f 和它的参数
  • 非常感谢您的建设性帮助,科林。
【解决方案2】:

这段代码闻起来很糟糕。您对如何执行规则非常不清楚。您的代码完全缺乏抽象。

NO POINT,您在执行安全验证检查时是否应该使用 try/catch all 块。除非您捕获特定的异常类型,否则您不知道为什么操作可能会失败。对于所有用户数据,您应该能够检查类型、执行强制转换、检查值的范围而不会引发异常。此外,您应该使用单一方法来显示错误页面。

复杂性是安全最大的敌人。

--布鲁斯·施奈尔

【讨论】:

  • 这是我第一次尝试制作 Web 应用程序,而且我一开始并不是一个细致入微的程序员,所以闻起来难闻并不奇怪。我想了解更多关于您所指内容的信息,但谷歌搜索并没有出现非常有用的网站。当我搜索“网络应用程序抽象”时,我会得到关于网络应用程序开发的摘要。您能否指出我在抽象方面的一两个好的资源以及验证用户数据的正确方法(您说检查类型,执行强制转换......)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 2017-04-13
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多