qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

XSS 前端防火墙—内联事件拦截

  关于 XSS 怎样形成、如何注入、能做什么、如何防范,前人已有无数的探讨,这里就不再累述了。本文介绍的则是另一种预防思路。
  几乎每篇谈论 XSS 的文章,结尾多少都会提到如何防止,然而大多万变不离其宗。要转义什么,要过滤什么,不要忘了什么之类的。尽管都是众所周知的道理,但 XSS 漏洞十几年来几乎从未中断过,不乏一些大网站也时常爆出,小网站更是家常便饭。
  预警系统
  事实上,至今仍未有一劳永逸的解决方案,要避免它依旧使用最古老的土办法,逐个的过滤。然而人总有疏忽的时候,每当产品迭代更新时,难免会遗漏一些新字段,导致漏洞被引入。
  即使圣人千虑也有一失,程序出 BUG 完全可以理解,及时修复就行。但令人费解的是,问题出现到被发现,却要经过相当长的时间。例如不久前贴吧 XSS 蠕虫脚本,直到大规模爆发后经用户举报,最终才得知。其他网站大多也类似,直到白帽子们挖掘出漏洞,提交到安全平台上,最终厂商才被告知。若遇到黑客私下留着这些漏洞慢慢利用,那只能听天由命了。
  因此,要是能有一套实时的预警系统,那就更好了。即使无法阻止漏洞的发生,但能在漏洞触发的第一时间里,通知开发人员,即可在最短的时间里修复,将损失降到最低。各式各样的应用层防火墙,也由此产生。
  不过,和传统的系统漏洞不同,XSS 最终是在用户页面中触发的。因此,我们不妨尝试使用前端的思路,进行在线防御。
  DOM 储存型 XSS
  先来假设一个有 BUG 的后台,没有很好处理用户输入的数据,导致 XSS 能被注入到页面:
  <img src="{路径}" />
  <img src="{路径" onload="alert(/xss/)}" />
  只转义尖括号,却忘了引号,是 XSS 里最为常见的。攻击者们可以提前关闭属性,并添加一个极易触发的内联事件,跨站脚本就这样被轻易执行了。
  那么,我们能否使用前端脚本来捕获,甚至拦截呢?
  被动扫描
  最简单的办法,就是把页面里所有元素都扫描一遍,检测那些 on 开头的内联属性,看看是不是存在异常:
  例如字符数非常多,正常情况下这是很少出现的,但 XSS 为了躲避转义有时会编码的很长;例如出现一些 XSS 经常使用的关键字,但在实际产品里几乎不会用到的。这些都可以作为漏洞出现的征兆,通知给开发人员。
  不过,土办法终究存在很大的局限性。在如今清一色的 AJAX 时代,页面元素从来都不是固定的。伴随着用户各种交互,新内容随时都可能动态添加进来。即使换成定期扫描一次,XSS 也可能在定时器的间隔中触发,并销毁自己,那样永远都无法跟踪到了。况且,频繁的扫描对性能影响也是巨大的。
  如同早期的安全软件一样,每隔几秒扫描一次注册表启动项,不仅费性能,而且对恶意软件几乎不起作用;但之后的主动防御系统就不同了,只有在真正调用 API 时才进行分析,不通过则直接拦截,完全避免了定时器的间隔遗漏。
  因此,我们需要这种类似的延时策略 —— 仅在 XSS 即将触发时对其分析,对不符合策略的元素,进行拦截或者放行,同时发送报警到后台日志。
  主动防御
  『主动防御』,这概念放在前端脚本里似乎有些玄乎。但不难发现,这仅仅是执行优先级的事而已 —— 只要防御程序能运行在其他程序之前,我们就有了可进可退的主动权。对于无比强大的 HTML5 和灵活多变的 JavaScript,这些概念都可以被玩转出来。
  继续回到刚才讨论的内联事件 XSS 上来。浏览器虽然没提供可操控内联事件的接口,但内联事件的本质仍是一个事件,无论怎样变化都离不开 DOM 事件模型。
  扯到模型上面,一切即将迎刃而解。模型是解决问题的最靠谱的办法,尤其是像 DOM-3-Event 这种早已制定的模型,其稳定性毋庸置疑。
  即便没仔细阅读官方文档,但凡做过网页的都知道,有个 addEventListener 的接口,并取代了曾经一个古老的叫 attachEvent 的东西。尽管只是新增了一个参数而已,但正是这个差别成了人们津津乐道的话题。每当面试谈到事件时,总少不了考察下这个新参数的用途。尽管在日常开发中很少用到它。
  关于事件捕获和冒泡的细节,就不多讨论了。下面的这段代码,或许能激发你对『主动防御』的遐想。
<button onclick="console.log('target')">CLICK ME</button>
<script>
document.addEventListener('click', function(e) {
console.log('bubble');
});
document.addEventListener('click', function(e) {
console.log('capture');
//e.stopImmediatePropagation();
}, true);
</script>
Run

 尽管按钮上直接绑了一个内联的事件,但事件模型并不买账,仍然得按标准的流程走一遍。capture,target,bubble,模型就是那样固执。
  不过,把那行注释的代码恢复,结果就只剩 capture 了。这个简单的道理大家都明白,也没什么好解释的。
  但仔细揣摩下,这不就是『主动防御』的概念吗?捕获程序运行在内联事件触发之前,并且完全有能力拦截之后的调用。
  上面的 Demo 只是不假思索拦截了所有的事件。如果我们再加一些策略判断,或许就更明朗了:
