即使用了 https 也不要通过 query strings 传敏感数据

2017/10/16 · 基础技术 ·
HTTPS

本文由 伯乐在线 –
xiaoheike
翻译,艾凌风
校稿。未经许可,禁止转载!
英文出处:HttpWatch。欢迎加入翻译组。

服务器端的 log 将明文记下完整 url;浏览器上的访问历史也会明文记下完整
url;Referrer headers 里也忠实记下完整 url,然后在别人家的 Google
Analytics 上显示。

我们经常听到的一个常见问题是:“URL
中的参数是否可以安全地传递到安全网站?”这个问题常常出现在客户看了
HttpWatch 捕获的 HTTPS 请求后,想知道还有谁可以看到这些数据。

 

例如,假设在一个查询中,使用如下安全的 URL 传递密码字符串:

HttpWatch 能够显示安全请求的内容,因为它与浏览器集成,因此它能够在
HTTPS 请求的 SSL
连接对数据加密之前查看数据。欧博国际平台 1

如果你使用网络嗅探器查看,例如
Network Monitor,对于同一个请求,你只能够查阅加密之后的数据。在数据包跟踪中没有可见的网址,标题或内容:

欧博国际平台 2

您可以信任 HTTPS 请求是安全的,只要:

  • 未忽略任何SSL证书警告
  • Web 服务器用于启动 SSL 连接的私钥在 Web 服务器本身之外不可用。

因此,在网络层面,URL 参数是安全的,但是还有一些其他基于 URL
泄漏数据的方法:

  1. URL 存储在 Web 服务器日志中–通常每个请求的完整 URL
    都被存放在服务器日志中。这意味着 URL
    中的任何敏感数据(例如密码)会以明文形式保存在服务器上。以下是使用查询字符串通过
    HTTPS 发送密码时存储在 httpwatch.com 服务器日志中的条目:
    **2009-02-20 10:18:27 W3SVC4326 WWW 208.101.31.210 GET
    /Default.htm password=mypassword 443 …
    通常认为即使是在服务器上,存储明文密码从来都不是好想法
    2.URLs are stored in the browser history – browsers save URL
    parameters in their history even if the secure pages themselves are
    not cached. Here’s the IE history displaying the URL parameter:
  2. URL 存储在浏览器历史记录中–即使安全网页本身未缓存,浏览器也会将
    URL 参数保存在其历史记录中。以下是 IE 的历史记录,显示了 URL
    的请求参数:欧博国际平台 3

如果用户创建书签,查询字符串参数也将被存储。

  1. URLReferrer 请求头中被传递–如果一个安全网页使用资源,例如
    javascript,图片或者分析服务,URL 将通过 Referrer
    请求头传递到每一个嵌入对象。有时,查询字符串参数可能被传递并存放在第三方站点。在
    HttpWatch 中,你可以看到我们的密码字符串正被发送到
    Google Analytics欧博国际平台 4

结论

解决这个问题需要两步:

  • 只有在绝对必要的情况下传递敏感数据。一旦用户被认证,最好使用具有有限生命周期的会话
    ID 来标识它们。

使用会话层级的 cookies 传递信息的优点是:

  • 它们不会存储在浏览器历史记录中或磁盘上
  • 它们通常不存储在服务器日志中
  • 它们不会传递到嵌入式资源,例如图片或 JavaScript
  • 它们仅适用于请求它们的域和路径

以下是我们的在线商店中,用于识别用户的 ASP.NET 会话 cookie 示例:

欧博国际平台 5

请注意,cookie 被限制在域
store.httpwatch.com,并且在浏览器会话结束时过期(即不会存储到磁盘)。

你当然可以通过 HTTPS
传递查询字符串,但是不要在可能出现安全问题的场景下使用。例如,你可以安全的使用它们显示部分数字或者类型,像
accountview 或者
printpage,但是不要使用它们传递密码,信用卡号码或者其他不应该公开的信息。

1 赞 收藏
评论

Get传输的数据有大小限制,因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了,不同的浏览器对URL的长度的限制是不同的。

