软件工程中,不论使用哪种开发语言,安全性一直是一个非常棘手却又重要的问题。安全性是软件开发领域永远的主题之一,而且随着互联网的蜂拥发展而带动的新技术的兴起与革命(比如近几年火起来的node.js,python,go等,甚至微软也开源后的.net Core),软件工程中的安全性更加的凸显与重要了。
那么,什么才是危险的呢?我的第一反应是注入攻击,比如SQL注入攻击。一个典型的场景是WEB应用中,用户登陆功能,根据用户输入的用户名密码获取相应的数据,那么SQL注入就应运而生,模拟用户名,密码加入特殊字符,加入恶意脚本等等手段,进而造成不了可挽回的后果。比如,正常脚本当如:
select * from userInfo where username='input_Name' and password='input_Pwd or'
那么,如果是这样的呢?
select * from userInfo where username='input_Name' and password='input_Pwdte' or 1=1 or ''
关于如何编写安全的Java代码,Sun官方给了一份指南,有兴趣的同学可以参考这篇文章,大致为:
• 静态字段
• 缩小作用域
• 公共方法和字段
• 保护包
• equals方法
• 如果可能使对象不可改变
• 不要返回指向包含敏感数据的内部数组的引用
• 不要直接存储用户提供的数组
• 序列化
• 原生函数
• 清除敏感信息
比如,DoS是一种常见的网络攻击,有人戏称为“洪水攻击”。其惯用手法是通过某种手段,比如大量的机器发送请求,将目标网站宽带和其资源耗尽,导致用户无法正常访问,甚至服务器的宕机。
而对于此类问题,如果单从服务器级别考虑,多少欠缺,我们或许需要考虑程序级别的攻击,比如Java,JVM,以及涉及到的线程方面的安全,应用程序的瑕疵等进行低成本的DoS攻击。
而在面试中,我们都会被问到安全性的问题,却大多比较多泛泛,大而广,而大多数的安全性问题都与代码安全性有关。我们回顾下Java代码的运行过程:
首先编译器把.java文件编程成.class字节码文件,然后由类加载器负责把.class文件加载到JVM,再由字节码校验进行校验,然后由Java解释器负责把该类文件解释为机器码执行。
在类加载器加载.class文件到java虚拟机的过程中,类加载器通过区分本机文件系统的类和网络系统导入的类增加安全性(不允许网络上的应用程序修改本地的数据),本机的类先被加载,一旦所有的类加载完,执行文件的内存划分就固定了,然后字节码校验器开始校验.class字节码文件,字节码校验器不检查那些可信任的编译器所产生的类文件。通过之后,java解释器材负责把类文件解释成为机器码进行执行。