<button onclick="console.log('xss')">CLICK ME</button>
<script>
document.addEventListener('click', function(e) {
console.log('bubble');
});
document.addEventListener('click', function(e) {
var element = e.target;
var code = element.getAttribute('onclick');
if (/xss/.test(code)) {
e.stopImmediatePropagation();
console.log('拦截可疑事件:', code);
}
}, true);
</script>
Run
  我们先在捕获阶段扫描内联事件字符,若是出现了『xss』这个关键字,后续的事件就被拦截了;换成其他字符,仍然继续执行。同理,我们还可以判断字符长度是否过多,以及更详细的黑白名单正则。
  怎么样,一个主动防御的原型诞生了吧。
  不过,上面的片段还有个小问题,就是把事件的冒泡过程也给屏蔽了,而我们仅仅想拦截内联事件而已。解决办法也很简单,把 e.stopImmediatePropagation() 换成 element.onclick = null 就可以了。
  当然,目前这只能防护 onclick,而现实中有太多的内联事件。鼠标、键盘、触屏、网络状态等等,不同浏览器支持的事件也不一样,甚至还有私有事件,难道都要事先逐一列出并且都捕获吗?是的,可以都捕获,但不必事先都列出来。
  因为我们监听的是 document 对象,浏览器所有内联事件都对应着 document.onxxx 的属性,因此只需运行时遍历一下 document 对象,即可获得所有的事件名。
<img src="*" onerror="console.log('xss')" />
<script>
function hookEvent(onevent) {
document.addEventListener(onevent.substr(2), function(e) {
var element = e.target;
if (element.nodeType != Node.ELEMENT_NODE) {
return;
}
var code = element.getAttribute(onevent);
if (code && /xss/.test(code)) {
element[onevent] = null;
console.log('拦截可疑事件:', code);
}
}, true);
}
console.time('耗时');
for (var k in document) {
if (/^on/.test(k)) {
//console.log('监控:', k);
hookEvent(k);
}
}
console.timeEnd('耗时');
</script>
Run
  现在,无论页面中哪个元素触发哪个内联事件,都能预先被我们捕获,并根据策略可进可退了。
 性能优化
  或许有些事件没有必要捕获,例如视频播放、音量调节等,但就算全都捕捉也耗不了多少时间,基本都在 1ms 左右。
  当然,注册事件本来就花不了多少时间,真正的耗费都算在回调上了。尽管大多数事件触发都不频繁,额外的扫描可以忽律不计。但和鼠标移动相关的事件那就不容忽视了,因此得考虑性能优化。
  显然,内联事件代码在运行过程中几乎不可能发生变化。使用内联事件大多为了简单,如果还要在运行时 setAttribute 去改变内联代码,完全就是不可理喻的。因此,我们只需对某个元素的特定事件,扫描一次就可以了。之后根据标志,即可直接跳过。
<div style="width:100%; height:100%; position:absolute" onmouseover="console.log('xss')"></div>
<script>
function hookEvent(onevent) {
document.addEventListener(onevent.substr(2), function(e) {
var element = e.target;
// 跳过已扫描的事件
var flags = element['_flag'];
if (!flags) {
flags = element['_flag'] = {};
}
if (typeof flags[onevent] != 'undefined') {
return;
}
flags[onevent] = true;
if (element.nodeType != Node.ELEMENT_NODE) {
return;
}
var code = element.getAttribute(onevent);
if (code && /xss/.test(code)) {
element[onevent] = null;
console.log('拦截可疑代码:', code);
}
}, true);
}
for (var k in document) {
if (/^on/.test(k)) {
hookEvent(k);
}
}
</script>
Run
  这样,之后的扫描仅仅是判断一下目标对象中的标记而已。即使疯狂晃动鼠标,CPU 使用率也都忽略不计了。
  到此,在 XSS 内联事件这块,我们已实现主动防御。
  对于有着大量字符,或者出现类似 String.fromCharCode,$.getScript 这类典型 XSS 代码的,完全可以将其拦截;发现有 alert(/xss/),alert(123) 这些测试代码,可以暂时放行,并将日志发送到后台,确定是否能够复现。
  如果复现,说明已有人发现 XSS 并成功注入了,但还没大规模开始利用。程序猿们赶紧第一时间修 BUG 吧,让黑客忙活一阵子后发现漏洞已经修复了:)
  字符策略的缺陷
  但是,光靠代码字符串来判断,还是会有疏漏的。尤其是黑客们知道有这么个玩意存在,会更加小心了。把代码转义用以躲避关键字,并将字符存储在其他地方,以躲过长度检测,即可完全绕过我们的监控了:
  <img src="*" onerror="window['ev'+'al'](this.align)" align="alert('a mass of code...')">
  因此,我们不仅需要分析关键字。在回调执行时,还需监控 eval、setTimeout('...') 等这类能解析代码的函数被调用。
  不过,通常不会注入太多的代码,而是直接引入一个外部脚本,既简单又靠谱,并且能实时修改攻击内容:
  <img src="*" onerror="$['get'+'Script'](...)">

posted @ 2014-07-09 16:01 顺其自然EVO 阅读(481) | 评论 (0)编辑 收藏

用Selenium WebDriver+Grid2实现浏览器端性能测试

