黑客攻击网站怎么判刑_黑客攻击java网站

hacker|
148

如何有效的防止Java程序被反编译和破解

由于Java字节码的抽象级别较高,因此它们较容易被反编译。下面介绍了几种常用的方法,用于保护Java字节码不被反编译。通常,这些方法不能够绝对防止程序被反编译,而是加大反编译的难度而已,因为这些方法都有自己的使用环境和弱点。

1.隔离Java程序

最简单的方法就是让用户不能够访问到Java Class程序,这种方法是最根本的方法,具体实现有多种方式。例如,开发人员可以将关键的Java Class放在服务器端,客户端通过访问服务器的相关接口来获得服务,而不是直接访问Class文件。这样黑客就没有办法反编译Class文件。目前,通过接口提供服务的标准和协议也越来越多,例如 HTTP、Web Service、RPC等。但是有很多应用都不适合这种保护方式,例如对于单机运行的程序就无法隔离Java程序。

2.对Class文件进行加密

为了防止Class文件被直接反编译,许多开发人员将一些关键的Class文件进行加密,例如对注册码、序列号管理相关的类等。在使用这些被加密的类之前,程序首先需要对这些类进行解密,而后再将这些类装载到JVM当中。这些类的解密可以由硬件完成,也可以使用软件完成。

在实现时,开发人员往往通过自定义ClassLoader类来完成加密类的装载(注意由于安全性的原因,Applet不能够支持自定义的ClassLoader)。自定义的ClassLoader首先找到加密的类,而后进行解密,最后将解密后的类装载到JVM当中。在这种保护方式中,自定义的ClassLoader是非常关键的类。由于它本身不是被加密的,因此它可能成为黑客最先攻击的目标。如果相关的解密密钥和算法被攻克,那么被加密的类也很容易被解密。

3.转换成本地代码

将程序转换成本地代码也是一种防止反编译的有效方法。因为本地代码往往难以被反编译。开发人员可以选择将整个应用程序转换成本地代码,也可以选择关键模块转换。如果仅仅转换关键部分模块,Java程序在使用这些模块时,需要使用JNI技术进行调用。当然,在使用这种技术保护Java程序的同时,也牺牲了Java的跨平台特性。对于不同的平台,我们需要维护不同版本的本地代码,这将加重软件支持和维护的工作。不过对于一些关键的模块,有时这种方案往往是必要的。为了保证这些本地代码不被修改和替代,通常需要对这些代码进行数字签名。在使用这些本地代码之前,往往需要对这些本地代码进行认证,确保这些代码没有被黑客更改。如果签名检查通过,则调用相关JNI方法。

4.代码混淆

代码混淆是对Class文件进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能(语义)。但是混淆后的代码很难被反编译,即反编译后得出的代码是非常难懂、晦涩的,因此反编译人员很难得出程序的真正语义。从理论上来说,黑客如果有足够的时间,被混淆的代码仍然可能被破解,甚至目前有些人正在研制反混淆的工具。但是从实际情况来看,由于混淆技术的多元化发展,混淆理论的成熟,经过混淆的Java代码还是能够很好地防止反编译。下面我们会详细介绍混淆技术,因为混淆是一种保护Java程序的重要技术。

网络安全包括哪些

问题一:网络安全包括哪些方面 一.网络安全是个太大的话题。

1。机房安全(防火、水、雷、虫;人员进入)

2。网络隔断(VLAN,端口检测)

3。口令(各种方式)

4。流量过滤(允许哪些,不允许哪些)

但现在,很多网络都只是想着安装一个防火墙而已。甚至很少配置、管理

而实际,现在用在防火墙上的功能,一个简单路由器就能实现(当然字符界面麻烦些)。

二.网络安全包括的东西很多,主要有防火墙,入侵检测,风险评估,加密认证,审计,VPNp,访问控制。如果你想要知道具体有哪些产品,可以去相关站点比如 里面的opsec .我在新加坡做网络安全,不知道国内现在这方面的市场如何,不过相信随着企业网络化和电子商务的发展,网络安全肯定有很好的市场。我推荐一些产品,抛砖引玉吧

firewall: checkpoint and cisco pix

IDS : iss realsecure ,CA etrust ,NAI

Vulnerability Asses *** ent: ISS ,NAI cybercop , webtrends

audit: tiger(open software)

认证: radius ,ldap

我个人觉得做的好不能仅仅停留于产品的销售,这样最多也是 vendor ,最好能做解决方案提供,solution provider and consulting

问题二:网络安全包括哪几个方面 1、企业安全制度(最重抚)

2、数据安全(防灾备份机制)

3、传输安全(路由热备份、NAT、ACL等)

4、服务器安全(包括冗余、DMZ区域等)

5、防火墙安全(硬件或软件实现、背靠背、DMZ等)

6、防病毒安全

问题三:网络安全包括哪些内容 网络安全知识互联网产业稳定发展解决网络安全问题是关键

网络安全问题接踵而至,给飞速发展的互联网经济笼上了一层阴影,造成巨额损失。可以说,互联网要持续快速发展就不得不趟过安全这道弯。

