﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-金家寶-随笔分类-网络转载</title><link>http://www.blogjava.net/jiabao/category/31721.html</link><description>機會只會給垂青有准備的人，運氣不是每個人都有的.</description><language>zh-cn</language><lastBuildDate>Fri, 30 May 2008 01:25:27 GMT</lastBuildDate><pubDate>Fri, 30 May 2008 01:25:27 GMT</pubDate><ttl>60</ttl><item><title>WEB交互界面易用性设计和验收的指导性原则</title><link>http://www.blogjava.net/jiabao/archive/2008/05/29/203948.html</link><dc:creator>金家寶</dc:creator><author>金家寶</author><pubDate>Thu, 29 May 2008 14:35:00 GMT</pubDate><guid>http://www.blogjava.net/jiabao/archive/2008/05/29/203948.html</guid><wfw:comment>http://www.blogjava.net/jiabao/comments/203948.html</wfw:comment><comments>http://www.blogjava.net/jiabao/archive/2008/05/29/203948.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiabao/comments/commentRss/203948.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiabao/services/trackbacks/203948.html</trackback:ping><description><![CDATA[
		<p>随着企业intranet和国际internet的迅速发展，越来越多的工作流程，商务交易，教育、培训、会议和讲座，以及个人消费娱乐都被转移到所谓的万维网（world wide web，以下简称web）上来了。与此相对应的是交互操作的复杂性越来越高。</p>
		<p>随着browser rver模式的日渐流行，很多操作都是在浏览器环境下的网页上完成的，并不是只有失效的链接和意外的出错才会使操作者感到烦恼，即便是一次完整的成功操作过程，也可能因为操作的繁复性过高或者使用上的不方便而给操作者带来不愉快的体验。</p>
		<p>本文试图阐述web交互页面设计的一些指导性原则，这些原则有利于避免发生不愉快的操作体验。这些原则是用户友好性的，是在完成同一种操作要求下，使用户最感到轻松、简单、舒适的web交互界面设计原则。我们假定我们讨论的web页面都是功能正常的，符合美学观点的。需要说明我们讨论的原则可能会和设计上的美学观点以及既有的功能设计有所冲突。如果发生这种情况，基于“实用的就是美的”观点，我们会建议您酌情放弃原先的美学观点与功能设计。</p>
		<p>一、输入控件的自动聚焦和可用键盘切换输入焦点 </p>
		<p>    使用javascript实现页面加载完成后立即自动聚焦(focus)到第一个输入控件。可用tab键（ie缺省实现）或方向键切换聚焦到下一个输入控件。 </p>
		<p>    输入控件指web页面表单(&lt;form&gt; )中显式的，需要用户进行修改、编辑操作的表单元素。对于这些控件，如果没有自动聚焦操作，不可避免的出现一次用户鼠标定位操作（如果用户此前处于键盘输入操作状态或鼠标定位后需要进行键盘输入操作，实际上是键盘鼠标切换操作）。如果鼠标定位后需要进行键盘输入操作，如果不能键盘切换输入焦点，那么不可避免的在切换输入焦点时需要反复的键盘鼠标切换操作，这是很繁琐的。</p>
		<p>    如果实现了页面加载完成即自动聚焦到第一个输入控件，并且可以键盘切换输入焦点标定位操作，那么对于用户来说整个页面的输入操作可能都不需要鼠标操作，或次数较少，这是一种便利。毕竟频繁的键盘鼠标切换操作是比较累人的。</p>
		<p>    对于有输入栏的对话框或网页，在不干预的情况下就应将当前控制焦点定位在待输入的输入栏上；如果输入栏在一般情况下不需要更改其中的内容，则应直接将焦点定在“确定”按钮上；在几个输入栏之间应支持tab，shift+tab切换操作，“确定”和“取消”应该是切换操作的终点，与具体所在位置无关。</p>
		<p>二、可用enter（或ctrl＋enter）键提交，确保和点击提交按钮的效果是相同的 </p>
		<p>不要在提交按钮上加入onclick=”…”这样的javascript代码。 </p>
		<p>    用enter键提交页面是原则1的自然延伸，而且这也是浏览器所缺省支持的。只所以单独列出来是因为实际上有些设计者设计的页面不能达到这种效果，结果导致使用enter键提交和点击“确定”按钮提交带来的效果不一样。大部分情况下是设计者在“确定”按钮上加入了onclik=”…”这样的代码，通过点击“确定”按钮后，会执行一段javascript代码，比如对某些hidden类型的input元素设值。而使用enter键提交时就不会执行这段代码。</p>
		<p>    正确的做法是把这段代码移到表单标签&lt;form&gt;中，以onsubmit=”…”属性引入。</p>
		<p>    对于&lt;textarea&gt;表单元素，它会消耗enter键，因此会使得enter键提交失效。可以引入javascript代码捕捉ctrl+enter复合键，一旦捕捉到即执行表单的submit()方法。对于需要频繁提交的场合，比如bbs上，这种代码是很有必要的。</p>
		<p>三、鼠标动作提示和回应 </p>
		<p>    对用户的鼠标定位操作，当移动到可响应的位置上时，应给予视觉或听觉的提示。 </p>
		<p>    动作回应的最简单形式就是鼠标icon变成手状。浏览器只对具有href属性的html标签会自动进行这种变换icon的行为。对于没有href属性（或没有设置href属性）的标签，可以通过javascript设置style属性的cursor为hand。</p>
		<p>    目标区域发生变化是更为主动的响应形式。当鼠标指针移到目标区域，此时指针图形改变或文字颜色发生改变均能较大的减轻用户搜索定位目标区域的注意力负担。在按钮上增添直观的图形，尽可能的增大按钮面积；按钮间保持适当的距离，太近增加了用户区别它们之间界限以防误操作的负担，太远增加了用户搜索定位按钮的负担。</p>
		<p>四、尽可能早的在客户端完成输入数据合法性验证 </p>
		<p>    输入数据的合法性检验应该在客户端使用javascript进行验证。除非验证只能在服务器端完成，否则验证工作应在最早能完成的情况下进行。 </p>
		<p>    在客户端完成数据合法性验证，可以避免一次服务器请求和回复通讯，这种通讯是需要用户等待的，如果用户等待很长时间后从服务器返回的结果提示出现的错误是在输入时即可发现的，那么这种设计就是不友好的。诸如密码长度限制，用户名允许字符限制等等，显然应该在客户端提交前就应该进行验证。</p>
		<p>五、根据应用场景决定在表单页面和提交后返回页面间是否使用中间过渡页面 </p>
		<p>    根据应用场景，决定是否显示接收表单页面（表单页面和提交后返回页面间的中间过渡页面），以及使用何种方式显示接收表单页面。 </p>
		<p>表单页面和接收表单页面是大部分web交互操作赖以实现的配合模式。关于表单页面和接收表单页面的相互关系的设计，要做如下几个方面的考虑。</p>
		<p>1．对于需要频繁操作的场合，从操作便利和快捷性出发，尽可能的减少服务器和客户端交互次数，应该避免使用中间过渡页面。提交完毕直接返回原来的表单页面或默认页面。在这种情况下要考虑到数据安全和可恢复性。</p>
		<p>如果因为用户输入的数据不合格，需要重新输入，那么，去除中间页面，把错误信息直接显示在原表单页面上的设计方式，将是最简洁的处理方式。用户只需要根据错误提示进行更正即可。当然这样做稍微增加了编程负担。在表单接收页面上需要包含原表单页面的内容，而且输入数据项都必须用服务器端代码或客户端javascript设置成用户输入的值。为了开发快捷，可以这样做：表单页面和接收表单页面用同一个服务器端脚本页面实现。这个页面按如下流程完成原来两个页面的工作：</p>
		<p>页面脚本初始化</p>
		<p>┃</p>
		<p>检查“提交”变量是否设置</p>
		<p>┠已设置，做数据验证</p>
		<p>┃ ┠验证通过－&gt;业务逻辑处理－&gt;使用包含页面方式或重定向方式返回到特定页面 </p>
		<p>┃ ┗验证不通过－&gt;保存用户输入的数据－&gt;退出表单提交处理到表单页面流程中</p>
		<p>┗未设置，做表单页面流程，如有来自提交流程中产生的用户输入数据，则显示出来</p>
		<p>其中，使用包含页面方式返回到特定页面可以避免一次客户端重定向过程，比客户端重定向过程还要快捷和稳定一些。但是有些情况下因为代码变量冲突或其他原因，使用包含页面方式可能并不方便，这时候可以使用服务器端重定向技术，在asp里是server.transfer方法，在java servlet里是requestdispatcher.forward()方法。不要使用response.redirect或者httpservletresponse.sendredirect()这种客户端http重定向方法。不使用中间过渡页面也就意味着用户不能后退浏览原先已经填好的表单页面，因为使用的是同一个url。所以在验证不通过情况下保存用户输入的数据就是必不可少的。 </p>
		<p>不使用中间过渡页面带来的另一个问题就是使用包含页面方式或服务器端重定向方式返回会使得url和页面内容不能一一对应。对于用户可能会直接用这个url（会收藏这个url）访问返回页面的情况，他会发现实际上到达的是表单页面，不是他想要的那个返回结果页面。所以，去除中间过渡页面，确实会带来url和内容含混不清的情况，因而不适合需要url和页面内容一一对应的场合。 </p>
		<p>2．从技术角度考虑，使用中间过渡页面能保证url和页面内容一一对应，简化页面开发工作。 </p>
		<p>为了保证页面内容总是和固定的url联系起来，必须使用客户端重定向： </p>
		<p>提交   业务逻辑处理 （中间过渡页面） </p>
		<p>表单页面――――－&gt;接收表单页面―――――――――&gt;显示处理结果―――&gt;客户端重定向到特定页面 </p>
		<p>客户端重定向分几种情况：</p>
		<p>1．使用http header重定向，location: <a href="http://www.netall.com.cn">http://www.netall.com.cn</a>，这种定向是最快的，在窗口一片空白的情况下就迅速访问（get）另一个页面。这种方式实际上不能显示处理结果，只能说是向第一种快速重定向方式的一种折衷处理；</p>
		<p>2．html标签刷新，&lt;meta http-equiv=”refresh” content=”5;url=http://www.netall.com.cn”&gt;，这种定向比较友好，在这个页面加载完毕后访问另一个页面。很多设计者把这个作为一个技巧使用，在载入一个大页面前放置一个缓冲页面以避免用户乏味的等待；</p>
		<p>3．javascript重定向。由于是用代码控制重定向，可以做的更灵活。比如根据用户习惯，控制操作完毕后的转向流程。</p>
		<p>4．被动式的重定向。在页面上放置按钮或链接，由用户手动决定返回到特定页面。这种情况适合于处理结果的显示页面包含相当多的信息，需要用户仔细浏览，而决定下一步的操作。 </p>
		<p>   在使用中间过渡页面的情况下，不能再使用页面过期失效了。否则一旦出现错误，需要用户重新输入表单数据，用户就不能用后退按钮恢复此前填写的表单数据了。除非设计者有意禁止这种恢复。 </p>
		<p>六、防止表单重复提交处理 </p>
		<p>    对提交按钮点击后做变灰处理避免在网络响应较慢情况下用户重复提交同一个表单。使用页面过期失效避免用户后退浏览重复提交表单。 </p>
		<p>    有些复杂的应用会导致需要较长时间的等待才会返回处理结果。而在较慢的网络环境中，这种情况更是频繁发生。焦急等待的用户往往会重复点击提交按钮。这种情况是设计者所不希望看到的。</p>
		<p>    使用javascript在点击提交按钮后使按钮失效变灰是一个最直接的办法（根据原则2这段代码应该放在&lt;form&gt;标签里onsubmit=”…”做）。此外，在表单页面上，用服务器端脚本设置http header的expires为立即过期可以保证用户没办法使用后退浏览恢复表单页面。注意这样做的代价可能是用户辛辛苦苦填写很长的内容，结果一旦操作失误就没法恢复。所以应该避免在包含&lt;textarea&gt;表单元素的页面上使用页面过期失效。</p>
		<p>    应该说，更严格的方法是，服务器端脚本就应该具备抵抗重复提交的能力。例如，为这个表单分配一个唯一id或一个使用一次即失效的验证码。此外，这个表单处理还应具有事务性质，如果表单不被接受，所做的改变还是能恢复的。在金融应用场合，重复提交同一笔交易是肯定不被允许的。能在重复提交中获利的一方总是会想办法绕过浏览器的限制，所以不能依赖于客户端的技术。</p>
		<p>七、页面链接是打开新窗口、使用原窗口还是弹出窗口的原则 </p>
		<p>    一般而言，首页上链接可以使用target=”_blank”属性打开新窗口，而其他页面上的链接都应使用原窗口或弹出窗口。如果链接页面内容相对原页面来说不重要，是附属性质的，可以使用弹出窗口方式。 </p>
		<p>    一般情况下应该使用原窗口，把是否保留原窗口内容的权利留给用户。除非设计者相信原页面是如此重要，在用户发出点击指令后还有使用上的价值，以至于不能被随便更新或覆盖。一般来说，只有首页才会处于这样一个地位，用户在首页上打开一个链接后，一般还会在这个首页上去打开另一个链接。比如首页包含极多链接的门户网站，或者搜索引擎的搜索结果页面。google.com以前的搜索结果页面上的链接是使用原窗口的，后来他们意识到用户会反复使用这个页面，而改成打开新窗口了。一般的网站如果首页链接不多，就不必使用新窗口，这是用户友好的设计原则。</p>
		<p>    上述情形的一个极端情况就是新页面内容比起原页面内容的重要性差很多，以至于都未必需要打开一个新页面。这时候使用弹出窗口比较合适。用javascript弹出窗口有好几种：一个是window.open()函数。这里有个技巧。应该使用window.open()先打开一个空白窗口，再使用location.replace()用目标页面替换。这样做可以避免在打开新页面的过程中导致原页面失去响应。window.open()将打开一个新的浏览器窗口进程，因此资源消耗比较大。另一个是由微软dynamichtml规范中扩充的方法createpopup()。createpopup()可以创建无边框的弹出窗口，消耗系统资源较小。还有一个就是用页面中隐藏的层&lt;div&gt;来模拟一个弹出页面。后两种可以使用javascript代码填充弹出窗口内容。如果需要下载网页作为其内容的话，需要微软dynamichtml规范中的&lt;download&gt;标签。</p>
		<p>八、尽可能少的排列可选项，尽可能少的安排操作步骤 </p>
		<p>    根据用户操作习惯安排尽可能少的操作菜单选项，同时要保证尽可能少的操作步骤。 在不降低功能多样性的前提下减少菜单项和操作步骤是用户友好的设计。要做到这一点很不容易。要从用户出发考虑他们最频繁的操作是什么。正常情况下一个用户需要的操作总可以归类为5个以下的种类，如果出现更多的种类，那一定是没有针对用户兴趣去区分主次。一个用户同时有5个以上的强烈兴趣中心是难以想像的，走马观花似的随意点击浏览的用户，是不大可能在某个种类上进行深入的交互操作的。在这5个种类中，每个种类都可能有若干个可操作的二级种类。如果这些二级操作项是不可见的，那么意味着要做两次选择才能进入可操作页面。这就违背了“尽可能少的安排操作步骤”这一原则。如果使用javascript制作二级菜单，避免请求服务器，会好一些。如果二级菜单项总共不超过20个左右，不妨将二级菜单直接显示出来，比如放在左列一字向下排开，这样只需要一次选择到可操作项，更加明了方便。</p>
		<p>九、操作逻辑无漏洞，保证数据是操作安全的 </p>
		<p>    多个页面间的操作和同个页面上的多个操作间的逻辑关系在设计上是安全和严谨的。保证不会出现不被允许的用户操作组合，至少不会因为用户的不适当的操作导致出错。 </p>
		<p>    这最典型的表现则是在页面上广泛采用的所谓联动下拉框设计。一个下拉框中允许的选项受另一个下拉框中的选择而变。另外一个例子是根据选择使表单元素有效或者失效。如果在多个页面间也要维持某种合法性逻辑，那么就需要服务器端脚本的参与。这样会使表单设计跟操作有关，应该说这不是一个好的设计。可以通过变更操作步骤顺序、组合方式来尽可能避免这种情况出现。</p>
		<p>    操作逻辑的设计既要保证用户任意的输入不会导致错误，也要保证是用户输入的数据能购被安全处理。在session控制下的表单中输入大幅文字可能会导致超时出错，这时候往往还伴随重定向过程，导致用户的长篇输入荡然无存。用javascript提醒用户已超时，请保存输入后重新提交，是一个好办法。某些表单元素如&lt;input type=”text”&gt;接受esc键清除数据，并且无法撤销，这也是很危险的。在中文输入法中常常使用esc键清楚输入的码位，一旦不小心多按一下esc就会使得输入数据消失。因此有必要用javascript禁用&lt;input&gt;和&lt;textarea&gt;的esc键处理过程。（Edit From:Internet,By Aaron）<br /></p>