在 Web 2.0 应用中,页面装载时间和浏览器渲染时间将成为决定性能的关键因素。我们在测试过程中不仅需要手动触发性能测试工具,而且需要模仿不同的用户行为,包括不同的浏览器、不同的网络条件和不同的使用习惯。在这种情况下我们需要新的方法与工具来覆盖特别是浏览器端的性能测试。用 Selenium WebDriver + Grid2 可以解决浏览器端性能测试中的自动化和并发性问题。本文介绍了这种新的测试框架和脚本的开发过程,并结合案例给出了具体的代码和结果分析。使用 Selenium WebDriver+Grid2 可以将已有的自动化测试资源为性能测试服务,将测试人员从繁杂的手动测试中解放出来,专注于结果分析和问题解决。
  我们需要新的方法与工具来覆盖浏览器端的性能测试
  在浏览器端的性能测试中遇到的一些问题
  在传统的互联网应用中,由于浏览器端的时间消耗比较有限,并且页面装载时间也比较简单且有限,所以在对传统互联网应用的响应时间分析中,我们通常忽略页面装载时间和浏览器渲染时间,而着重分析服务器响应时间。而在 Web 2.0 应用中,页面装载时间和浏览器渲染时间将成为决定性能的关键因素,所以我们需要新的方法与工具来覆盖特别是客户端的性能:浏览器响应时间。
  我们使用一些工具来帮助我们测试浏览器端的性能;比如说 DummyNet 可以模拟不同网络带宽和延迟,以便我们分析不同网络情况下的的网页性能;HttpWatch 可以分别记录每个请求的服务器端响应时间、页面装载时间、浏览器渲染时间;DynaTrace AJAX 是一种详细的底层工具,它不仅可以显示所有请求和文件在网络中的传输时间,还会记录浏览器 render、CPU 消耗、JavaScript 解析和运行的详细情况。我们使用这些工具的时候大多是手动触发,为了得到数据和分析报告,必须将用户案例在不同的浏览器上手动实现,并且在某一时刻打开或关闭工具和保存结果。过多的手动操作使我们很难专注于数据分析和发现问题。所以我们需要解决以下问题:
  需要有工具在模仿用户使用 web 应用程序的同时自动触发这些工具,生成分析数据。
  可以同时模仿不同的用户行为,包括不同的浏览器,网络条件和使用习惯。
  下面的章节将介绍如何利用自动化工具 Selenium 来搭建测试网页浏览器端性能的测试框架,实现浏览器端自动测试和并行测试。
  浏览器端性能测试框架中用到的技术
  我们的测试框架主要采用了以下技术:
  Selenium WebDriver
  Selenium 是针对 Web 应用的测试框架,支持多种浏览器和多种编程语。WebDriver 通过原生浏览器支持或者浏览器扩展直接控制浏览器。它提供了一个更为简单,一致的编程接口并且解决了在 Selenium-RC API 遇到的问题。Selenium WebDriver 更好的支持了动态网页。它的目标是为现代的网页程序测试提供设计良好的面向对象的 API。
  Selenium Grid2
  Selenium Grid 允许用户将测试案例分布在几台机器上并行执行。用户可以在一个集中控制点控制不同的环境。在不同的浏览器 / 系统组合上面更为容易的运行测试案例。允许用户更多的利用虚拟资源减少了维护测试环境的成本。Selenium Grid2 很好的支持了 WebDriver。利用原有的 WebDriver 脚本和 Grid 技术就可以将不同的测试用例分布在不同的机器或虚机上,在特定的浏览器版本上运行,自动地启动关闭分析工具,统一地保存测试结果。Selenium Grid2 的机制如图 1,启动一个中央节点(Hub),然后启动多个远程控制节点(rc),启动 rc 时告知 Hub 的位置,这样这些 rc 就可以注册到 Hub 上,测试程序与 Hub 通讯,当测试被并发地发给 Hub 时,Hub 会自动将这些测试命令分发给已经注册的 rc,rc 接到命令后执行测试。
  TestNG
  本测试系统还使用 TestNG 工具来辅助配置自动测试。TestNG 是测试 Java 应用程序的框架之一。TestNG 以其灵活性和参数化成为定义 Selenium 的驱动验收测试的首选。它通过一些语义注释来传递测试的参数,定义测试脚本的顺序并配置运行时的性能。用户可以通过配置来生成各式测试报告,十分方便。
  图 1. Selenium Grid2 的机制
  Ant
  在框架中我们使用 Ant 来构建版本 , 然后部署到测试环境中去 , 再然后执行测试脚本到生成发送测试报告 .
  浏览器端性能测试框架的实现
  Selenium WebDriver 编写测试脚本
  利用 Selenium WebDriver 为动作执行和页面跳转进行设计。Selenium WebDriver 可以模拟用户上网的行为,添加计时代码用以测算用户某个动作执行的时间或是页面跳转需要的时间。以用户登录为例,在输入用户名和密码之后开始用 startTrans 函数开始计时,在点击提交按钮页面跳转之后用 endTrans 函数结束计时。
  清单 1. 在 Selenium 中添加计时代码
  利用 DummyNet 模拟不同网络条件下用户的案例执行。带宽模拟与控制是性能测试的一个常规需求。很多时候我们必须能够提供可变的带宽、上行和下行速率,从而获得这些条件下性能的表现。开源工具 DummyNet 是一款优秀的网络控制工具,它通过重载本机的网卡驱动,提供给开放人员命令行接口去模拟带宽可变利用。调用 DummyNet 的命令后执行 Selenium 脚本可以设置网络带宽和延迟。以下命令限制从源地址到目的地址的流量带宽 2Mb, 延迟 300ms。
  ipfw add pipe 2 ip from %sourceip%  to %targetip% out proto ip
  ipfw pipe 2 config delay 300ms bw 2Mbit/s
  利用 HttpWatch 和 DynaTrace AJAX 为特定的页面请求记录时间。HttpWatch 和 DynaTrace AJAX 是两款强大的网页数据分析工具。它们通常集成在浏览器的工具栏。以往我们通过手动打开这些工具在浏览页面的同时收集所需的分析数据。在新的框架中 Selenium 脚本可以调用它们的接口驱动浏览器从会话中启动分析工具并收集保存性能信息。
  清单 2. Selenium 脚本调用 DynaTrace AJAX 接口
  Selenium Grid2 集中控制测试环境
  步骤一:启动中央节点(Hub)。Hub 会接收测试请求并将它们分布在正确的节点上。启动 Hub 的默认端口为 4444,也可以通过参数指定端口。打开地址:http://localhost:4444/grid/console,通过页面可以观察 Hub 的状态。启动命令如下 :
  java -jar selenium-server-standalone-2.14.0.jar -role hub
  步骤二:配置和启动远程控制节点(rc)。远程节点是您需要测试的测试机所在的物理机或虚拟机。启动节点时需要传入 Hub 的 IP 地址和端口号。默认情况下,节点的端口为 5555,每个节点可以启动 11 个浏览器,包括 5 个 firefox、5 个 chrome 和 1 个 ie 浏览器。最多有 5 个并行的测试案例。用户也可以通过参数指定端口和浏览器,以下命令将会启动 Linux 远程节点上的三个 firefox 浏览器进行并行测试,它们指向在另一台机器的 Hub 节点。
  java -jar selenium-server-standalone-2.14.0.jar -role node \
  -hub http://remotehost:4444/grid/register \
  -browser browserName=firefox,version=3.6,maxInstances=3,\
  platform=LINUX
  Selenium WebDriver 和 Grid2 并发执行测试用例
  TestNG 可以很方便的加载在已经开发好的 Selenium WebDriver 测试案例,测试用例中的参数通过 @Parameters 传递。在测试中我们需要将同一个测试案例发送到不同的节点或是浏览器上执行。所以我们从已有的 Selenium 脚本中选出案例后用 @Test 标注并加入节点的 IP、端口和浏览器类型参数。

 清单 3. 将 TestNG 加载在已有的 Selenium 测试脚本
  @Test
  @Parameters({"seleniumHost", "seleniumPort", "bs"})
  public void sitenav(String Host,String Port,String browser)
  TestNG 要求将所有要运行的测试用例都记录在一个叫 testng.xml 的文件中,然后根据该文件中的测试用例顺序依次执行测试。通过 suit 标签的属性可以指定 method、tests 或是 classes 的并发执行。我们在 testng.xml 中将测试的并行粒度设为 Test, 用参数传入不同的 IP 地址、端口号、浏览器名称,形成不同的测试案例,以便在不同节点上的不同浏览器中并行执行。
  清单 4. testng.xml 中有关并行测试案例的配置
  最后用 Ant 从命令行运行 TestNG 类。用户通过命令行启动 Ant,读取目标文件 build.xml 来获得项目的参数,例如目标定义、类路径、引入的文件等。Ant 通过读取 TestNG 的配置文件 testng.xml 来获取参数,将 Java 代码编译成 TestNG 类,并且根据配置文件中传入的参数和顺序来执行这些类。以下是在 Ant 的 build.xml 里面如何正确配置 TestNG。
  清单 5. Build.xml 里配置 TestNG
  应用示例
  IBM Connections 3 是 IBM 专门为满足企业业务需求而设计的一款社交软件。我们用它作为目标程序来测试其浏览器端的性能。用 Selenium WebDriver 编写脚本模拟用户依次浏览主页、登陆、个人资料、博客等主要页面。我们将同样的脚本在不同网络环境、不同操作系统、不同浏览器中并行执行,并且记录页面的响应时间,完整下载时间,对不同浏览器,不同网络条件下的页面响应时间加以比较。测试过程如下:
  选取几台测试机作为测试节点,测试机器上具有我们所需要的操作系统、浏览器类型、测试分析工具,选取一台测试机作为 Hub。配置和启动 Hub 和测试节点。
  准备不同类型的测试案例 Test1.....TestN。根据操作系统、浏览器和所需的测试工具,在 testng.xml 中将测试脚本分配给相对应的测试节点 Node1.......NodeN 形成不同的测试案例。图 2 是测试节点配置和测试案例的分布图。
  编辑 build.xml 文件。执行 ant 命令。通过网页观察 Hub 的状态和测试节点的执行情况。
  测试执行完,从各节点和 Hub 上收集测试数据加以整理和分析。
  测试数据从几个方面获得。有关测试环境的数据将会直接从配置文件获取,简单的页面响应时间会由 Selenium 脚本获取。浏览器响应时间分解和网页分析数据将会由 HTTPWACTH 等辅助测试工具获得。图 3 是由部分测试数据经过汇总整理后形成的表格。从表格中可以看到同一个页面请求在不同配置的测试机上的响应时间,如果该机器加载了性能分析工具,还可以通过抓取 HTTPWACTH 分析结果进一步得到响应时间分解。
  小结
  利用 Selenium WebDriver 和 Grid2 可以将已有的自动化测试脚本为性能测试服务,并发、自动地执行测试案例节省了时间和人力,使测试人员能够将精力集中在数据分析和性能调优上。灵活的配置测试环境,包括网络环境、操作系统和浏览器类型,可以在短时间内得出不同情况下目标程序的客户端性能数据,方便比较和发现问题。