<a name=”t3″></a><a target=”_blank” name=”t3″ style=”color:rgb(12,137,207)”></a>部分API详述

由于篇幅较长,可以选择感兴趣的部分阅读
存储机制
File
API
Web
Worker
history对象
2D绘图(canvas和svg)
H5的兼容性

Get请求适用于安全的交互行为就是那些你可以反复发起请求而不会带来副作用的请求。**Post请求适用于不安全的互交行为*意思是每一个请求都会导致服务器端发生某种变化,而重复请求可能会带来问题。*

关于作者:xiaoheike

欧博国际平台 6

简介还没来得及写 :)
个人主页 ·
我的文章 ·
10 ·
     

欧博国际平台 7

string
name=context.Request.Form[“pwd”];

<a target=”_blank” name=”t10″ style=”color:rgb(12,137,207)”></a>读取部分内容

File对象支持一个slice()方法以实现读取文件的一部分而不是全部内容,这个方法在FireFox中的实现叫mozSlice(),在chrome中的实现是webkitSlice(),Safiri的5.1及之前的版本不支持这个方法。Slice()方法接收两个参数:起始字节及要读取的字节数。这个方法返回一个Blob实例,Blob是File类型的父类型。下面是一个通用的函数,可以在不同实践中使用slice()方法:

function blobSlice(blob,startByte,length){
    if(blob.slice){
        return blob.slice(startByte,length);
    } else if(blob.webkitSlice){
        return blob.webkitSlice(startByte,length);
    } else if(blob.webkitSlice){
        return blob.webkitSlice(startByte,length);
    } else {
     return null;
    }
}

blob类型有一个size属性和一个type属性,而且它也支持slice()方法,以便进一步切割数据。通过FileReader也可以从Blob中读取数据。下面这个例子只读取文件的32B内容

