如何在phantomJS中正确添加csrf标记

时间:2016-03-29 09:14:25

标签: phantomjs

我想在phantomJS中将网站的内容作为pdf获取,这非常简单,如phantomJS docs中所述

phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf

到目前为止一切顺利。我目前的问题是,我想要打印为pdf的网页需要登录的用户并发布包含2个输入字段的表单!输入字段是开始日期和结束日期,它生成所需网站的结果,稍后将以pdf格式打印。该站点是用Django编写的,默认情况下需要一个csrf令牌。我写了这段代码,它不起作用,即使它不会帮助我,因为我无法在栅格化的帮助下将它用于将页面内容转换为pdf。

"use strict"
var page = require('webpage').create(),
    server = 'http://10.0.3.201:8000/report/',
    data = 'start_date=23.03.2016&end_date=24.03.2016';

page.settings.userName = 'ubuntu';
page.settings.password = 'ubuntu';

page.includeJS(
    // Include the http version, you can change this to http if you like.
    'https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js',
    function() {
        (page.evaluate(function getCookie(name) {
            var cookieValue = null;
            if (document.cookie && document.cookie != '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
        phantom.addCookie({
            'name'      : 'csrf',
            'value'     : getCookie('csrftoken'),
            'domain'    : 'localhost',
            'path'      : 'report',
            'httponly'  : true,
            'secure'    : false,
            'expires'   : (new Date()).getTime() + (1000 * 60 * 60)
        });
        )
    }
);

page.open(server, 'post', data, function(status) {
    if (status !== 'success') {
        console.log('Unable to post!');
    } else {
        console.log(page.content);
    }
    phantom.exit();
});

我非常无能为力,甚至不知道我想用phantomJS做什么是可能的。非常感谢帮助!

1 个答案:

答案 0 :(得分:3)

Django在每个GET中使用csrf令牌设置一个cookie(并且在Forms内部的DOM中,如果它在POST模板中配置),但是这个cookie不用于验证服务器中的POST请求(这会导致安全漏洞)。

Django似乎从标准POST主体(表单数据)或名为X-CSRFToken的自定义HTTP标头中读取csrf标记。

因此,要伪造有效请求,您必须模拟标准用户交互:

  • 对为您需要的POST创建csfr标记的页面进行GET(可以是autopostback中的同一页面或具有FormAction =&#34的其他页面; postDestination&#34;)。此响应将在Form DOM和cookie中附带一个csrf令牌。
  • 从cookie或DOM获取csrf令牌
  • 伪造有效的POST请求,在表格数据请求和/或自定义标题中设置令牌。
  • 您应该收到可以呈现为pdf的成功回复。

如果rasterize.js不允许上述任何步骤,则需要创建自定义rasterize.js。

无论如何,你的POST似乎没有修改系统中的任何内容,它看起来像是一个搜索,所以我认为你可以为这个POST禁用csrf。