【问题标题】:How to intercept uploading of email attachments with a Firefox XUL extension in outlook.com web mail如何在 Outlook.com 网络邮件中拦截带有 Firefox XUL 扩展的电子邮件附件的上传
【发布时间】:2013-10-29 16:54:49
【问题描述】:

我有一个 XUL 扩展,它使用本地 Windows DLL 和 js-ctypes 来加密本地文件系统中的文件。我已经测试了它的菜单驱动版本,它似乎工作正常。

现在我想做以下事情:在创建带有附件的新电子邮件时,能够“捕获”附件文件并在上传到撰写的电子邮件之前对其进行处理(意思是:对其进行加密)。我想以一种透明的方式来做,这样用户就不必通过菜单驱动的过程,除了提供加密密码。

我想在基于 web 的 Outlook.com 电子邮件(不是 Office 版本)中执行此操作。

我知道这是一个很长的目标,但有人知道从哪里开始寻找吗?过去有人做过类似的事情吗?

提前致谢!

【问题讨论】:

    标签: javascript dom encryption outlook xul


    【解决方案1】:

    一个好的起点是一个已经做了你想做的事情的插件(以通用方式):

    https://addons.mozilla.org/en-US/firefox/addon/tamper-data/

    在下载页面上显示Use tamperdata to view and modify HTTP/HTTPS headers and post parameters。您有兴趣更改“发布参数”,因此这是一个很好的起点。


    但如果你只是想自己实现这个......

    我已经乱序回答了这个问题,以便在您可能构建开发解决方案的方式上取得进展。

    在最终扩展中,您需要:

    1. 拦截请求
    2. 定位正确的请求
    3. 获取对 POST 请求正文的访问权限
    4. 解析POST请求体的表单数据(获取真正的二进制文件数据)
    5. 执行加密步骤
    6. 重新编码二进制文件数据,重新组装表单数据,修改POST请求头
    7. 替换 POST 请求中的现有内容。

    拦截请求并替换现有的 POST 内容

    基本原理是您需要实现 nsIObserver 传递 nsIHTTPChannel 作为观察的“主题”。您希望观察的“通知”称为http-on-modify-request。

    http-on-modify-request 的文档中有拦截 GET 请求的简单示例(1、2),但拦截 POST 请求更复杂。

    获取 POST 请求正文:

    有一个mozillazine forum thread 处理这个确切的主题。 Kamelot9 在该线程中的第二个帖子详细说明了如何(1) 获取帖子正文:

    var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
    var uploadChannel = httpChannel.QueryInterface(Ci.nsIUploadChannel);
    var uploadChannelStream = uploadChannel.uploadStream;
    uploadChannelStream
        .QueryInterface(Ci.nsISeekableStream)
        .seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
    var stream = Cc["@mozilla.org/binaryinputstream;1"]
        .createInstance(Ci.nsIBinaryInputStream);
    stream.setInputStream(uploadChannelStream);
    var postBytes = stream.readByteArray(stream.available());
    var poststr = String.fromCharCode.apply(null, postBytes);
    

    这里的aSubject 是http-on-modify-request 通知的参数。然后您可以修改poststr。根据服务器的不同,您可能还需要修改 Content-length 标头(或者您的帖子可能会被截断)。

    替换 POST 请求内容:

    获得修改后的 POST 正文后,您需要 (2) 将 uploadChannel 中 inputStream 的现有内容替换为您自己的内容:

    var inputStream = Cc["@mozilla.org/io/string-input-stream;1"]
        .createInstance(Ci.nsIStringInputStream);
    inputStream.setData(poststr, poststr.length);
    uploadChannel.setUploadStream(
        inputStream, 
        "application/x-www-form-urlencoded", 
        -1);
    // do this last - setUploadStream resets requestMethod to PUT
    httpChannel.requestMethod = "POST";
    

    上面的Cc 和Ci 分别是Components.classes 和Components.interfaces 的简写。这些速记变量可能已经设置好了,也可以自己定义。

    解析表单数据:

    我认为通常对于文件上传,Content-type: 将是multipart/form-data。

    要深入了解您感兴趣的特定“附件”,您需要:

    1. 解析 mime 信封以获取文件附件
    2. 查找文件附件
    3. 删除已使用的任何文本编码(例如:BASE64)

    在 POST 标头中,您会得到如下内容:

    Content-Type: multipart/form-data; boundary=JGUOAeGT3Fjgjcdk6s35F2mPVVyTdzgR
    

    其中“JGUOAeGT3Fjgjcdk6s35F2mPVVyTdzgR”是 MIME 边界。在 POST 的正文中,开始内容的格式如下:

    --[boundary]
    CONTENT-PART #1
    --[boundary]
    CONTENT-PART #2
    --[boundary]
    

    上面的每个CONTENT-PART 都会有一些HTTP 标头、一个空行,然后是那个特定CONTENT-PART 的正文。

    另一个stackoverflow question的例子:

    Content-Disposition: form-data; name="updates"; filename="update1353963418000.json"
    Content-Type: application/json; charset=UTF-8
    Content-Transfer-Encoding: binary
    
    {"collectionType":"activities","date":"2012-11-26","ownerId":"qw12er23","ownerType":"user","subscriptionId":"112233-activities"}]
    

    在这种情况下,Content-Transfer-Encoding 是二进制(原始、编码)UTF8,因此您无需再做任何工作即可读取CONTENT-PART 正文中的 JSON。

    在您的情况下,浏览器将发送一个二进制文件,因此它可能已将 Content-Transfer-Encoding 设置为 base64,这意味着您需要将 CONTENT-PART 的正文进行 Base64 解码以获取您真正的二进制文件。如果base64data 包含编码内容,那么这将为您提供原始二进制数据:

    var rawData = atob(base64data);
    

    此时你可以对rawData进行任何你想要的加密。

    请记住,您必须在加密后重新编码二进制数据(使用btoa),然后您需要重新组装多部分信封,然后再重新构建 POST 请求正文。 (不要忘记获取最终请求正文的.length,以便您可以替换请求标头中的Content-length。)。

    定位请求:

    这是修改 POST 请求的基本机制。但是您仍然必须挑选出您的特定的 POST 请求(检查观察者通知中的 POST 请求 URL),以便您允许其他 POST 请求正常进行而不调用您的修改代码。 p>

    【讨论】:

      猜你喜欢
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-31
      相关资源
      最近更新 更多