var filesList = document.getElementById('files-list');
EventUtil.addHandler(filesList, "change", function(event){
         var info = "",
              output = document.getElementById("output"),
              progress = document.getElementById("progress"),
              files = EventUtil.getTarget(event).files,
              type = "default",
              reader = new FileReader();
              blob = blobSlice(files[0],0,32);

          if (blob){
              reader.readAsText(blob);
              reader.onerror = function(){
               outpit.innerHTML = 'could not read file,error code is' + reader.error.code;
           }
           reader.onload = function(){
            output.innerHTML = reader.result;
        };
     } else {
         alert('your browser does not support slice()');

          }

          reader.onerror = function(){
              output.innerHTML = "Could not read file, error code is " + reader.error.code;
          };

只读取文件的一部分可以节省时间,非常适合只关注数据中某个特定部分(如请求头部)的情况

Get请求的参数会跟在url后进行传递,请求的数据会附在URL之后,以?分割URL和传输数据,参数之间以&相连,%XX中的XX为该符号以16进制表示的ASCII,如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密。

Get是获取信息,而不是修改信息,类似数据库查询功能一样,数据不会被修改;

<a target=”_blank” name=”t18″ style=”color:rgb(12,137,207)”></a>history在h5中新增的属性和方法

h5中的history对象新增了两个新方法:history.pushState()和history.replaeState();
两种方法都允许我们添加和更新历史记录,它们的工作原理相同并且可以添加数量相同的参数。但是pushState()是在history栈中添加一个新的条目,replaceState()是替换当前的记录值。除了方法之外,还有popstate
事件
pushState(data,title[,url])和replaceState(data,title[,url])参数一样,参数说明如下:

  • data:一个表示状态的对象,json格式数据
  • title:一个string格式的标题(大多数浏览器不支持或忽略这个参数,最好用null代替)
  • url:一个url(用于替换当前URL)

当浏览会话记录的时候,不管点击前进或者后退按钮,还是使用history.go和history.back方法,popstate事件都会被触发。当事件发生时,浏览器会从history中取出URL和对应的state对象替换当前的URL和history.state。通过event.state也可以获取history.state
需要说明的是pushState只是将当前页面保存到history的历史记录中(并作为最近的一个记录),并且将当前浏览器的地址栏改为参数url指定的值,但并不会加载它。这点与普通的通过链接打开或浏览器地址输入url完全不一样。所以如果想在url改变的时候需要监听popstate事件。

利用history可以弥补ajax无法回退的缺陷。如下方法是模拟ajax操作的实现方法。

<input type="button" value="加1" onclick="add()" />
   <div id="info" style="border:red 1px solid;width:200px;padding:10px;">0</div>
<script>
    var info = document.getElementById('info');
    var i = 1;
    function add() {
        var data = {
            param : i,
            func : func
        };
        info.innerHTML = i;
        document.title = i;
        History.push(data);
        i++;
    }

    function func(i) {
        info.innerHTML = i;
        document.title = i;
    }

    History = function() {  
            var 
               list = [],
               index = 1,

               func, scope;

            function push(data) {
                if(typeof data !== 'object') return;

                if(typeof data.param == undefined || typeof data.func !== 'function') return;

                func = data.func;
                scope = data.scope;

                history.pushState({param: data.param}, index, '#' + index);
                index++;
            }

            window.onpopstate = function(e) {
                if(e.state) {
                    var state = e.state,
                        param = state.param;
                    if(param) {
                        func.call(scope, param);
                    }
                }
                else{
                    if(func){
                        func.call(scope, 0);
                    }

                }

            }

            return {
                push : push
            };
        }();
</script>

Http方法:Get请求与Post请求的区别

POST表示可能修改变服务器上的资源的请求,在服务器端,用Post方式提交的数据只能用Request.Form来获取.

<a name=”t7″></a><a target=”_blank” name=”t17″ style=”color:rgb(12,137,207)”></a>history对象

history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。
使用Go欧博国际平台,()方法可以在用户的历史记录中任意跳转,可以向后也可以向前。这个方法接受一个参数,表示向后或向前跳转的页面数的一个整数值。负数表示向后跳转(类似于单击浏览器的‘后退’按钮),正数表示向前跳转(类似于单击浏览器的“前进”按钮)

history.go(-1);//后退一页
history.go(1);//前进一页
history.go(2);//前进两页

也可以给go()方法传递一个字符串参数,此时浏览器会跳转到历史记录中包含该字符串的第一个位置–可能后退,也可能前进,具体看那个位置最近。如果历史记录中不包含该字符串,那么这个方法什么也不做

history.go('wrox.com');//跳到最近的wrox.com页面

另外,还可以使用两个简写方法back()和forward()来代替go()。这两个方法都可以模仿浏览器的‘后退’和‘前进’按钮。

history.back();//后退一页
history.forward();//前进一页

history对象还有一个length属性,保存着历史记录的数量。这个数量包括所有的历史记录,即所有向后和向前的记录。

Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求。

Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求;

<a target=”_blank” name=”t20″ style=”color:rgb(12,137,207)”></a>SVG

SVG 是一种使用 XML 描述 2D 图形的语言。
SVG 基于 XML,这意味着 SVG DOM
中的每个元素都是可用的。您可以为某个元素附加 JavaScript 事件处理器。
在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG
对象的属性发生变化,那么浏览器能够自动重现图形。

Get传输的数据有大小限制,因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了,不同的浏览器对URL的长度的限制是不同的。

Post请求则作为http消息的实际内容发送给web服务器,数据放置在HTML
Header内提交,Post没有限制提交的数据。Post比Get安全,当数据是中文或者不敏感的数据,则用get,因为使用get,参数会显示在地址,对于敏感数据和不是中文字符的数据,则用post;

<a name=”t9″></a><a target=”_blank” name=”t23″ style=”color:rgb(12,137,207)”></a>h5的兼容性问题

IE6/IE7/IE8支持通过document.createElement方法产生的标签,可以利用这一特性让这些浏览器支持HTML5新标签。但是浏览器支持新标签后,还需要添加标签默认的样式。

POST表示可能修改变服务器上的资源的请求,在服务器端,用Post方式提交的数据只能用Request.Form来获取

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注