Python 模板引擎的注入问题分析

这几年比较火的一个漏洞就是jinjia2之类的模板引擎的注入,通过注入模板引擎的一些特定的指令格式,比如 {{1+1}} 而返回了 2 得知漏洞存在。实际类似的问题在Python原生字符串中就存在,尤其是Python 3.6新增 f 字符串后,虽然利用还不明确,但是应该引起注意。

最原始的 %

userdata = {"user" : "jdoe", "password" : "secret" }
passwd = raw_input("Password: ")

if passwd != userdata["password"]:
  print ("Password " + passwd + " is wrong for user %(user)s") % userdata

如果用户输入 %(password)s 那就可以获取用户的真实密码了。

format方法相关

https://docs.python.org/3/library/functions.html#format

除了上面的payload改写为 print ("Password " + passwd + " is wrong for user {user}").format(**userdata) 之外,还可以

>>> import os
>>> '{0.system}'.format(os)
'<built-in function system>'

会先把 0 替换为 format 中的参数,然后继续获取相关的属性。

但是貌似只能获取属性,不能执行方法?但是也可以获取一些敏感信息了。

例子: http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/

CONFIG = {
  'SECRET_KEY': 'super secret key'
}

class Event(object):
  def __init__(self, id, level, message):
    self.id = id
    self.level = level
    self.message = message

def format_event(format_string, event):
  return format_string.format(event=event)

如果 format_string 为 {event.__init__.__globals__[CONFIG][SECRET_KEY]} 就可以泄露敏感信息。

Python 3.6中的 f 字符串

这个字符串非常厉害,和Javascript ES6中的模板字符串类似,有了获取当前context下变量的能力。

https://docs.python.org/3/reference/lexical_analysis.html#f-strings

>>> a = "Hello"
>>> b = f"{a} World"
>>> b
'Hello World'

而且不仅仅限制为属性了,代码可以执行了。

>>> import os
>>> f"{os.system('ls')}"
bin   etc   lib   media  proc   run   srv   tmp   var
dev   home   linuxrc mnt   root   sbin   sys   usr
'0'

>>> f"{(lambda x: x - 10)(100)}"
'90'

但是貌似 没有 把一个普通字符串转换为 f 字符串的方法,也就是说用户很可能无法控制一个 f 字符串,可能无法利用,还需要继续查一下。

(0)

相关推荐

  • Python Web开发模板引擎优缺点总结

    做 Web 开发少不了要与模板引擎打交道.我陆续也接触了 Python 的不少模板引擎,感觉可以总结一下了. 一.首先按照我的熟悉程度列一下:pyTenjin:我在开发 Doodle 和 91 外教时使用.Tornado.template:我在开发知乎日报时使用.PyJade:我在开发知乎日报时接触过.Mako:我只在一个早期就夭折了的小项目里用过.Jinja2:我只拿它做过一些 demo. 其他就不提了,例如 Django 的模板,据说又慢又难用,我根本就没接触过. 二.再说性能 很多测试就是

  • 为Python的Tornado框架配置使用Jinja2模板引擎的方法

    tornado 默认有一个模板引擎但是功能简单(其实我能用到的都差不多)使用起来颇为麻烦, 而jinja2语法与django模板相似所以决定使用他. 下载jinja2 还是用pip 下载(用的真是爽) pip install jinja2 这样就可以使用了. tornado与jinja2 整合 tornado和jinja2整合起来很简单(其实是网上找的比较简单), 不知道从那里找到的反正找到了,不说了直接上代码 #coding:utf-8 import tornado.web from jinj

  • python Django模板的使用方法(图文)

    模版基本介绍模板是一个文本,用于分离文档的表现形式和内容. 模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签). 模板通常用于产生HTML,但是Django的模板也能产生任何基于文本格式的文档.来一个项目说明1.建立MyDjangoSite项目具体不多说,参考前面.2.在MyDjangoSite(包含四个文件的)文件夹目录下新建templates文件夹存放模版.3.在刚建立的模版下建模版文件user_info.html 复制代码 代码如下: <html>    <

  • Python的Flask框架标配模板引擎Jinja2的使用教程

    Jinja2需要Python2.4以上的版本. 安装 按照Jinja有多种方式,你可以根据需要选择不同的按照方式. 使用easy_install 或pip: #sudo easy_install Jinja2 #sudo pip install Jinja2 这两个工具可以自动从网站上下载Jinja,并安装到python目录的site-packages目录中. 从tar包安装: # 下载Jinja的安装包 # 解压缩 # sudo python setup.py install 基本API用法

  • 基于python实现微信模板消息

    我的风格,废话不多说了,直接给大家贴代码了,并在一些难点上给大家附了注释,具体代码如下所示: #!/usr/bin/env python #-*- coding:utf-8 -*- import urllib2,json import datetime,time from config import * import sys reload(sys) sys.setdefaultencoding("utf-8") class WechatPush(): def __init__(self

  • Python实现的简单模板引擎功能示例

    本文实例讲述了Python实现的简单模板引擎功能.分享给大家供大家参考,具体如下: #coding:utf- 8 __author__="sdm" __author_email='sdmzhu3@gmail.com' __date__ ="$2009-8-25 21:04:13$" '' ' pytpl 类似 php的模板类 '' ' import sys import StringIO import os.path import os #模 板的缓存 _tpl_c

  • Python的Flask框架中的Jinja2模板引擎学习教程

    Flask的模板功能是基于Jinja2模板引擎来实现的.模板文件存放在当前目前下的子目录templates(一定要使用这个名字)下. main.py 代码如下: from flask import Flask, render_template app = Flask(__name__) @app.route('/hello') @app.route('/hello/<name>') def hello(name=None): return render_template('hello.html

  • 常用python编程模板汇总

    在我们编程时,有一些代码是固定的,例如Socket连接的代码,读取文件内容的代码,一般情况下我都是到网上搜一下然后直接粘贴下来改一改,当然如果你能自己记住所有的代码那更厉害,但是自己写毕竟不如粘贴来的快,而且自己写的代码还要测试,而一段经过测试的代码则可以多次使用,所以这里我就自己总结了一下python中常用的编程模板,如果还有哪些漏掉了请大家及时补充哈. 一.读写文件 1.读文件 (1).一次性读取全部内容 filepath='D:/data.txt' #文件路径 with open(file

  • 深入解析Python的Tornado框架中内置的模板引擎

    template中的_parse方法是模板文法的解析器,而这个文件中一坨一坨的各种node以及block,就是解析结果的承载者,也就是说在经过parse处理过后,我们输入的tornado的html模板就变成了各种block的集合. 这些block和node的祖宗就是这个"抽象"类, _Node,它定义了三个方法定义,其中generate方法是必须由子类提供实现的(所以我叫它"抽象"类).  理论上来说,当一个类成为祖宗类时,必定意味着这个类包含了一些在子类中通用的行

  • Python的Django框架中模板碎片缓存简介

    你同样可以使用cache标签来缓存模板片段. 在模板的顶端附近加入{% load cache %}以通知模板存取缓存标签. 模板标签{% cache %}在给定的时间内缓存了块的内容. 它至少需要两个参数: 缓存超时时间(以秒计)和指定缓存片段的名称. 示例: {% load cache %} {% cache 500 sidebar %} .. sidebar .. {% endcache %} 有时你可能想缓存基于片段的动态内容的多份拷贝. 比如,你想为上一个例子的每个用户分别缓存侧边栏.

随机推荐