如果说高高上扬的纳斯达克股使人们看到泡沫背后的网络魔力的话,那么接连不断的网络安全事件则让人们开始冷静地思考魔力背后的现实――网络游戏玩家装备被盗事件层出不穷;网站被黑也是频繁发生;一波又一波的病毒“冲击波”则让互联网用户们战战兢兢。黑客、病毒已经成为时下充斥网络世界的热门词语,它们轮番的攻势使本不坚固的互联网络越发显得脆弱。这就告诉我们:人们在享受着互联网所带来的便利信息的同时,必须认真对待和妥善解决网络安全问题。

据最新统计数据显示,目前我国95%的与因特网相联的网络管理中心都遭到过境内外黑客的攻击或侵入,受害涉及的覆盖面越来越大、程度越来越深。据国际互联网保安公司symantec2002年的报告指出,中国甚至已经成为全球黑客的第三大来源地,竟然有6.9%的攻击国际互联网活动都是由中国发出的。另一方面从国家计算机病毒应急处理中心日常监测结果来看,计算机病毒呈现出异常活跃的态势。在2001年,我国有73%的计算机曾感染病毒,到了2002年上升到近84%,2003年上半年又增加到85%。而微软的官方统计数据称2002年因网络安全问题给全球经济直接造成了130胆美元的损失。

众所周知,安全才是网络的生存之本。没有安全保障的信息资产,就无法实现自身的价值。作为信息的载体,网络亦然。网络安全的危害性显而易见,而造成网络安全问题的原因各不相同。

首先是用户观念上的麻痹,缺乏相应的警惕性,而这种观念的结果就是管理跟不上技术发展的步伐,更谈不上具体的网络安全防范措施和防范意识。由于用户对网络安全存在被动和一劳永逸的意识,在出现网络安全问题时,并不知道该采取什么措施有效地保护自己的信息安全。大多数人认为,用几种杀毒软件和防火墙就能保障网络信息的安全,虽然这种做法的确有一定的效果,但这并不能保障网络的绝对安全。可见,要想有效地解决网络安全问题,首要的就是用户要重视安全问题和提高安全意识,在思想意思上为网络筑起一道“防护墙”。

其次,我国的网络安全设备大部分都是进口的,还没有我们自己的核心产品。这在很大程度上造成了对国外企业网络安全产品的依赖性,对我国的网络信息安全造成了一定的影响。因此,我们应该加强自身网络安全技术的研发能力,提高我国网络安全实际操作能力。

问题四:网络安全软件有哪些 很多,看你什么方面。

之前的回答里面都是杀毒软件,相信一定无法满足您的回答。

您需要的比如D-D-O-S软件有Hoic,Loic和Xoic,当然还有效率较低级的国人开发的软件。

漏洞测试软件比如Goolag Scanner

当然,线上工具也很多,比如Shodan可以寻找到网络上的任何一个存在的东西,包括摄像头啊,网站的后台服务器啊,之类的,注册的话提供详细物理位置。

OFCORS也有专门用来攻击的Anonymous OS和魔方渗透系统之类的。

就看你想干嘛了。至于为什么圆角符号,这个,如果不用你就看不到了。

问题五:一个常见的网络安全体系主要包括哪些部分 大型复杂的网络必须有一个全面的网络安全体系。

一、防火墙技术

在网关上安装防火墙,分组过滤和ip伪装,监视网络内外的通信。

二、用户身份验证技术

不同用户分设不同权限,并定期检查。

三、入侵检测技术

四、口令管理

每个用户设置口令,定义口令存活期,不准使用简单数字、英文等

五、病毒防护

建立病毒防火墙,安装杀毒软件,及时查杀服务器和终端;限制共享目录及读写权限;限制网上下载和盗版软件使用;

六、系统管理

及时打系统补丁;定期对服务器安全评估,修补漏洞;禁止从软盘、光驱引导;设置开机口令(cmos中);设置屏保口令;nt系统中使用ntfs格式;删除不用账户;

七、硬件管理

八、代理技术

在路由器后面使用代理服务器,两网卡一个对内,一个对外,建立物理隔离,并隐藏内网ip。

九、系统使用双机冗余、磁盘陈列技术。

问题六:网络安全管理包括什么内容? 网络安全管理是一个体系的东西,内容很多

网络安全管理大体上分为管理策略和具体的管理内容,管理内容又包括边界安全管理,内网安全管理等,这里给你一个参考的内容,金牌网管员之网络信息安全管理,你可以了解下:

ean-info/2009/0908/100

同时具体的内容涉及:

一、信息安全重点基础知识

1、企业内部信息保护

信息安全管理的基本概念:

信息安全三元组,标识、认证、责任、授权和隐私的概念,人员角色

安全控制的主要目标:

安全威胁和系统脆弱性的概念、信息系统的风险管理

2、企业内部信息泄露的途径

偶然损失

不适当的活动

非法的计算机操作

黑客攻击:

