谈一谈 Airpub.io 又拍云 bucket 被篡改的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
turing
V2EX    程序员

谈一谈 Airpub.io 又拍云 bucket 被篡改的问题

  •  
  •   turing
    guo-yu 2014-09-25 15:58:48 +08:00 4625 次点击
    这是一个创建于 4086 天前的主题,其中的信息可能已经有所发展或是发生改变。
    中午收到同事微信,说 Airpub.io 首页几个图片被改写了,应该是前端暴露了又拍云表单上传密钥导致的。


    我躺在床上琢磨这个事情,心想还是有闲的蛋疼的程序员做了。所以大概谈谈为什么 Airpub 要这么设计,以及如何规避这种事情的发生:

    1. 为何如此设计?

    在刚开始写 Airpub 时,我们考虑要为 markdown 编辑器构建一种非常好的图片上传用户体验,同时又不需要用户自建后端服务,或依赖本地工作流。这种方式的工具其实本身面临着很大的安全风险,如果不暴露又拍云的表单密钥,就意味着图片上传的签名需要手动依赖工作流进行构造,也违背了这工具所设计的初衷。

    2. 图片如何被复写?

    Airpub 0.2.x 所依赖的 upyun 组件使用的文件最后上传路径是文件名,因此这个文件名很容易使用已经暴露的密钥重新上传导致覆盖。

    在 Airpub 0.3.x 的版本中采用新版 upyun 模块,使用文件的 md5 作为最终上传路径,因此也就没那么容易被覆盖。但还是可以通过复制此文件的 md5 的方式,写死上传最终文件地址,上传新的图片覆盖掉此图片。也就是说,一旦暴露了表单密钥,任何文件都有可能会被覆盖。

    3. 如何避免这种情况发生?

    我们考虑了两种方式:

    - Airpub 提供一个工作流工具,此工具将提供一个命令行界面,根据用户提供的表单密钥一次性生成签名,然后将此签名暴露给前端组件。
    - 在非编辑的情况下,经常性地在又拍云后台修改表单密钥,确保此密钥及时更新,不被泄露。在编辑文章时,临时将正确的密钥进行替换。

    另外, Airpub 已将编辑器拆分出核心代码,另起项目 EditorNinja,拆分后的项目最新稳定版本已发布 v0.3.2。今后,编辑器相关的功能,都会在 EditorNinja 项目进行维护。我们欢迎大家给 Airpub 挑错,但更欢迎大家以提 issue 的方式告诉我们问题在哪儿,让这个项目越来越完善。

    欢迎 Star & fork:
    https://github.com/duoshuo/airpub

    EditorNinja,可便捷拓展,支持实时代码高亮的 markdown 编辑器:
    https://github.com/airpub/ninja
    11 条回复    2014-09-29 12:08:58 +08:00
    chemzqm
        1
    chemzqm  
       2014-09-25 16:28:25 +08:00
    让用户把 secret 放到前端感觉挺不负责任的
    loading
        2
    loading  
       2014-09-25 16:54:42 +08:00   3
    前端提供AES加密后的密文,提示输入密码,在解密存到本地cookie,在自己电脑上其实也就输一次!

    在线提供一个工具对API密钥进行AES加密,当然这样改密码比较麻烦,但相对安全很多!
    easychen
        3
    easychen  
       2014-09-25 17:40:44 +08:00   1
    我觉得把key完全放到前端还是太危险了,要么就提供一个集中式的API中心,通过domain来分配内容,第一个设置密码的人获得管理权( cvbox.sinaapp.com就这么做的 );要么就提供一个服务器端docker image,pull就启用。

    顺便,我很看好Airpub这类前后端分离的书写工具。可以把云端接口定义一个简洁的规范,然后由社区来贡献各个语言的实现版本。

    Ghost虽然好用,但后端是Node,服务器上维护起来还是不方便,难免变成只能在Node社群流行的东西。而如果Ghost后端有PHP实现,我想就不同了。
    willwen
        4
    willwen  
       2014-09-25 18:39:49 +08:00 via iPhone
    @easychen 道理也是一的,即使成了PHP照只能是PHP社玩的,言不是好事情,更何ghost也提供如wordpress.conm的服。

    (好吧,我是Node.js粉,拍片黑
    easychen
        5
    easychen  
       2014-09-25 19:55:05 +08:00
    @willwen 不是换成PHP。是PHP,Node,Java,Go全有。谁想用谁写就是。写个API很简单。
    willwen
        6
    willwen  
       2014-09-25 19:58:23 +08:00 via iPhone
    @easychen 你是想,一套前端,一套,多後端吧。

    思路我在5年前已做了
    easychen
        7
    easychen  
       2014-09-25 20:00:37 +08:00
    @willwen 5年前浏览器ajax还不支持cross domain呢。
    willwen
        8
    willwen  
       2014-09-25 20:03:20 +08:00 via iPhone
    @easychen 不是不支持,只是新技而已
    easychen
        9
    easychen  
       2014-09-25 20:21:46 +08:00
    @willwen 你自己的浏览器支持有什么用,得访客的浏览器支持。

    而且吧,你做过没做成,和别人做不成没什么逻辑关系…

    后端API独立,和古代那种一个程序有N个版本是不同的,最大的区别就是后端API独立可以共享模板市场,从而可以构建一个跨语言的生态出来。

    聪明人多,我就不细说了 :)
    willwen
        10
    willwen  
       2014-09-25 20:26:16 +08:00 via iPhone
    @easychen 其思路是好的,我做成是因精力有限了,要做成一套完善的,先得有一套完善的作基。
    loading
        11
    loading  
       2014-09-29 12:08:58 +08:00
    突然想起来,其实我上面说的前端加AES也挡不住暴力破解的,必须有认证服务器来防爆破!
    自己那太天真了!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2397 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 81ms UTC 15:53 PVG 23:53 LAX 07:53 JFK 10:53
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86