posted @ 2014-07-09 15:59 顺其自然EVO 阅读(1231) | 评论 (0)编辑 收藏

LoadRunner压力测试时监控服务器Linux的资源情况

在进行负载测试(Load Test)是要监控服务器的CPU、内存、磁盘、网络的情况。如何监控Ubuntu的情况呢。
  1、安装rstatd,sudo apt-get install rstatd,如果无法apt安装,可以下载安装。
  2、启动rpc.rstatd
  查看是否正常启动,用如下命令
rpcinfo -p
[root@localhost ~]# rpcinfo -p
program vers proto   port
100000    2   tcp    111  portmapper
100000    2   udp    111  portmapper
100024    1   udp    676  status
100024    1   tcp    679  status
100001    3   udp    691  rstatd
100001    2   udp    691  rstatd
100001    1   udp    691  rstatd
  3、在LoadRunner Controller的run界面中,添加System Resource Graphs下的Unix Resource,在Unix Resource图上右键Add Measurements,然后点击Add,填写ip如192.168.1.99,默认只有三个指标,在下面的Add中可以添加其他指标。
  4、下面说一下各种指标的情况
  CPU指标
  Average load
  上一分钟同时处于“就绪”状态的平均进程数,< CPU个数 * 核心数 * 0.7
  CPU utilization
  CPU 的使用时间百分比,如果在75%以上,则可以考虑换CPU了
  Swap-in rate
  正在交换的进程数
  Swap-out rate
  正在交换的进程数
  Context switches rate
  每秒钟在进程或线程之间的切换次数
  System mode CPU utilization
  在系统模式下使用 CPU 的时间百分比
  User mode CPU utilization
  在用户模式下使用 CPU 的时间百分比
  Interrupt rate
  每秒内的设备中断数
  内存
  Page-in rate
  每秒钟读入到物理内存中的页数
  Page-out rate
  每秒钟写入页面文件和从物理内存中删除的页数
  Paging rate
  每秒钟读入物理内存或写入页面文件的页数,如果持续在几百,可能要加大内存了
  LoadRunner采集的数据中,内存的使用情况是没有的,可以装sar,然后用sar来观察:
  可以使用该命令sar -n DEV -u -r 3 120 > perform.log
  这个命令3秒采样一次,共采样120次 360秒=6分钟,可以根据自己的需要调整 3 和 120 这两个值。perform.log是保存的文件名

