素材巴巴 > 程序开发 >

easy_tornado复现

程序开发 2023-09-18 13:28:52

Easy_tornado分析

问题与解答

  1. cookie_secret是什么?
    答:根据Tornado官方文档的解释:这是settings中关于认证和安全方面的一个配置参数。

  2. settings又是什么?

    答:是一个python字典。通常用作于application的配置项。

  3. application是什么?
    答:这个问题会比较难直接回答。这需要先理解一个tornado web应用是如何工作的。
    我们先看Tornado官方给的一个Hello World程序的例子:

    import tornado.ioloop
     import tornado.webclass MainHandler(tornado.web.RequestHandler):"""主路由处理类"""def get(self):"""对应http的get请求方式"""self.write("Hello, world")if __name__ == "__main__":application = tornado.web.Application([(r"/", MainHandler),])application.listen(8888)tornado.ioloop.IOLoop.current().start()
     

    这段代码做的事情是创建一个web应用实例的对象,初始化参数传入路由映射列表。

    可以看到MainHandler继承了RequestHandlerRequestHandler封装好了对一个请求的处理方法:例如write()就是写响应信息的方法。

    之后创建服务器实例,绑定好指定的8888端口,让ioloop模块帮助我们处理I/O请求。

    这里借用一张图来说明工作流程:

    img

    最后可以解释application的作用了,实际上他负责把URL请求按照映射列表去调用指定的处理类。

    源码中的注释也解释了application到底是什么:

    A collection of request handlers that make up a web application.
     
  4. 要怎么样才能访问到settings中的内容?
    答:通过阅读tornado的源码可以看到:

    class Application(ReversibleRouter):def __init__(self,handlers: Optional[_RuleList] = None,default_host: Optional[str] = None,transforms: Optional[List[Type["OutputTransform"]]] = None,**settings: Any) -> None:......self.default_host = default_hostself.settings = settings
     

    阅读application的构造函数可以发现,settingsapplication类中的一个公开的成员变量,因此,只要有办法在当前创建运行的application类中访问self.application.settings就能够获取我们想要的cookie_secret。另外,在官方文档中提到,self.application.settings这种写法等同于RequestHandler.settings

    目前,我们依旧不知道怎么才能让服务器返还我们想要的数据。

  5. 在哪里注入?怎么注入?

    /welcome.txt提示了render函数,明摆着是存在服务器模板注入了,通过测试也确实发现了URL/error?msg=Error这个页面存在注入。

    这里需要解释一下render函数是如何处理变量,以及获取cookie_secret的payload是怎么被构造出来的

    1. render函数怎么处理模板中的变量?
      答:在模板中以{{}}的形式引入变量,像是模板继承等操作也是类似的做法,在html页面的指定位置留下一块地方给模板引擎进行填充。

    2. 为什么payload是{{handler.settings}}?

      答:其实问的是为什么handler能够指向当前执行render函数的类,这是因为tornado提供了一些对象别名来快速访问对象。这是由命名空间实现的,源码如下:

      def get_template_namespace(self) -> Dict[str, Any]:"""Returns a dictionary to be used as the default template namespace."""namespace = dict(handler=self,request=self.request,current_user=self.current_user,locale=self.locale,_=self.locale.translate,pgettext=self.locale.pgettext,static_url=self.static_url,xsrf_form_html=self.xsrf_form_html,reverse_url=self.reverse_url,)namespace.update(self.ui)return namespace
       

      函数get_template_namespaceRequestHandler类中的一个方法,用于返回一个命名空间的字典,可以看到其中定义了handler指向自身,也就是当前的RequestHandler类,模板引擎在处理变量的时候可以根据命名空间快速访问对象。

参考文档

  1. Python中从服务端模板注入到沙盒逃逸的源码探索 (一)
  2. 上文作者提供的题目源码
  3. Tornado官方文档
  4. Tornado简易教程

标签:

上一篇: nginx的两种安装流程 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。