V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leonwong
V2EX  ›  程序员

网站安全性探讨(纯静态页的动态化尝试)

  •  
  •   leonwong · 2013-08-25 21:04:01 +08:00 · 7081 次点击
    这是一个创建于 4100 天前的主题,其中的信息可能已经有所发展或是发生改变。
    先来说说我的项目:

    项目基于jsp开发,采用struts2+mybatis+spring三大框架。

    由于事先做好了前端页面,是纯html,出于懒惰,暂且不想转化成jsp页面,所以用js来对其动态化尝试。

    尝试包括:

    1)表单提交:利用JQuery.ajax()提交表单到后台action,这里取代了form提交表单;
    2)读取用户个人数据:同样也是用JQuery.ajax()方法:提交空值>>通过cookie中sessionid保持session>>session中存在用户的ID>>服务器根据用户ID返回特定用户的数据


    困惑:

    现在业务功能可以基本实现,能够保证让服务器识别到是哪个用户,但是还没设置token,所以暂时没办法确保用户是在特定页面提交的参数,这样也就给CSRF攻击提供了机会,这点经网友指正我已经认识到。

    此外的问题就是:
    1)js配合纯静态html于长远看,是否有前途?html纯静态页配合js动态化只是我的一个尝试,如果不好我并不会坚持;
    2)为了防止CSRF攻击我还应该采取什么措施?
    3)除了CSRF我还应该注意什么?
    先谢谢各位!
    33 条回复    1970-01-01 08:00:00 +08:00
    leonwong
        1
    leonwong  
    OP
       2013-08-25 21:11:56 +08:00
    zzNucker
        2
    zzNucker  
       2013-08-25 21:28:10 +08:00   ❤️ 1
    坚持纯静态HTML是没有意义的
    既给程序员添加了复杂度 又不能给用户带来更好的体验

    纯静态的页面我不知道如何使用CSRF token,因为你根本没办法从server带出任何信息,也就是说你这个页面的任何元素都可以不用通过server的信息直接构造出来,因此你从页面提交的任何信息都无法进行甄别来源。。。
    leonwong
        4
    leonwong  
    OP
       2013-08-26 00:02:46 +08:00
    @kfll express框架我从来没接触过,不过这确实是一个新的解决思路,我可以看看学习一下express
    aaronzheng
        5
    aaronzheng  
       2013-08-26 00:03:15 +08:00
    纯静态的HTML,你怎么获取ID~ 你总不能够直接在页面那里放个ID吧。。。
    如果你的项目是纯粹的文章发布,评论部分交给另外的ifram做的话,还是可以行得通的。
    leonwong
        6
    leonwong  
    OP
       2013-08-26 00:10:06 +08:00
    @zzNucker 3楼貌似用了express框架来实现前端请求验证,最根本还是ajax,我猜想如果运用成熟的js框架,纯静态其实也不是不行,但是这个观点有待考证.

    的确坚持纯静态有点困难,也不适合我这个初学者.

    我开始有点理解你说的CSRF token难以实现的问题了,因为貌似js文件是不是可以轻易被构造然后也可以轻易更改其提交参数?问题就在于此,token如果能轻易被构造那么验证就无从谈起,你的意思是这样吧?
    leonwong
        7
    leonwong  
    OP
       2013-08-26 00:11:55 +08:00
    @aaronzheng 获取参数,比如用户id,可以通过ajax的回调方法给页面某个元素赋值,但是有点多此一举的感觉,因为动态页就轻易实现了,但是静态就是这么大费周章.
    aaronzheng
        8
    aaronzheng  
       2013-08-26 00:13:58 +08:00   ❤️ 1
    @leonwong 我不知道你做的网站涉不涉及安全问题,如果按照你这样说的话,我直接做一个伪post,你就信息返回给我了,放只爬虫就可以直接把你数据库拖走了。
    darcy
        9
    darcy  
       2013-08-26 00:34:06 +08:00 via iPhone   ❤️ 1
    token可以从ajax api的后台接口中吐 写到cookie里每次请求时带上;敏感数据不要要jsonp获取,仍使用POST方法获取
    undeadking
        10
    undeadking  
       2013-08-26 00:39:42 +08:00
    楼主还在坑里继续挖啊……防跨站不是在静态层面上能实现的东西,折腾js纯粹是自己和自己玩,别人看一下你的代码,分析出你post的动态页面地址就能进行攻击了
    Frannk
        11
    Frannk  
       2013-08-26 01:02:22 +08:00   ❤️ 1
    我的看法是:
    1. 我觉得纯HTML是很好的开发实践,让前端和后端完全分离,也便于API部署到不同的服务器,前后端的开发解耦,大家都很过瘾;
    2. 不知道你的app是什么类型的,如果用户之间数据完全隔离(比如支付宝,dropbox吧),几乎没有什么CSRF的危险
    3. 我在一个应用中直接禁止浏览器中url携带参数,每次进入app的时候,url直接变成app.xxx.com/,防止注入代码,但牺牲了app状态可以通过的url存储的能力,用户不能保存特别的状态到书签和分享(我觉得基本没有必要的特性)
    4. GET 请求一律做成没有副作用的,只能读数据,不能改变数据
    5. 做好参数携带javascript代码的防范,即便用户之间有共享的数据,也不会有风险
    6. 十分敏感的操作引入二次验证,比如我要执行post的ajax(转账),需要用户提供token(类似支付密码),让后端允许这个操作的,加大csrf的难度。

    总之我觉得不应该因为安全隐患放弃这么好的开发模式。请有经验的同学多给点这方面的经验吧。
    msg7086
        12
    msg7086  
       2013-08-26 02:02:25 +08:00   ❤️ 1
    全程ajax最大的问题就是SEO吧。如果不在意SEO的话全程ajax我看不出什么问题。

    防止跨站不是很大的问题吧,以前怎么做现在还是怎么做啊。

    token可以存在url里 (用路由来导出到静态文件),或者存在js的变量表里。

    在一定要验证页面访问次序的时候可以这么做。
    PrideChung
        13
    PrideChung  
       2013-08-26 02:08:56 +08:00   ❤️ 2
    不建议你这么搞,平白增加了HTTP连接次数,增加代码复杂度,对用户体验一点帮助都没有,还留下了安全隐患。
    msg7086
        14
    msg7086  
       2013-08-26 02:13:54 +08:00   ❤️ 1
    看到了你之前发的帖子,那我就照着实际问题和情况说一下。

    token是用来防止跨域一键请求的,也就是说要验证提交来源。
    我就以v2ex现在的跨域作为例子。
    <input type="hidden" value="abcde" name="once" />
    表单里有这么个东西。这东西是怎么生成的呢?
    1. 用户请求了本页面
    2. 生成一个唯一字符串$once,写入用户session变量里
    3. 生成本页面,把$once写入表单区域
    4. 用户提交了回复
    5. 将session里的$once与提交的once做对比,相同就pass,不同就重来

    那么在ajax的情况下要怎么做呢?
    1. 用户请求了静态页面
    2. 静态页面向服务器索要唯一字符串
    3. 服务器生成唯一字符串$once,写入用户session变量里,并返回给客户端
    4. 客户端用jquery把$once写入表单区域
    5. goto #1.4
    leonwong
        15
    leonwong  
    OP
       2013-08-26 10:16:07 +08:00
    @aaronzheng 这也是我应该考虑的一点,网站安全至少要保证不被爬虫爬到,因为里边是用户的个人信息,有隐私安全的存在,如果不希望被爬虫拖走,您有什么好建议?
    leonwong
        16
    leonwong  
    OP
       2013-08-26 10:17:57 +08:00
    @darcy 通常token应该都是存在session里,存入cookie会不会有不妥?
    leonwong
        17
    leonwong  
    OP
       2013-08-26 10:25:29 +08:00
    @undeadking 我没有说一定要坚持啦,只是动态页面如果实现的话也是会暴露action提交的url信息,这样其实和纯静态页面配合js来说没什么太大区别,其实最关键的是我还想知道除了token还有没有别的防止因为暴露url而遭受攻击的办法?静态页动态化只是我的尝试,如果论证各方面都不足的话,我是不会坚持的
    blahnice
        18
    blahnice  
       2013-08-26 10:36:24 +08:00   ❤️ 1
    struts2,安全性,呵呵
    leonwong
        19
    leonwong  
    OP
       2013-08-26 10:43:37 +08:00
    @Frannk
    谢谢你对这种模式的支持,我的安全需求是:
    1、要求用户资料相互隔离,不能被爬虫爬到关键隐私信息;
    2、能防止CSRF攻击。
    如果用https的话,可能成本有点高。大概和微信公众平台管理页面,或者孔明社交管理平台差不多,我也参考过他们的源码,说实话才疏学浅看不明白,也可能是我仅学了jsp,其他平台语言尚未接触,所以看不懂。
    另外,您说的第3点和第4点如何实现?(平台是jsp+tomcat服务器)
    leonwong
        20
    leonwong  
    OP
       2013-08-26 10:47:48 +08:00
    @PrideChung 的确,我同意你这个看法,但是性能上暂时还在我的可接受范围内,但是可能后来复杂度一增加可能就不如意了,安全隐患其实连我自己都觉得这样很不靠谱,但是我之所以提出此类问题就是想知道不靠谱的地方在哪,一一例举出来,这样才可以找到靠谱的方式去解决,就好像玩网络攻防实验课一样,我觉得这样是一个不错的学习过程,谢谢你能参与进来讨论
    leonwong
        21
    leonwong  
    OP
       2013-08-26 10:54:59 +08:00
    @msg7086 感谢给出一个非常具体的实施方法,你的描述过程非常符合我的口味啊,我也大概知道纯静态的token该怎么实现了,我还想知道,如何防止因为暴露URL带来的隐患和恶性攻击?因为ajax中会暴露我后台程序的URL信息
    darcy
        22
    darcy  
       2013-08-26 11:01:48 +08:00 via iPhone
    @leonwong 我这里说的token是指防止csrf的token
    你这个模式存在的安全问题,在由后端生成页面也会遇到的
    敏感信息也用post请求获取 防止爬虫
    大致流程如 @msg7086 在14楼所说 你提的前端纯静态页面的方案我们在实际生产中已经用了好几年
    zzNucker
        23
    zzNucker  
       2013-08-26 11:11:58 +08:00
    @leonwong express不是纯静态 是可以用模板的 这种也是比较好的实践

    @Frannk lz说的纯静态是服务器不能往页面写入任何东西 如果我没理解错的话。 前后端没必要完全分离, 适当的解耦可以用模板实现 没什么问题
    leonwong
        24
    leonwong  
    OP
       2013-08-26 11:18:11 +08:00
    @darcy 用了好几年也就证明这个模式可行对吧?我的确感觉出这种方式所遇到的安全问题,动态页也是面临的,所以我才会去尝试
    zzNucker
        25
    zzNucker  
       2013-08-26 11:18:12 +08:00
    @msg7086 嗯这个方法应该是可行的 实际上还是说明一定要能够从server获取到特殊信息来避免构造。
    darcy
        26
    darcy  
       2013-08-26 11:39:00 +08:00
    @leonwong
    嗯,大部分富ajax页面初次载入的内容是server生成,接着都是ajax载入的;而这种做法只是把开始时server生成的初始这一步省略了,改用ajax获取而已。
    leonwong
        27
    leonwong  
    OP
       2013-08-26 12:01:23 +08:00
    @darcy 恩恩。我明白了很多了,具体细节交给我自己捉摸吧,谢谢
    momofiona
        28
    momofiona  
       2013-08-26 13:14:48 +08:00
    从资源的角度来看,静态动态是没有区别的,反正都跑到了客户端,你觉得怎么方便就这么搞。安全性上,数据库写操作只允许使用post
    undeadking
        29
    undeadking  
       2013-08-26 14:54:19 +08:00   ❤️ 1
    楼主是栽在坑里出不来了…防CSRF必须在后端来实现,用前端js来偷懒本来就是个错误方向,你大概是只听说过CSRF这个名词而没搞懂它是怎么回事吧.直接用jsp来实现带token的from,比分离前端js和后端jsp要简单得多,没意识到这是舍近求远么?

    防止因为暴露url而遭受攻击的办法当然还有别的,微信公众平台的消息接口指南就有.把全部参数拼接到一块加上一个token值进行hash运算,最终能得到个signature值,很多移动应用的API都有用到这种验证机制.不过在js上还是算了,代码逆向分析的成本太低
    yushiro
        30
    yushiro  
       2013-08-26 15:22:56 +08:00
    @undeadking “直接用jsp来实现带token的from”, 对这个实现比较好奇, jsp如何实现? 靠的是session? 还是发送token String到客户端的HTML?
    msg7086
        31
    msg7086  
       2013-08-26 15:35:32 +08:00   ❤️ 1
    @leonwong
    后台暴露的问题,
    你的程序不过是从「只有java」变成了「html+java」。如果你的后台能够被攻击,那么不管是用动态页面还是用API,都会被干的。自己在java端做好安全措施才是真的。

    https的问题,
    https有什么代价?一张证书20块钱搞定,就算是用泛域名证书也就70。
    leonwong
        32
    leonwong  
    OP
       2013-08-26 19:37:16 +08:00
    @undeadking 是我太依赖js了,的确是舍近求远,我现在采取的措施是,jsp和纯静态混合使用,jsp效率高的就用jsp,html适合的就用html,不坚持用js配合html死做下去
    leonwong
        33
    leonwong  
    OP
       2013-08-26 19:41:12 +08:00
    @msg7086 https搭建复杂度可能对我而言比较高,而且如果参考孔明社交平台后台管理的话,也是可以不用https的,你说的我会好好斟酌,谢谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2778 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 12:41 · PVG 20:41 · LAX 04:41 · JFK 07:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.