黑客简史、黑客攻击分类、黑客攻击的一般过程、常见黑客攻击手段

3、避免内部信息泄露的方法

结构性安全(PDR模型)

风险评估:

资产评估、风险分析、选择安全措施、审计系统

安全意识的培养

二、使用现有安全设备构建安全网络

1、内网安全管理

内网安全管理面临的问题

内网安全管理实现的主要功能:

软硬件资产管理、行为管理、网络访问管理、安全漏洞管理、补丁管理、对各类违规行为的审计

2、常见安全技术与设备

防病毒:

防病毒系统的主要技订、防病毒系统的部署、防病毒技术的发展趋势

防火墙:

防火墙技术介绍、防火墙的典型应用、防火墙的技术指标、防火墙发展趋势

VPN技术和密码学:

密码学简介、常见加密技术简介、VPN的概念、VPN的分类、常见VPN技术、构建VPN系统

IPS和IDS技术:

入侵检测技术概述、入侵检测系统分类及特点、IDS结构和关键技术、IDS应用指南、IDS发展趋势、入侵防御系统的概念、IPS的应用

漏洞扫描:

漏洞扫描概述、漏洞扫描的应用

访问控制:

访问控制模型、标识和认证、口令、生物学测定、认证协议、访问控制方法

存储和备份:

数据存储和备份技术、数据备份计划、灾难恢复计划

3、安全设备的功能和适用范围

各类安全设备的不足

构建全面的防御体系

三、安全管理体系的建立与维护

1、安全策略的实现

安全策略包含的内容

制定安全策略

人员管理

2、物理安全

物理安全的重要性

对物理安全的威胁

对物理安全的控制

3、安全信息系统的维护

安全管理维护

监控内外网环境

问题七:网络安全技术主要有哪些? 计算机网络安全技术简称网络安全技术,指致力于解决诸如如何有效进行介入控制,以及如何保证数据传输的安全性的技术手段,主要包括物理安全分析技术,网络结构安全分析技术,系统安全分析技术,管理安全分析技术,及其它的安全服务和安全机制策略。

技术分类

虚拟网技术

虚拟网技术主要基于近年发展的局域网交换技术(ATM和以太网交换)。交换技术将传统的基于广播的局域网技术发展为面向连接的技术。因此,网管系统有能力限制局域网通讯的范围而无需通过开销很大的路由器。

防火墙技术

网络防火墙技术是一种用来加强网络之间访问控制,防止外部网络用户以非法手段通过外部网络进入内部网络,访问内部网络资源,保护内部网络操作环境的特殊网络互联设备.它对两个或多个网络之间传输的数据包如链接方式按照一定的安全策略来实施检查,以决定网络之间的通信是否被允许,并监视网络运行状态.

防火墙产品主要有堡垒主机,包过滤路由器,应用层网关(代理服务器)以及电路层网关,屏蔽主机防火墙,双宿主机等类型.

病毒防护技术

病毒历来是信息系统安全的主要问题之一。由于网络的广泛互联,病毒的传播途径和速度大大加快。

将病毒的途径分为:

(1 ) 通过FTP,电子邮件传播。

(2) 通过软盘、光盘、磁带传播。

(3) 通过Web游览传播,主要是恶意的Java控件网站。

(4) 通过群件系统传播。

病毒防护的主要技术如下:

(1) 阻止病毒的传播。

在防火墙、代理服务器、SMTP服务器、网络服务器、群件服务器上安装病毒过滤软件。在桌面PC安装病毒监控软件。

(2) 检查和清除病毒。

使用防病毒软件检查和清除病毒。

(3) 病毒数据库的升级。

病毒数据库应不断更新,并下发到桌面系统。

(4) 在防火墙、代理服务器及PC上安装Java及ActiveX控制扫描软件,禁止未经许可的控件下载和安装。

入侵检测技术

利用防火墙技术,经过仔细的配置,通常能够在内外网之间提供安全的网络保护,降低了网络安全风险。但是,仅仅使用防火墙、网络安全还远远不够:

(1) 入侵者可寻找防火墙背后可能敞开的后门。

(2) 入侵者可能就在防火墙内。

(3) 由于性能的限制,防火墙通常不能提供实时的入侵检测能力。

入侵检测系统是近年出现的新型网络安全技术,目的是提供实时的入侵检测及采取相应的防护手段,如记录证据用于跟踪和恢复、断开网络连接等。

实时入侵检测能力之所以重要首先它能够对付来自内部网络的攻击,其次它能够缩短hacker入侵的时间。

入侵检测系统可分为两类:基于主机和基于网络的入侵检测系统。

安全扫描技术

网络安全技术中,另一类重要技术为安全扫描技术。安全扫描技术与防火墙、安全监控系统互相配合能够提供很高安全性的网络。

安全扫描工具通常也分为基于服务器和基于网络的扫描器。

认证和数字签名技术

认证技术主要解决网络通讯过程中通讯双方的身份认可,数字签名作为身份认证技术中的一种具体技术,同时数字签名还可用于通信过程中的不可抵赖要求的实现。