磁盘
  Collision rate
  每秒钟在以太网上检测到的冲突数
  Disk rate
  磁盘传输速率
  网络
  Incoming packets error rate
  接收以太网数据包时每秒钟接收到的错误数
  Incoming packets rate
  每秒钟传入的以太网数据包数
  Outgoing packets errors rate
  发送以太网数据包时每秒钟发送的错误数
  Outgoing packets rate
  每秒钟传出的以太网数据包数
  pps是
  以太网传输最小包长是64字节。包转发线速的衡量标准是以单位时间内发送64byte的数据包(最小包)的个数作为计算基准的。
  对于千兆以太网来说,计算方法如下:
  1000Mbps/((64B+8B+12B)×8bit)=1.488095pps
  说明:当以太网帧为64Byte时,需考虑8Byte的前导符和12Byte的帧间隙的固定开销。
  在以太网中,每个帧头都要加上了8个字节的前导符,前导符的作用在于告诉监听设备数据将要到来。然后,以太网中的每个帧之间都要有帧间隙,即每发完一个帧之后要等待一段时间再发另外一个帧,在以太网标准中规定最小是12个字节,然而帧间隙在实际应用中有可能会比12个字节要大,在这里我用了最小值。每个帧都要有20个字节的固定开销。(另外这20字节的信息是不能通过抓包软件抓下来的)
  因此一个全双工线速的千兆以太网端口在转发64Byte包时的包转发率为1.488Mpps。
  以下是常用以太网端口的包转发率:
  1、万兆以太网:14.88Mpps
  2、千兆以太网:1.488Mpps
  3、百兆以太网:0.1488Mpps
  4、十兆以太网:0.01488Mpps(14.88Kpps)

posted @ 2014-07-09 15:59 顺其自然EVO 阅读(741) | 评论 (0)编辑 收藏

