月度归档:2014年11月

《松本行弘的程序世界》– 面向对象

编程语言不是从安全的角度考虑减少程序员犯错误,而是在程序员自己负责的前提下为他提供最大限度发挥能力的灵活性。

一、结构化编程

结构化编程的基本思想是有序地控制流程,即把程序的执行顺序限制为顺序、分支和循环这 3 种,把共通的处理称为例程。

把基本上相同的处理抽象成例程,其中不同的部分由外部传递进来的参数来对应。

面向对象编程是结构化编程的延伸。

二、面向对象编程

多态性(也称动态绑定)、数据抽象(也称信息隐藏或封装)和继承被称为面向对象编程的三原则。

多态

多态的基本内容:根据对象的不同类型而进行适当处理;自动选择最合适的方法,而程序内部则不发生冲突。

各种数据可以统一处理。多态性让程序员只关注要处理什么(What),而不是怎么去处理(How)。

数据抽象

数据抽象是数据和处理方法的结合。对数据内容的处理和操作,必须通过事先定义好的方法来进行。数据和处理方法结合起来成为了黑盒子。

利用现有的类派生新类的方法称为“差分编程法”(difference programming)。

类以数据为核心,把与之相关的处理也都集中到一起。

黑盒化是模块化的基本原则,面向对象编程语言将每一类数据都当作黑盒处理。

继续阅读

Java 反射 抽取类的方法信息

目前参与的项目是用 Spring MVC + MyBatis 实现的,项目部署就是一个war包。公司从外面请了个顾问,建议将公司网络分为A、B两个区,B区的安全级别高些,可以访问数据库,A区的安全级别低些,不能访问数据库,直接面向互联网,应用需要访问外部互联网服务时 或 外部用户请求应用时都必须在 A 区完成,A区通过定制的网关访问 B 区的应用。这个建议是强制执行,所以就需要拆分项目了。

考虑到开发的方便性,A区与B区之间就必须工作在类似Hessian之类的远程调用上,而不能直接在http层上,要不然装包拆包都累死人了。

项目目前的代码层次是 Rest 风格的 Controller + Service + MyBatis 的 Mapper。Controller 里大量使用servlet的API,所以不能把controller层抽取出来作为远程调用的接口。Mapper本身只是一个接口,service层与mapper层之间没法再拆,只能在controller与service之间拆。项目里没有专门为每个 service 组件定义一个相应的接口,需要根据已有的service组件抽取出对应的接口。

由于组件太多,只能写工具类抽取。

工具类的目标:

  1. 抽取所有组件的公开方法作为接口的方法,保留方法定义的类型信息和参数名等信息。
  2. 生成接口所依赖的导入并拷贝所有依赖的导入类。
  3. 生成对应的Hessian配置。

要保留方法的参数名信息需要 Java 8 的特性。Java 8 的 javac 增加了一个选项 -parameters,表示在生成的字节码文件里保留方法的参数名。

继续阅读

Session Fix 与 Jboss 4.2.2

Session Fix 会话固定

Session Fix,会话固定,是一个安全漏洞,以 servlet 容器为例。

  • 无状态的HTTP与会话:由于 HTTP 是无状态的服务,容器为了在同一个用户的不同请求之间保持状态,为每个状态维持一个会话,Servlet 容器里一般就是 HttpSession 对象。HTTP 客户端每次请求时,都需要把表示这个 HttpSession 对象的 ID (一般命名为 JSESSIONID)传递过来,JSESSIONID 的传递机制常用的是作为URL 的一部分或放在 Cookie,由于每个 HTTP 请求都会传输 Cookie,所以这是最常见的机制。在第一次请求时,由于没有 JSESSIONID,容器会创建一个 HttpSession 对象,把它的的ID 作为 JSESSIONID 的值设置到 Cookie,HTTP 客户端第二次请求时,把这个 JSESSIONID 的值也传递给了容器,容器就可以找到对应的 HttpSession 对象。

  • 会话固定
    登陆与注销前后,如果这个 JSESSIONID 不会改变,则表示存在会话固定的漏洞。
    登陆前,用户第一次请求容器,容器生成一个 HttpSession 对象,设置 JSESSIONID,但这个JSESSIONID 是未验证的,如果这个 JSESSIONID 被恶意用户获取到,那么用户登录后,这个 JSESSIONID 变为有效的后,恶意用户就可以把用 JSESSIONID 来伪冒合法用户。
    注销后,也需要把合法的 JSESSIONID 作废,以免被恶意用户获取后假冒。

  • 修复方法
    登陆成功后作废登陆前的会话;注销成功后作为之前的合法会话。
    注销后需要调用 HttpSession.invalidate() 方法来作废合法的 HttpSession 对象,要不然还会存在内存泄漏,因为未注销的 HttpSession 对象只有在超时后才会被回收。

Jboss 4.2.2 默认配置导致会话固定

Jboss 4.2.2 的配置 .../deploy/jboss-web.deployer/server.xml 里的默认配置 emptySessionPath="true",这会导致 HttpSession.invalidate() 方法无效,需要修改为 false