Python - 杀死挂起的功能

时间:2013-09-24 10:58:39

标签: javascript python timeout signals python-multithreading

我正在编写服务器后端,以解决可能在某些CTF挑战中托管的概念问题。 它将托管在Ubuntu 12.04 LTS,nginx 1.1.19和uWSGI 1.0.3-debian上,它将处理Python 2.7.3。

挑战的目标是利用参赛者浏览器上加载的JavaScript,通过成功注入函数调用来触发PyV8定义的函数runThis(),非常类似于XSS。下面描述的Python脚本将用作CGI并使用PyV8验证参赛者的输入,判断XSS是否成功。

但是,这个Python脚本容易受到DoS攻击的影响(我想有些参赛者可能会为这个脚本提供“while(1){}”)

我想通过将超时设置为evalJavaScript()来解决此问题,因此我尝试采用一种使用来自https://stackoverflow.com/a/601168/1402144此引用的SIGALRM的解决方案,但它无效。

这是概念代码(大大简化了以免过多地泄露游戏,并专注于当前关于超时的问题):

#!/usr/bin/env python

import PyV8
import cgi, cgitb
import signal
from contextlib import contextmanager

# Timeout handler
class TimeoutException(Exception):
    pass

@contextmanager
def time_limit(seconds):
    def timeout(signum, frame):
        raise TimeoutException, "Timed out!"
    signal.signal(signal.SIGALRM, timeout)
    signal.alarm(seconds)
    try:
        yield
    finally:
        signal.alarm(0)
# end Timeout handler

# check JavaScript
class Global(PyV8.JSClass):
    def runThis(self):
        print "You have called this function via JavaScript."

def evalJavaScript(post_data):
    try:
        ctxt = PyV8.JSContext(Global())
        ctxt.enter()
        ctxt.eval(post_data)
        ctxt.leave()
    except Exception, e:
        print e
        print "Perhaps syntax error? Try again!"
# end JavaScript

# CGI
form = cgi.FieldStorage()

print 'Content-type: text/html'
print

try:
    with time_limit(5):
        evalJavaScript(form.getvalue('javascript'))
except TimeoutException, msg:
    print "Timed out!"

# end CGI
  • 网址:http://localhost/validation.py?javascript=runThis()

    • 结果:“您已通过JavaScript调用此功能。”
  • 网址:http://localhost/validation.py?javascript=while(1){}

    • 结果:Nginx超时,而Python脚本以100%的CPU使用率运行。 我还向流程发布了kill -ALRM ${pid},但它对它没有任何影响。

我还测试了一个非常小的脚本,它起作用了。

import signal
from time import sleep

def main():
    while 1:
        sleep(1)
        print "main"

def timeout_handler(signum, frame):
    raise Exception

signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(10)

try:
    main()
except:
    print "whoops"

以下是我目前看过的参考资料:

你能不能给我一个关于我做错了什么的暗示,或者甚至更好,建议一个更好的方法来实现反DoS解决方案?

0 个答案:

没有答案