自由测试人Jarod的一天

  宇宙中心接任务
  上午10:05
  五道口漫咖啡,Jarod摆弄着新淘来的Nexus5手机,时而饮一口桌上的焦糖拿铁,间或偷眼瞄一下邻桌的长腿妹子。
  上午10:30
  Allison如约而至,开始为Jarod介绍本次任务,并演示本次任务的目标:对Android应用“探路者”进行性能评估。“探路者”是Allison所在公司的新研发的产品,既有给用户展示的动态界面,也会常驻手机后台。其核心业务模式是将位置信息上报云端,结合云端数据进行复杂的计算后,将计算结果返回给手机。“除了CPU的消耗,还有流量的消耗和GPS模块的使用”,Jarod默默记下。
  由于“探路者”是Allison本次创业的关键,不容有失,但创业公司资源紧张,团队中并没有专门的终端测试专家,产品临近发布,心里不免惴惴,于是便有了这次与Jarod的合作。
  Jarod现在是一名自由职业者,曾任职于世界知名IT企业的安全产品部门,有着丰富的软硬件测试经验和黑客经验,如今五子登科,便早早主动退休,过起了养鱼遛鸟的生活。闲来无事,Jarod也会偶尔从熟人圈子接些私活,与人方便,也顺便瞒着夫人赚些零花钱,以维护经济自由。
  上午11:15
  Allison交接了委托任务后先行离去,Jarod先简单浏览了“探路者”的界面,把玩一番后,又开启了核心的“随行”功能,“随行”功能是持续型功能,要在运动中才能看出效果,不过静止的状态也是要保证正常处理的。虽然Allison说过“探路者”已经通过了功能测试和用户体验,基本功能是没问题的,但Jarod作为一个资深的测试者,怀疑一切是职业的第一信条,质量如何,一定要亲身试过才知道。
  上午11:30
  Jarod判定“探路者”的基本功能正常,于是对“探路者”进行启动状态的基本性能评估。Jarod先将“探路者”退出,然后从测试工具GT中启动“探路者”,启动完成后回到GT界面查看,“探路者”的CPU占用在0%-2%波动,结合手机默认的调频策略判断比较正常,jiffes(CPU时间片)值累积在400多,内存PSS值稳定在36M,上行流量和下行流量都不到1K,无异常,数据存档。再启动电流监控观察,1分钟后平均电流是220mA,从数据变化曲线上看没有连续的峰值和规律性波动,待后面长时间测试时综合多项指标再分析吧。回到“探路者”界面,从GT的悬浮框中观察,CPU占用在0%-5%波动,PSS值和上下行流量也没有异常的增长,OK。

  一人一机一GT
  上午11:50
  Jarod完成“探路者”的启动性能验证,把采集的数据存档备案后,开始场测(到产品的实际使用环境中测试)前的准备:清理了“探路者”的缓存,给手机充满电并固化了亮度等设置,规划好场测路线,顺便吃午饭。40分钟后,Jarod喝完最后一杯柠檬水,只带上Nexus5,便奔香山去了。作为独行的极客,Jarod追求极致简约:MBA,mini机箱,无线键鼠,网线自然是见不得的,所以当Jarod遇到“GT随身调”时,一种幸福感无可言状,因为GT可以独立完成手机的大部分性能指标的采集,以后场测时他不必再背着笔记本,不必再带着电流计了。Jarod出门前计算了一下,本次任务的实测和数据采集,1人1机1GT足矣,充电宝也不带了。
  下午12:45
  Jarod上了辆直达香山的311路,找了个座位坐下,先打开了GT的“月光宝盒”,再启动“探路者”并切换到 “随行”模式,接着使用GT对其进行性能监控,然后在GT的悬浮框中对CPU、PSS、流量值即时观察。行进中,PSS逐渐跃升到90M稳定下来,观察一会没有明显的内存泄露迹象,OK。但是“探路者”的CPU占用持续在25%~40%,这对主流的4核手机已经算是高消耗了。Jarod等了3分钟看到CPU没有下降的趋势,于是进入GT界面,发现这几分钟的平均电流达到660mA。Jarod心里一紧,对Nexus5的2100mAh的电池来说,持续运行在“随行”模式下的手机只能支撑3个小时,与“随行”的目标续航5小时有不小差距。
  公交上忙碌的Jarod
  Jarod立即观察流量,10分钟的下行流量有110K,在没抓包的情况看不出明显的疑点。Jarod思考了一下,对着“随行”界面上几个按钮试了试,其中有个点下去,屏幕上弹出“停止实时路况”的提示,再看平均电流,这回降到500mA。“先反馈上去,看看这块逻辑能有多大的优化空间吧”。Jarod想。“即使开启实时路况的耗电优化到550mA,续航时间能达到4小时,离目标还差1小时呢”。Jarod又开始盯着手机观察“嗯,画面的动画倒是挺顺滑的……咦?好像忽略了什么……会不会过于顺滑了?”这个想法闪念而出,Jarod立即切到GT的界面,激活FPS(帧率)的监测,回到“随行”界面观察。从GT的悬浮框中,Jarod看到FPS的数字变换着:59,60,60,58,60,59,59,59……“果然如此,Allison他们并没有给动画做帧率上的限制,所以Android系统会尽可能的刷新UI画面,达到上限60帧”。其实,从Jarod的经验看,“随行”功能并不需要这么高的帧率,即使把动画刷新降低到30帧,普通用户也不会感觉到有卡顿的。而降低帧率,最直接的好处就是减少耗电。
  Jarod立即记下:“建议1:在不影响动画效果下降帧率。建议2:优化‘实时路况’的算法性能。”
  Jarod又持续的对“随行”的性能数据进行了10分钟的采集,确认没有新的发现后,即保存了数据,进行第二个核心功能“潜行”的测试。“潜行”是“探路者”退到后台或手机灭屏后,“探路者”仍然以语音提示的方式对用户提供服务的模式。
  下午13:25
  Jarod开始“潜行”模式的测试,还是那些监测指标。顺利的“潜行”了10分钟后,Jarod看到没有明显异常,只是产生了140K的下行流量,比“随行”模式还要多一些,而上行流量也达到70K,。虽然流量一般会根据环境的复杂变化出现较大波动,不过Jarod谨慎起见,还是决定上山测试“潜行”的时候,用GT抓个包回去分析一下。
  登顶香炉峰
  下午13:55
  Jarod到达香山,启动抓包后,开始测试爬山中的“潜行”。五月的香山风景迤逦,凉风习习,Jarod工作兼怡情,畅快之余,不免健步如飞,四刻钟后即抵达香炉峰。掏出手机,点亮屏幕一看,顿时傻眼,原来“探路者”不知何时已弃主crash于宝刹云间去了。“刚刚爬上香炉峰的时候,‘探路者’还语音提醒了啊……”,回想到这里,Jarod心中有所明悟。熟练的保存了抓包文件后,Jarod切换到GT的Logcat查看界面,立即把手机缓存的Logcat日志保存下来,然后开始回溯。所幸,在3分钟前的位置发现了“探路者”crash的踪迹。“有迹可循的crash都不会太难解决,又多了笔收获”,Jarod心中盘算。
  下午15:10
  Jarod看到Nexus5的电量已不足30%了,便关闭了早先在GT上打开的“月光宝盒”准备下山。其实“月光宝盒”是一个记录用户移动轨迹的功能,利用它,Jarod完整的记录了这次测试过程中的位置变化,后续若有回归测试,在Android手机模拟GPS的模式下回放录制好的移动轨迹,就不必再跑一趟香山了。
  下午16:15
  Jarod赶在大塞车之前回到家中,连上电脑分析抓包后,连同一天的测试数据一起整理了报告给Allison,Allison立即回复并预约了3天后进行回归测试,Jarod表示接受挑战。
  下午16:30
  算算时间孩子该放学,妻子也该串门回来,Jarod摇身一变回复了本职,开始准备一家3口的晚餐。