VPN技术

1、企业对VPN 技术的需求

企业总部和各分支机构之间采用internet网络进行连接,由于internet是公用网络,因此,必须保证其安全性。我们将利用公共网络实现的私用网络称为虚拟私用网(VPN)。

2、数字签名

数字签名作为验证发送者身份和消息完整性的根据。公共密钥系统(如RSA)基于私有/公共密钥对,作为验证发送者身份和消息完整性的根据。CA使用私有密钥计算其数字签名,利用CA提供的公共密钥,任何人均可验证签名的真实性。伪造数字签名从计算能力上是不可行的。

3、IP......

问题八:网络安全包括哪几方面? 环境;资源共享;数据通信;计算机病毒;网络管理

问题九:常见的网络安全问题有哪些 网络安全问题分为很多类,比如说系统安全,web安全,无线安全,物联网安全等等。就我个人学习而言,我是学习web安全的,所谓的web安全也就是我们常见的网站安全。

web安全:当网站源码的程序员对源码编写的时候,没有给赋值的参数进行过滤,那么会产生很多安全漏洞,比较常见的漏洞就是SQL注入漏洞,XSS漏洞,文件包含漏洞,越权漏洞,等等。其实这些漏洞很容易杜绝,但是程序员因为懒惰所以铸成大错,当然,在服务器配置方面也会出现漏洞,比如说常见的,目录遍历,敏感下载,文件上传,解析漏洞等等。都是因为服务器的配置不当而产生的,产生这些漏洞非常容易让攻击者获得想要的数据,比如说网站管理员的账号密码,如果漏洞严重,可以直接提权服务器,拿到服务器的shell权限。

系统安全:系统安全的漏洞一般都是权限类漏洞,用户没有及时更新补丁,或者开放了敏感端口,敏感服务,等等,都可以被黑客利用,详细的可以看看缓冲区溢出漏洞原理。

无线安全和物联网安全,这些的话,我也没有深究过,我们说的无线常用的就是wifl,或者说是无线设备,攻击者可以伪造页面,植入木马等等获取到连入恶意wifl的主机权限,物联网我们最常见的就是自动贩卖机或者是一些智能设备了,那么就自动贩卖机来说,自动贩卖机是一个沙盒系统,说到底他还是个系统,当用户通过某种方式获取到可以对系统进行操作的时候,那岂不是可以任意的买东西,等等。

当然。网络安全不是一两句话就可以说完的,这里只是举几个常见的例子,具体不懂得可以追问,手工打字,望楼主采纳。

java的框架(比如struts2)对于xss攻击、sql注入等黑客方式有防御么?

框架本身并不具有这些功能。

防止xss,sql等的攻击大部分需要程序员自己注意。

sql注入本身就是sql语句写法的漏洞导致。

xss攻击的防御还是需要对非法字符串进行判断过滤。

服务器被攻击后怎么处理?

1、发现服务器被入侵,应立即关闭所有网站服务,暂停至少3小时。这时候很多站长朋友可能会想,不行呀,网站关闭几个小时,那该损失多大啊,可是你想想,是一个可能被黑客修改的钓鱼网站对客户的损失大,还是一个关闭的网站呢?你可以先把网站暂时跳转到一个单页面,写一些网站维护的的公告。

2、下载服务器日志,并且对服务器进行全盘杀毒扫描。这将花费你将近1-2小时的时间,但是这是必须得做的事情,你必须确认黑客没在服务器上安装后门木马程序,同时分析系统日志,看黑客是通过哪个网站,哪个漏洞入侵到服务器来的。找到并确认攻击源,并将黑客挂马的网址和被篡改的黑页面截图保存下来,还有黑客可能留下的个人IP或者代理IP地址。

3、Windows系统打上最新的补丁,然后就是mysql或者sql数据库补丁,还有php以及IIS,serv-u就更不用说了,经常出漏洞的东西,还有就是有些IDC们使用的虚拟主机管理软件。

4、关闭删除所有可疑的系统帐号,尤其是那些具有高权限的系统账户!重新为所有网站目录配置权限,关闭可执行的目录权限,对图片和非脚本目录做无权限处理。

5、完成以上步骤后,你需要把管理员账户密码,以及数据库管理密码,特别是sql的sa密码,还有mysql的root密码,要知道,这些账户都是具有特殊权限的,黑客可以通过他们得到系统权限!

6、Web服务器一般都是通过网站漏洞入侵的,你需要对网站程序进行检查(配合上面的日志分析),对所有网站可以进行上传、写入shell的地方进行严格的检查和处理。如果不能完全确认攻击者通过哪些攻击方式进行攻击,那就重装系统,彻底清除掉攻击源。

怎么样才能写出安全的Java代码?不被黑客攻击?

在本文中,我们讨论了对付 13 种不同静态暴露的技巧。对于每种暴露,我们解释了不处理这些安全性问题所造成的影响。我们还为您推荐了一些准则,要开发不受这些静态安全性暴露威胁的、健壮且安全的 Java 应用程序,您应该遵循这些准则。一有合适的时机,我们就提供代码样本(既有暴露的代码也有无暴露的代码)。