<img src ="http://www.blogjava.net/jiabao/aggbug/203948.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiabao/" target="_blank">金家寶</a> 2008-05-29 22:35 <a href="http://www.blogjava.net/jiabao/archive/2008/05/29/203948.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP安全几个小问题</title><link>http://www.blogjava.net/jiabao/archive/2008/05/23/202469.html</link><dc:creator>金家寶</dc:creator><author>金家寶</author><pubDate>Fri, 23 May 2008 10:20:00 GMT</pubDate><guid>http://www.blogjava.net/jiabao/archive/2008/05/23/202469.html</guid><wfw:comment>http://www.blogjava.net/jiabao/comments/202469.html</wfw:comment><comments>http://www.blogjava.net/jiabao/archive/2008/05/23/202469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiabao/comments/commentRss/202469.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiabao/services/trackbacks/202469.html</trackback:ping><description><![CDATA[
		<div>记得还是去年，刚到据说是高手云集的威威公司上班的时候，一个新到的同事给我讲他花了半天的时间写，并做了很长时间的实践，写了个关于攻击.jsp页面的程序。下面我把具体的实现过程和大家分享一下。测试平台是Tomcat，当然，版本有点低，他的目的只是想证实一下他的某些想法。首先，他在Tomcat的WEB目录下建立了一个Hello.jsp文件，内容是： 