posted @ 2014-07-09 15:56 顺其自然EVO 阅读(193) | 评论 (0)编辑 收藏

浅淡常见的WEB安全漏洞测试及验证

【文件上传漏洞】
  1.对用户上传的文件没有进行充分合理的验证,导致被上传木马等恶意文件并执行
  验证方式可能有:客户端JS检测、服务器MIME类型检测、服务器目录路径检测、服务器文件扩展名检测、服务器文件内容检测。
  常见的方式:服务器充分验证文件类型及文件内容、服务器端重命名
  其他限制:服务器端上传目录设置不可执行权限
  【CSS漏洞】
  例如input输入框这种类型的测试
  http:/host/xss/example1.php?name = song <script>alert("hello")</script>
  测试的时候也可以直接简单点,输入简单的这些实体字符(例如:<>()"),然后查看前台的源代码是否做转义,如果没有那么自己可以输入任何的脚本都是有可能执行的。
  Ps: CSS 绕过的方法,其实是很多的,一般我们可以根据后台的返回来通过不同的方法绕过进行测试
  【SQL注入攻击】
  相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。
  SQL注入:
  还有所谓的命令注入:


二、关于WEB安全的几点思考:
  安全意识
  永远不用相信来自用户的输入
  管理所有来自客户端的数据
  开发安全的代码
  遵循最佳安全实践来指导构建WEB系统
  三、常用WEB安全检测工具介绍
  黑盒类测试工具:
  三、安全测试包含内容
  一般来说,80%的安全测试都包含在这里面了:
  简单来看一下这类测试生成的测试报告,例如 acunetix web vulnerability scanner 工具扫描测试结果如下,我们可以针对不同等级的测试漏洞来选择性的进行关注或者手工验证尝试。

posted @ 2014-07-09 15:53 顺其自然EVO 阅读(743) | 评论 (0)编辑 收藏

NoSQL系列:选择合适的数据库

NoSQL系列:选择合适的数据库
  为什么使用NoSQL数据库?
  1、阻抗失衡
  关系模型和内存中的数据结构不匹配
  采用更为方便的数据交互方式提升开发效率
  2、待处理的数据量很大
  数据量超过关系型数据库的承载能力
  大集群的出现
  在成本方面,集群中应用关系数据库,许可费用是一笔很大的支出;
  横向扩展和纵向扩展:关系数据库一般只能是纵向扩展,通过对单机服务器的性能换代增强而实现;而对于扩展到多个服务器,
  DBMS先天不足;(DBMS不是设计给集群使用的)
  3、对数据的访问效率要求高
  NoSQL数据库的分类
  键值数据库
  1、产品
  Redis
  BerkerleyDB
  Memcached
  Project Voldemort
  Riak
  LevelDB
  2、适用场景
  存放会话信息
  用户配置信息
  购物车数据
  3、不适合的场景
  数据间有大量关系
  含有多项操作的事务
  根据键值的部分来查询数据
  操作关键字集合
  文档数据库
  1、产品
  MongoDB
  CouchDB
  RavenDB
  Terrastore
  OrientDB
  2、适用场景
  事件记录
  内容管理系统及博客平台
  网站分析及实时分析
  电子商务应用程序
  (需要较灵活的模式,低成本建立数据模型)
  3、不适合场景
  包含多项操作的复杂查询
  查询持续变化的聚合结构

 列族数据库
  1、产品
  HBase
  Amazon SimpleDB
  Cassdndra
  Hypertable
  BigTable(google)
  2、适用场景
  事件记录
  (保存应用程序状态,运行中遇到的错误)
  CMS及博客平台
  计数器
  3、不适用场景
  需要ACID事务
  查询模式变化频繁的场合
  图数据库
  1、产品
  FlockDB
  HyperGraphDB
  Infinite Graph
  Neo4J
  OrientDB
  2、适用场景
  互联数据
  推荐引擎
  基于位置的服务
  3、不适用场景
  更新全部或某个子集的实体
  附思维导图

posted @ 2014-07-09 11:15 顺其自然EVO 阅读(170) | 评论 (0)编辑 收藏

Java 对象存储到Oracle Blob字段

 Java 数据对象在没有持久存储到业务表时,可能需要临时存储。原因如下:有些持续时间长的任务需要数据对象,但是该任务没完成时数据对象不能持久存储;当服务在持久任务执行期间重启后恢复任务时需要数据对象。这样的情况下,数据对象的临时存储是有意义的。
  java对象存储到Blob
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo;
try {
oo = new ObjectOutputStream(bo);
oo.writeObject(libraryEtextJn);
} catch (IOException e) {
e.printStackTrace();
}
Blob blob=  Hibernate.createBlob(bo.toByteArray());
  从Blob读取Java对象
  ObjectInputStream is = new ObjectInputStream(new BufferedInputStream(blob.getBinaryStream()));
  LibraryEtext libraryEtext = (LibraryEtext)is.readObject();
  Hibernate配置Blob字段
  <property name="liberary" column="LIBERARY" type="blob" />

posted @ 2014-07-09 11:15 顺其自然EVO 阅读(294) | 评论 (0)编辑 收藏

判断windows操作系统平台

判断当前Windows系统是win2000,winXP,winVista,win2003,win7...
private static IntPtr GetSysTrayWnd()
{
IntPtr handle = FindWindow("Shell_TrayWnd", null);
handle = FindWindowEx(handle, IntPtr.Zero, "TrayNotifyWnd", null);
if (IsWindowsXP || IsWindows2000 || IsWindows2003 || IsWindowsVista || IsWindows7)
{
if (IsWindows2000)
{
handle = FindWindowEx(handle, IntPtr.Zero, "ToolbarWindow32", null);
return handle;
}
else
{
handle = FindWindowEx(handle, IntPtr.Zero, "SysPager", null);
handle = FindWindowEx(handle, IntPtr.Zero, "ToolbarWindow32", null);
return handle;
}
}
else
{
return handle;
}
}

判断当前Windows系统是win2000,winXP,winVista,win2003,win7...
private static IntPtr GetSysTrayWnd()
{
IntPtr handle = FindWindow("Shell_TrayWnd", null);
handle = FindWindowEx(handle, IntPtr.Zero, "TrayNotifyWnd", null);
if (IsWindowsXP || IsWindows2000 || IsWindows2003 || IsWindowsVista || IsWindows7)
{
if (IsWindows2000)
{
handle = FindWindowEx(handle, IntPtr.Zero, "ToolbarWindow32", null);
return handle;
}
else
{
handle = FindWindowEx(handle, IntPtr.Zero, "SysPager", null);
handle = FindWindowEx(handle, IntPtr.Zero, "ToolbarWindow32", null);
return handle;
}
}
else
{
return handle;
}
}

posted @ 2014-07-09 11:12 顺其自然EVO 阅读(237) | 评论 (0)编辑 收藏

Java中需要注意的一些案例

 在编写Java代码中,我们或多或少会遇到下面的一些案例,对于这些情况,我们怎么做?那么接下来我介绍一些方法,大家可以看一下:
  1.判断数组{"a","b","c","d"}是否包含有"a",见以下代码,你喜欢用哪一种呢,我推荐使用ifcontainsByArrays,因为该方法内部更严谨一些。
public static void main(String[] args) {
String [] strs = {"a","b","c","d"};
Test t = new Test();
System.out.println(t.ifcontains(strs, "a"));
System.out.println(t.ifcontainsByArrays(strs, "a"));
}
public boolean ifcontains(String [] strs, String str) {
for (String s : strs) {
if (s.equals(str)) {
return true;
}
}
return false;
}
public boolean ifcontainsByArrays(String [] strs, String str) {
// 注意:Arrays.asList()方法返回的是 java.util.Arrays.ArrayList而不是java.util.ArrayList
return Arrays.asList(strs).contains(str);
}
  2.在循环中删除一个列表中的元素,见如下代码,我建议使用removeByIterator方法,因为不需要再创建新的list。
public static void main(String[] args) {
List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
List<String> list1 = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Test1 t = new Test1();
for (String s : t.removeByIterator(list, "c")) {
System.out.print(s);
}
System.out.println();
System.out.println("----------------------------");
for (String s : t.removeByNewList(list1, "c")) {
System.out.print(s);
}
}
public List<String> removeByNewList(List<String> list, String str) {
List<String> newList = new ArrayList<String>();
for (String s : list) {
if (!s.equals(str)) {
newList.add(s);
}
}
return newList;
}
public List<String> removeByIterator(List<String> list, String str) {
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (s.equals(str)) {
// 移除迭代器返回的元素
iterator.remove();
}
}
return list;
}
  暂时先列举两个,有时间的话,继续