对付高严重性暴露的技巧

请遵循下列建议以避免高严重性静态安全性暴露:

限制对变量的访问

让每个类和方法都成为 final,除非有足够的理由不这样做

不要依赖包作用域

使类不可克隆

使类不可序列化

使类不可逆序列化

避免硬编码敏感数据

查找恶意代码

限制对变量的访问

如果将变量声明为 public,那么外部代码就可以操作该变量。这可能会导致安全性暴露。

影响

如果实例变量为 public,那么就可以在类实例上直接访问和操作该实例变量。将实例变量声明为 protected 并不一定能解决这一问题:虽然不可能直接在类实例基础上访问这样的变量,但仍然可以从派生类访问这个变量。

清单 1 演示了带有 public 变量的代码,因为变量为 public 的,所以它暴露了。

清单 1. 带有 public 变量的代码

class Test {

public int id;

protected String name;

Test(){

id = 1;

name = "hello world";

}

//code

}

public class MyClass extends Test{

public void methodIllegalSet(String name){

this.name = name; // this should not be allowed

}

public static void main(String[] args){

Test obj = new Test();

obj.id = 123; // this should not be allowed

MyClass mc = new MyClass();

mc.methodIllegalSet("Illegal Set Value");

}

}

建议

一般来说,应该使用取值方法而不是 public 变量。按照具体问题具体对待的原则,在确定哪些变量特别重要因而应该声明为 private 时,请将编码的方便程度及成本同安全性需要加以比较。清单 2 演示了以下列方式来使之安全的代码:

清单 2. 不带有 public 变量的代码

class Test {

private int id;

private String name;

Test(){

id = 1;

name = "hello world";

}

public void setId(int id){

this.id = id;

}

public void setName(String name){

this.name = name;

}

public int getId(){

return id;

}

public String getName(){

return name;

}

}

让每个类和方法都为 final

不允许扩展的类和方法应该声明为 final。这样做防止了系统外的代码扩展类并修改类的行为。

影响

仅仅将类声明为非 public 并不能防止攻击者扩展类,因为仍然可以从它自己的包内访问该类。

建议

让每个类和方法都成为 final,除非有足够的理由不这样做。按此建议,我们要求您放弃可扩展性,虽然它是使用诸如 Java 语言之类的面向对象语言的主要优点之一。在试图提供安全性时,可扩展性却成了您的敌人;可扩展性只会为攻击者提供更多给您带来麻烦的方法。

不要依赖包作用域

没有显式地标注为 public、private 或 protected 的类、方法和变量在它们自己的包内是可访问的。

影响

如果 Java 包不是封闭的,那么攻击者就可以向包内引入新类并使用该新类来访问您想保护的内容。诸如 java.lang 之类的一些包缺省是封闭的,一些 JVM 也让您封闭自己的包。然而,您最好假定包是不封闭的。

建议

从软件工程观点来看,包作用域具有重要意义,因为它可以阻止对您想隐藏的内容进行偶然的、无意中的访问。但不要依靠它来获取安全性。应该将类、方法和变量显式标注为 public、private 或 protected 中适合您特定需求的那种。

使类不可克隆

克隆允许绕过构造器而轻易地复制类实例。

影响

即使您没有有意使类可克隆,外部源仍然可以定义您的类的子类,并使该子类实现 java.lang.Cloneable。这就让攻击者创建了您的类的新实例。拷贝现有对象的内存映象生成了新的实例;虽然这样做有时候是生成新对象的可接受方法,但是大多数时候是不可接受的。清单 3 说明了因为可克隆而暴露的代码:

清单 3. 可克隆代码