<p></p><p>&lt;%out.print(hello);%&gt;</p><p>通过IE的正常请求地址为：<a class="contentlink" href="http://localhost:8080/examples/jsp/hello.jsp" target="_blank"><font color="#4455aa">http://localhost:8080/examples/jsp/hello.jsp</font></a>，显示结果为：hello。然后开始具体的攻击测试。测试时，发出的请求地址为：<a class="contentlink" href="http://localhost:8080/examples/jsp/////////hello.jsp" target="_blank"><font color="#4455aa">http://localhost:8080/examples/jsp/////////hello.jsp</font></a> ，浏览器上显示编译错误，错误的原因是500 java.lang.NullPointerException。这个应该是比较常见的错误了。现在，恢复正常的请求<a class="contentlink" href="http://localhost:8080/examples/jsp/hello.jsp" target="_blank"><font color="#4455aa">http://localhost:8080/examples/jsp/hello.jsp</font></a>，问题就出现了，即出错，而且所报的错误和刚才造成它错误的请求是一样的：“500 java.lang.NullPointerException”。难道是缓存在浏览器里了吗？换台机器访问<a class="contentlink" href="http://192.168.10.188/examples/jsp/hello.jsp" target="_blank"><font color="#4455aa">http://192.168.10.188/examples/jsp/hello.jsp</font></a>。问题依然如故，哎！可怜的Hello.jsp呀!</p><p>　　虽然这个问题有些弱智，不过，他的目的也达到了，即找出“.jsp”流程中存在的一些问题。所以，JSP程序同ASP一样，还是存在着很多安全上的问题的。因此，对于一心研究论坛或者其他安全信息的朋友来说，要想发现JSP的BUG，了解一些JSP的工作原理是十分重要的。</p><p>　　需要指出的是，虽然是一门网络编程语言，JSP和PHP、ASP的工作机制还存在很大的区别，首次调用JSP文件时，JSP页面在执行时是编译式，而不是解释式的。首次调用JSP文件其实是执行一个编译为Servlet的过程。当浏览器向服务器请求这一个JSP文件的时候，服务器将检查自上次编译后JSP文件是否有改变，如果没有改变，就直接执行Servlet，而不用再重新编译，这样，工作效率得到了明显提高。这也是目前JSP论坛开始逐渐风靡的一个重要原因。</p><p>　　小提示：Servlet是用Java编写的Server端程序，它与协议和平台无关；Servlet运行于Java－enabled WEB Server中；Java Servlet可以动态地扩展Server的能力，并采用请求－响应模式提供WEB服务；最早支持Servlet技术的是JavaSoft的Java WEB Server；Servlet的主要功能在于交互式地浏览和修改数据，生成动态WEB内容。</p><p>　　说到这里，我们自然就会关心一些JSP的安全问题。一般来说，常见的JSP安全问题有源代码暴露（包括程序源代码以明文的方式返回给访问者，如添加特殊后缀引起jsp源代码暴露；插入特殊字符串引起Jsp源代码暴露；路径权限引起的文件Jsp源代码暴露；文件不存在引起的绝对路径暴露问题等）、远程程序执行类、数据库如SQL Server、Oracle 、DB2等的漏洞，操作系统漏洞等。不过，为了突出Jsp的安全问题，本文将结合目前的一些比较流行的Jsp论坛分类阐述和提出解决的建议。为了讲解方便，本文还采用一些公开了原代码的论坛实例代码，至于安装软件版本、操作系统等，可以查看安装提示。</p><p>　　论坛用户管理缺陷</p><p>　　为了加强实战效果，我们可以到<a class="contentlink" href="http://down.chinaz.com/S/5819.asp" target="_blank"><font color="#000050">http://down.chinaz.com/S/5819.asp</font></a>这个地址下载一个典型的论坛代码，根据提示，数据源名称为yyForum，用户名为xyworker，密码：999。到baidu、Google等网站搜索一下，我们可以看到，安装这个代码的论坛不少。仔细分析后，可以发现，用户管理的页面是user_manager.jsp文件。首先，我们看看这个系统是如何加强它的代码安全性的。其中，在代码的开始部分有一个if限制条件，代码的第三行到第十行具体如下：</p><p>&lt;%<br />if ((session.getValue(UserName)==null)||(session.getValue(UserClass)==null)||(!session.getValue(UserClass).equals(系统管理员)))</p><p>%&gt;</p><p>　　其中，Session.getValue表示检索出Session的值；sendRedirect()执行后，地址栏链接会改变，相当于客户端又重新发了一个get请求，要服务器传输另一个文件过来。</p><p>　　下面，我们再来看看修改用户信息的文件modifyuser_manager.jsp。典型代码如下：</p><p>&lt;%@page contentType=text/html; charset=gb2312 language=java import=java.sql.*,java.util.*  %&gt;<br />&lt;jsp:useBean id=yy scope=page class=yy.jdbc/&gt;<br />&lt;%!String User_Name,User_Password,sql, User_Sign;%&gt;<br />&lt;%<br />User_Name=request.getParameter(name);</p><p>//out.println(User_Name);<br />User_Password=request.getParameter(password);<br />User_Password=yy.ex_chinese(User_Password);<br />……<br />User_Sign=request.getParameter(sign);<br />User_Sign=yy.ex_chinese(User_Sign);</p><p>Connection con=yy.getConn();<br />Statement  stmt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);<br />sql=update 用户表 set 用户密码='+User_Password+',用户性别='+User_Sex+',用户邮箱='+User_Email+',居住地址='+User_Address+',手机号码='+User_Mobile+',Oicq='+User_Oicq+',出生日期='+User_Birthay+',用户等级='+User_Class+',签名='+User_Sign+' where 用户名='+User_Name+';<br />//out.println(sql);<br />stmt.executeUpdate(sql);<br />out.println(&lt;font size=2 color=blue&gt;正在处理你的用户信息，请稍后...&lt;/font&gt;&lt;meta http-equiv='refresh' content='2;url=user_manager.jsp'&gt;);<br />%&gt;<br />&lt;jsp:include page=inc/online.jsp flush=true/&gt;</p><p>　　看看这个文件，我们就好像看到了一个简单的教学文件。现在，假设管理员提交如下地址，即<a class="contentlink" href="http://www.51dz.net/bbs/modifyuser_manager.jsp?modifyid=51" target="_blank"><font color="#4455aa">http://www.51dz.net/bbs/modifyuser_manager.jsp?modifyid=51</font></a>，需要查看、修改ID为51的用户的资料（管理员默认的用户ID为51）。问题就出来了。同样的，我们可以通过搜索引擎得到如下地址<br /></p><div>很明显，这个用户管理文件缺乏认证，即使是普通的用户，甚至包括我们这些搭不上边的“游客”，也可以直接提交上述请求，从而将其资料一览无余，更让人动心的是，密码也是明文存储的。<br />　　<br />　　<a class="contentlink" href="http://www.51dz.net/bbs/modifyuser_manager.jsp" target="_blank"><font color="#000050">http://www.51dz.net/bbs/modifyuser_manager.jsp</font></a>同样是大开山门，直到恶意用户把数据更新的操作执行完毕，重定向到user_manager.jsp的时候，管理员才会看见那个显示错误的页面，但这个时候为时已晚，更谈不上“亡羊补牢”了。类似的错误存在于很多JSP的站点上，面对这样的论坛，我们能够放心的说“安全”吗？解决之道有很多，不过，最基本的要求是为每个需要加身份认证的地方加上身份认证，如果借用别人的代码，一定要对涉及到用户管理、密码认证等重要文件修改一下，照搬虽然省事，但代码毫无安全性可言。 
<p></p><p>　　再就是SQL注入的问题。比如，这个典型的问题：“昨天公司的数据库被人SQL注入，9万条记录都被update了，同事写了个JSP程序来把他改回来，可是这JSP没有一点信息返回，看不到进度，在运行些什么都不知道。”不过，这和JSP程序没有什么必然的联系，根据国情，国内的网站用ASP+Access或SQLServer的占70%以上，PHP+MySQL占20%，其它的不足10%。因此，ASP的SQL注入比较常见也不足为怪。不过，SQL注入漏洞可谓是“千里之堤，溃于蚁穴”，这种漏洞在网上极为普遍，即使是JSP程序也不能幸免。归根结底，通常是由于程序员对注入不了解，或者程序过滤不严格，或者某个参数忘记检查导致。看看这个教材式的JSP程序就可以窥见一般：</p><p>Statement stmt = conn.createStatement(); <br />String checkUser = select * from login where username = ' + userName + ' and userpassword = ' + userPassword + '; <br />ResultSet rs = stmt.executeQuery(checkUser); <br />if(rs.next()) <br />　response.sendRedirect(SuccessLogin.jsp); <br />else <br />　response.sendRedirect(FailureLogin.jsp);</p><p>　　针对这种情况，如果数据库里存在一个名叫“Tom”的用户，那么在不知道密码的情况下至少有下面几种方法可以登录： <br />用户名：Tom            密码：' or 'a'='a<br />用户名：Tom            密码：' or 1=1/*<br />用户名：Tom' or 1=1/*     密码：（任意）</p></div></div>
<img src ="http://www.blogjava.net/jiabao/aggbug/202469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiabao/" target="_blank">金家寶</a> 2008-05-23 18:20 <a href="http://www.blogjava.net/jiabao/archive/2008/05/23/202469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>