posted @ 2014-07-08 14:11 顺其自然EVO 阅读(179) | 评论 (0)编辑 收藏

mysql数据存储目录迁移小记

 背景:
  因刚开始安装mysql的时候没有考虑后期磁盘分区空间问题,所以mysql的数据保存目录就按安装默认的目录/usr/local/mysql/(我下载的是一个lamp一键安装包安装的mysql),现在随着服务的运行发现/usr/local/mysql所在分区空间使用快接近100%了,怎么办?不想重装mysql,我服务器大部分空间mount在/app下了,于想想到了linux下的ln -s命令
  OK 下面开操作了(注:以下操作均在零晨1点操作,记住先将数据备份成sql文件):
  1. service mysqld stop
  2. 在/app 下新建一个目录mysqldir : mkdir mysqldir #在新分区上建立mysqldir目录
  3. cd /usr/local/mysql && cp -r /app/mysqldir 新数据拷到新目录mysqldir下
  4. rm -rf mysql  //把原来的数据目录删掉
  5 ln -s /app/mysqldir mysql
  6. service mysqld start
  本以为没啥问题,运行第6条命令后发现mysql起不来,所如下错误:
  Starting MySQL. ERROR! The server quit without updating PID file (/usr/local/mysql/data/AY13121220352352963dZ.pid).
  运行service mysqld status输出如下提示信息:
  ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists
  ok 这个问题应该很常见了,我的解决办法是运行如下命令:
  1. chown -R mysql:mysql /app/mysqldir #设置新目录权限归mysql用户所有
  2. rm -f /var/lock/subsys/mysql
  再执行service mysqld start 大功告成

posted @ 2014-07-08 14:11 顺其自然EVO 阅读(1452) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 86 87 88 89 90 91 92 93 94 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