class MyClass{

private int id;

private String name;

public MyClass(){

id=1;

name="HaryPorter";

}

public MyClass(int id,String name){

this.id=id;

this.name=name;

}

public void display(){

System.out.println("Id ="+id+"

"+"Name="+name);

}

}

// hackers code to clone the user class

public class Hacker extends MyClass implements Cloneable {

public static void main(String[] args){

Hacker hack=new Hacker();

try{

MyClass o=(MyClass)hack.clone();

o.display();

}

catch(CloneNotSupportedException e){

e.printStackTrace();

}

}

}

建议

要防止类被克隆,可以将清单 4 中所示的方法添加到您的类中:

清单 4. 使您的代码不可克隆

public final Object clone()

throws java.lang.CloneNotSupportedException{

throw new java.lang.CloneNotSupportedException();

}

如果想让您的类可克隆并且您已经考虑了这一选择的后果,那么您仍然可以保护您的类。要做到这一点,请在您的类中定义一个为 final 的克隆方法,并让它依赖于您的一个超类中的一个非 final 克隆方法,如清单 5 中所示:

清单 5. 以安全的方式使您的代码可克隆

public final Object clone()

throws java.lang.CloneNotSupportedException {

super.clone();

}

类中出现 clone() 方法防止攻击者重新定义您的 clone 方法。

使类不可序列化

序列化允许将类实例中的数据保存在外部文件中。闯入代码可以克隆或复制实例,然后对它进行序列化。

影响

序列化是令人担忧的,因为它允许外部源获取对您的对象的内部状态的控制。这一外部源可以将您的对象之一序列化成攻击者随后可以读取的字节数组,这使得攻击者可以完全审查您的对象的内部状态,包括您标记为 private 的任何字段。它也允许攻击者访问您引用的任何对象的内部状态。

建议

要防止类中的对象被序列化,请在类中定义清单 6 中的 writeObject() 方法:

清单 6. 防止对象序列化

private final void writeObject(ObjectOutputStream out)

throws java.io.NotSerializableException {

throw new java.io.NotSerializableException("This object cannot

be serialized");

}

通过将 writeObject() 方法声明为 final,防止了攻击者覆盖该方法。

使类不可逆序列化

通过使用逆序列化,攻击者可以用外部数据或字节流来实例化类。

影响

不管类是否可以序列化,都可以对它进行逆序列化。外部源可以创建逆序列化成类实例的字节序列。这种可能为您带来了大量风险,因为您不能控制逆序列化对象的状态。请将逆序列化作为您的对象的另一种公共构造器 — 一种您无法控制的构造器。

建议

要防止对对象的逆序列化,应该在您的类中定义清单 7 中的 readObject() 方法:

清单 7. 防止对象逆序列化

private final void readObject(ObjectInputStream in)

throws java.io.NotSerializableException {

throw new java.io.NotSerializableException("This object cannot

be deserialized");

}

通过将该方法声明为 final,防止了攻击者覆盖该方法。

避免硬编码敏感数据

您可能会尝试将诸如加密密钥之类的秘密存放在您的应用程序或库的代码。对于你们开发人员来说,这样做通常会把事情变得更简单。

影响

任何运行您的代码的人都可以完全访问以这种方法存储的秘密。没有什么东西可以防止心怀叵测的程序员或虚拟机窥探您的代码并了解其秘密。

建议

可以以一种只可被您解密的方式将秘密存储在您代码中。在这种情形下,秘密只在于您的代码所使用的算法。这样做没有多大坏处,但不要洋洋得意,认为这样做提供了牢固的保护。您可以遮掩您的源代码或字节码 — 也就是,以一种为了解密必须知道加密格式的方法对源代码或字节码进行加密 — 但攻击者极有可能能够推断出加密格式,对遮掩的代码进行逆向工程从而揭露其秘密。

这一问题的一种可能解决方案是:将敏感数据保存在属性文件中,无论什么时候需要这些数据,都可以从该文件读取。如果数据极其敏感,那么在访问属性文件时,您的应用程序应该使用一些加密/解密技术。

查找恶意代码

从事某个项目的某个心怀叵测的开发人员可能故意引入易受攻击的代码,打算日后利用它。这样的代码在初始化时可能会启动一个后台进程,该进程可以为闯入者开后门。它也可以更改一些敏感数据。

这样的恶意代码有三类:

类中的 main 方法

定义过且未使用的方法

注释中的死代码

影响

入口点程序可能很危险而且有恶意。通常,Java 开发人员往往在其类中编写 main() 方法,这有助于测试单个类的功能。当类从测试转移到生产环境时,带有 main() 方法的类就成为了对应用程序的潜在威胁,因为闯入者将它们用作入口点。

请检查代码中是否有未使用的方法出现。这些方法在测试期间将会通过所有的安全检查,因为在代码中不调用它们 — 但它们可能含有硬编码在它们内部的敏感数据(虽然是测试数据)。引入一小段代码的攻击者随后可能调用这样的方法。

避免最终应用程序中的死代码(注释内的代码)。如果闯入者去掉了对这样的代码的注释,那么代码可能会影响系统的功能性。

可以在清单 8 中看到所有三种类型的恶意代码的示例:

清单 8. 潜在恶意的 Java 代码

public void unusedMethod(){

// code written to harm the system

}

public void usedMethod(){

//unusedMethod(); //code in comment put with bad intentions,

//might affect the system if uncommented

// int x = 100;

// x=x+10; //Code in comment, might affect the

//functionality of the system if uncommented

}

建议

应该将(除启动应用程序的 main() 方法之外的)main() 方法、未使用的方法以及死代码从应用程序代码中除去。在软件交付使用之前,主要开发人员应该对敏感应用程序进行一次全面的代码评审。应该使用“Stub”或“dummy”类代替 main() 方法以测试应用程序的功能。

对付中等严重性暴露的技巧

请遵循下列建议以避免中等严重性静态安全性暴露:

不要依赖初始化

不要通过名称来比较类

不要使用内部类

不要依赖初始化

您可以不运行构造器而分配对象。这些对象使用起来不安全,因为它们不是通过构造器初始化的。

影响

在初始化时验证对象确保了数据的完整性。

例如,请想象为客户创建新帐户的 Account 对象。只有在 Account 期初余额大于 0 时,才可以开设新帐户。可以在构造器里执行这样的验证。有些人未执行构造器而创建 Account 对象,他可能创建了一个具有一些负值的新帐户,这样会使系统不一致,容易受到进一步的干预。

建议

在使用对象之前,请检查对象的初始化过程。要做到这一点,每个类都应该有一个在构造器中设置的私有布尔标志,如清单 9 中的类所示。在每个非 static 方法中,代码在任何进一步执行之前都应该检查该标志的值。如果该标志的值为 true,那么控制应该进一步继续;否则,控制应该抛出一个例外并停止执行。那些从构造器调用的方法将不会检查初始化的变量,因为在调用方法时没有设置标志。因为这些方法并不检查标志,所以应该将它们声明为 private 以防止用户直接访问它们。

清单 9. 使用布尔标志以检查初始化过程

public class MyClass{

private boolean initialized = false;

//Other variables

public MyClass (){

//variable initialization

method1();

initialized = true;

}

private void method1(){ //no need to check for initialization variable

//code

}

public void method2(){

try{

if(initialized==true){

//proceed with the business logic

}

else{

throw new Exception("Illegal State Of the object");

}

}catch(Exception e){

e.printStackTrace();

}

}

}

如果对象由逆序列化进行初始化,那么上面讨论的验证机制将难以奏效,因为在该过程中并不调用构造器。在这种情况下,类应该实现 ObjectInputValidation 接口:

清单 10. 实现 ObjectInputValidation

interface java.io.ObjectInputValidation {

public void validateObject() throws InvalidObjectException;

}

所有验证都应该在 validateObject() 方法中执行。对象还必须调用 ObjectInputStream.RegisterValidation() 方法以为逆序列化对象之后的验证进行注册。 RegisterValidation() 的第一个参数是实现 validateObject() 的对象,通常是对对象自身的引用。注:任何实现 validateObject() 的对象都可能充当对象验证器,但对象通常验证它自己对其它对象的引用。RegisterValidation() 的第二个参数是一个确定回调顺序的整数优先级,优先级数字大的比优先级数字小的先回调。同一优先级内的回调顺序则不确定。

当对象已逆序列化时,ObjectInputStream 按照从高到低的优先级顺序调用每个已注册对象上的 validateObject()。

不要通过名称来比较类

有时候,您可能需要比较两个对象的类,以确定它们是否相同;或者,您可能想看看某个对象是否是某个特定类的实例。因为 JVM 可能包括多个具有相同名称的类(具有相同名称但却在不同包内的类),所以您不应该根据名称来比较类。

影响

如果根据名称来比较类,您可能无意中将您不希望授予别人的权利授予了闯入者的类,因为闯入者可以定义与您的类同名的类。

例如,请假设您想确定某个对象是否是类 com.bar.Foo 的实例。清单 11 演示了完成这一任务的错误方法:

清单 11. 比较类的错误方法

if(obj.getClass().getName().equals("Foo")) // Wrong!

// objects class is named Foo

}else{

// object's class has some other name

}

建议

在那些非得根据名称来比较类的情况下,您必须格外小心,必须确保使用了当前类的 ClassLoader 的当前名称空间,如清单 12 中所示:

清单 12. 比较类的更好方法

if(obj.getClass() == this.getClassLoader().loadClass("com.bar.Foo")){

// object's class is equal to

//the class that this class calls "com.bar.Foo"

}else{

// object's class is not equal to the class that

// this class calls "com.bar.Foo"

}

然而,比较类的更好方法是直接比较类对象看它们是否相等。例如,如果您想确定两个对象 a 和 b 是否属同一个类,那么您就应该使用清单 13 中的代码:

清单 13. 直接比较对象来看它们是否相等

if(a.getClass() == b.getClass()){

// objects have the same class

}else{

// objects have different classes

}

尽可能少用直接名称比较。

不要使用内部类

Java 字节码没有内部类的概念,因为编译器将内部类转换成了普通类,而如果没有将内部类声明为 private,则同一个包内的任何代码恰好能访问该普通类。

影响

因为有这一特性,所以包内的恶意代码可以访问这些内部类。如果内部类能够访问括起外部类的字段,那么情况会变得更糟。可能已经将这些字段声明为 private,这样内部类就被转换成了独立类,但当内部类访问外部类的字段时,编译器就将这些字段从专用(private)的变为在包(package)的作用域内有效的。内部类暴露了已经够糟糕的了,但更糟糕的是编译器使您将某些字段成为 private 的举动成为徒劳。

建议 如果能够不使用内部类就不要使用内部类。

对付低严重性暴露的技巧

请遵循下列建议以避免低严重性静态安全性暴露:

避免返回可变对象

检查本机方法

避免返回可变对象

Java 方法返回对象引用的副本。如果实际对象是可改变的,那么使用这样一个引用调用程序可能会改变它的内容,通常这是我们所不希望见到的。

影响

请考虑这个示例:某个方法返回一个对敏感对象的内部数组的引用,假定该方法的调用程序不改变这些对象。即使数组对象本身是不可改变的,也可以在数组对象以外操作数组的内容,这种操作将反映在返回该数组的对象中。如果该方法返回可改变的对象,那么事情会变得更糟;外部实体可以改变在那个类中声明的 public 变量,这种改变将反映在实际对象中。

清单 14 演示了脆弱性。getExposedObj() 方法返回了 Exposed 对象的引用副本,该对象是可变的:

清单 14. 返回可变对象的引用副本

class Exposed{

private int id;

private String name;

public Exposed(){

}

public Exposed(int id, String name){

this.id = id;

this.name = name;

}

public int getId(){

return id;

}

public String getName(){

return name;

}

public void setId(int id){

this.id=id;

}

public void setName(String name){

this.name = name;

}

public void display(){

System.out.println("Id = "+ id + " Name = "+ name);

}

}

public class Exp12{

private Exposed exposedObj = new Exposed(1,"Harry Porter");

public Exposed getExposedObj(){

return exposedObj; //returns a reference to the object.

}

public static void main(String[] args){

Exp12 exp12 = new Exp12();

exp12.getExposedObj().display();

Exposed exposed = exp12.getExposedObj();

exposed.setId(10);

exposed.setName("Hacker");

exp12.getExposedObj().display();

}

}

建议

如果方法返回可改变的对象,但又不希望调用程序改变该对象,请修改该方法使之不返回实际对象而是返回它的副本或克隆。要改正清单 14 中的代码,请让它返回 Exposed 对象的副本,如清单 15 中所示:

清单 15. 返回可变对象的副本

public Exposed getExposedObj(){

return new Exposed(exposedObj.getId(),exposedObj.getName());

}

或者,您的代码也可以返回 Exposed 对象的克隆。

检查本机方法

本机方法是一种 Java 方法,其实现是用另一种编程语言编写的,如 C 或 C++。有些开发人员实现本机方法,这是因为 Java 语言即使使用即时(just-in-time)编译器也比许多编译过的语言要慢。其它人需要使用本机代码是为了在 JVM 以外实现特定于平台的功能。

影响

使用本机代码时,请小心,因为对这些代码进行验证是不可能的,而且本机代码可能潜在地允许 applet 绕过通常的安全性管理器(Security Manager)和 Java 对设备访问的控制。

建议

如果非得使用本机方法,那么请检查这些方法以确定:

它们返回什么

它们获取什么作为参数

它们是否绕过安全性检查

它们是否是 public、private 等等

它们是否含有绕过包边界从而绕过包保护的方法调用

结束语

编写安全 Java 代码是十分困难的,但本文描述了一些可行的实践来帮您编写安全 Java 代码。这些建议并不能解决您的所有安全性问题,但它们将减少暴露数目。最佳软件安全性实践可以帮助确保软件正常运行。安全至关重要和高可靠系统设计者总是花费大量精力来分析和跟踪软件行为。只有通过将安全性作为至关紧要的系统特性来对待 — 并且从一开始就将它构建到应用程序中,我们才可以避免亡羊补牢似的、修修补补的安全性方法。

参考资料

请通过单击文章顶部或底部的讨论来参加本文的论坛。

了解关于 Java 安全性 API 的更多知识。

developerWorks 安全专题上通常含有有关计算机安全性的优秀资源。

Larry Koved、 Anthony J. Nadalin、Don Neal 和 Tim Lawson 合作编写的 “The evolution of Java security”(developerWorks,1998 年)对 Java 语言的安全性模型早期开发进行了深入探讨。

Sing Li 在他的 Java 安全性系列文章(由两部分组成的)(developerWorks, 2001 年 2 月)中向开发人员显示:尽管社区可能不得不重新考虑 Java 2 中的安全性设计,还是出现了只对开发人员有帮助,可以满足他们的需求的一致的进展:

第一部分

第二部分

John Viega、Tom Mutdosch、 Gary McGraw 和 Ed Felten 合著的 “Statically scanning Java code for security vulnerabilities” (IEEE Software,2000 年 9 月)介绍了一种 Java 工具,可以使用该工具来检查您的 Java 代码中的安全性漏洞。

G. McGraw 和 E. Felten 合作编写的 Securing Java: Getting Down to Business with Mobile Code(John Wiley 和 Sons,1998 年)深入涵盖了 Java 安全性。(文档是 PDF 格式的。)

定期检查 IBM 研究 Java 安全页面以便 IBM 在安全性领域的创新有重要发展时能够跟踪这一创新。

如果您的 Java 代码运行在 S/390 系统上,那么您将需要查阅 S/390 Java 安全页面以获取额外的信息。

关于作者

Bijaya Nanda Sahu 是就职于印度 IBM Global Services 的软件工程师。他从事过各种因特网技术和框架(J2EE、WSBCC、JADE)、 WebSphere 相关技术、UML 和 OOAD 方面的工作。目前,他从事因特网银行安全性问题方面的工作,重点在 WebSphere Application Server 和 Portal Server 上。可以通过 bijaya.sahu@in.ibm.com 和他联系

0条大神的评论

发表评论