好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

从get和post的区别说缓冲区溢出 - 网站安全 - 自学

网页表单(form)提交时可选择2种提交方式:get和post。我们大都知道提交表单数据时应该使用post,也知道get方式不安全。是什么造成了get和post的区别,本文将从http协议层面分析,来说说get和post境遇不同的根本原因。

 

先来看看一个简单的hello woeld页面的http消息:

浏览器请求]http:// HdhCmsTest2cto测试数据 /test/hello.html]发送的http协议报文:

Accept-Encoding: gzip,deflate

Connection: keep-alive

 

捕获http报文需要使用工具程序(这里我使用自己编写的TCP代理程序来截获http消息)。请求协议报文第1行[GET]表明了提交方式,[/test/hello.html]表示请求的文家及路径,[HTTP/1.1]表示使用的http协议版本。第2行表示请求的服务器IP和端口,注意[80]是默认添加上的端口号。后面几行描述了客户端系统、浏览器的一些信息。

WEB服务器应答报文:

HTTP/1.1 200 OK

Content-Type: text/html;charset=GBK

Date: Wed, 26 Dec 2007 18:00:59 GMT

 

<!– HTML网页文件实例  –>

<html>

    <head>

        <title>你好,世界!</title>

    </head>

    <body>

        <h3>世界你好!</h3>

    </body>

</html>

[200 OK]表示服务应答编码,表示成功,常见的还有[404]、[500]等。[Content-Length: 145]表示应答网页的长度,[Date: Wed, 26 Dec 2007 18:00:59 GMT]是应答时间,在这之后空一行,然后是网页正文。

对于http通讯,总是像上面这样客户端(浏览器)发出请求,服务端(web服务器)给予应答,表单提交也同样如此,下面分析一个简单的表单。

表单提交

1. get方式提交:

<form name="form1" method="get" action="result.jsp">

姓名:<input type="text" name="userName" value=""><br>

密码:<input type="password" name="password" value=""><br>

性别:<input type="radio" name="sex" value="m">男 <input type="radio" name="sex" value="f">女<br>

爱好:<input type="checkbox" name="interest" value="dance">跳舞

         <input type="checkbox" name="interest" value="sing">唱歌

         <input type="checkbox" name="interest" value="basketball">篮球<br>

<br>    <input type="submit" name="submit" value="提交">

</form>

注意在<form>标签中,method=]get]。

http请求协议报文:

Accept-Encoding: gzip,deflate

Connection: keep-alive

 

get方式表单的提交数据显示在请求http协议的第一行,和请求地址用[?]间隔(这一行同样会显示在浏览器地址栏中)。从[ userName=lisi&password=1111&sex=f&interest=dance&interest=sing&submit=%CC%E1%BD%BB]可以分析出表单提交的数据:

■ userName=lisi 姓名文本框输入的是[lisi]

■ password=1111 密码文本框输入的是[111]

■ sex=f 性别单选钮选择的是[女]

■ interest=dance&interest=sing 爱好多选框选择了2个:跳舞、唱歌

■ submit=%CC%E1%BD%BB 点击[提交]按钮进行提交(submit按钮也是表单元素,同样会提交给服务端),[%CC%E1%BD%BB]是按钮的value属性]提交]两个汉字的gb2312的16位编码。

下面看看post方式和get有什么不同。

2. post方式提交:

将<form>中的method=]get]改为method=]post],提交同样的数据,http请求协议报文如下:

Accept-Encoding: gzip,deflate

Connection: keep-alive

Content-Type: application/x-www-form-urlencoded

 

userName=lisi&password=1111&sex=f&interest=dance&interest=sing&submit=%CC%E1%BD%BB

 

区别

对比一下get和post方式的请求http协议报文,注意以下几点:

■ 协议第一行起始,get方式声明为[GET],post方式声明为[POST]。

■ 提交数据[userName=lisi&password=1111&sex=f&interest=dance&interest=sing&submit=%CC%E1%BD%BB],对于get方式在第一行,对于post方式在最后一行,两种方式对表单数据的编码完全一致。

■ post方式多了3行: Content-Type: application/x-www-form-urlencoded,Content-Length: 82,和数据前的空行。

仅从以上几点,很难想象出get和post究竟有什么实质性的区别,为什么在使用中差别如此之大,真是以讹传讹吗?就像[菠菜含铁量高]被误传了十来年,直到有人证明当年计算铁含量时标错了小数点。

实质差别只有一点:[Content-Length: 82],在post中表示了提交数据[userName=lisi&password=1111&sex=f&interest=dance&interest=sing&submit=%CC%E1%BD%BB]的长度,而get中没有。

正是此导致服务端在接收get提交的数据时,极易出现一个安全漏洞:缓冲区溢出。

缓冲区溢出

■ 名词解释 【缓冲区溢出】: 通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。

服务端程序在接收客户端表单提交的数据时,需要先将数据存储到一个内存空间,然后做解析等后续工作,这个内存空间一般称之为接收缓冲区。对于post数据因为有Content-Length标记,服务端可以按标记的长度创建一个等于或稍大于提交数据的缓冲区;对于get,因为事先不知道提交的数据有多少,需要估计缓冲区长度,如果缓冲区很大而接收数据很小会造成内存浪费,而如果缓冲区小于接收数据,就可能造成缓冲区溢出。

缓冲区溢出

[聪明的] 黑客 ,会在溢出部分放置特殊的代码来攻陷你的服务器。

现代的WWW服务器并不是如此弱不禁风,但完全、有效的解决缓冲区溢出 漏洞 却很难,操作 系统 、C语言程序都提供了滋生此问题的温床,至今还有相当部分的WWW服务软件有此漏洞,可以搜索一下[get 缓冲区溢出]看看。

这也就是不建议使用get方式提交表单数据的原因所在。

深入思考去学习

随便翻看http入门书籍,都有get和post的区别的描述,但往往只说其然,不说其所以然,而年轻的程序员往往记忆力很好,却忽略了更重要的[思考]。

本篇文章的另一个目的是关于学习方法的: 要习惯于深入思考,要怀着疑问、探索、证明的态度去学习,哪怕是被广泛认为是[公理]的观点

查看更多关于从get和post的区别说缓冲区溢出 - 网站安全 - 自学的详细内容...

  阅读:43次