java安全编码指南之:基础篇

简介: 作为一个程序员,只是写出好用的代码是不够的,我们还需要考虑到程序的安全性。在这个不能跟陌生人说话世界,扶老奶奶过马路都是一件很困难的事情。那么对于程序员来说,尤其是对于开发那种对外可以公开访问的网站的程序员,要承受的压力会大很多。 任何人都可以访问我们的系统,也就意味着如果我们的系统不够健壮,或者有些漏洞,恶意攻击者就会破门而入,将我们辛辛苦苦写的程序蹂躏的体无完肤。 所以,安全很重要,今天本文将会探讨一下java中的安全编码指南。

简介

作为一个程序员,只是写出好用的代码是不够的,我们还需要考虑到程序的安全性。在这个不能跟陌生人说话世界,扶老奶奶过马路都是一件很困难的事情。那么对于程序员来说,尤其是对于开发那种对外可以公开访问的网站的程序员,要承受的压力会大很多。

任何人都可以访问我们的系统,也就意味着如果我们的系统不够健壮,或者有些漏洞,恶意攻击者就会破门而入,将我们辛辛苦苦写的程序蹂躏的体无完肤。

所以,安全很重要,今天本文将会探讨一下java中的安全编码指南。

java平台本身的安全性

作为一个强类型语言,java平台本身已经尽可能的考虑到了安全性的,为我们屏蔽了大多数安全性的细节。

比如可以为不同级别权限的代码提供受限的执行环境。 java程序是类型安全的,并且在运行时提供了自动内存管理和数组边界检查,Java会尽可能的及早发现程序中的问题,从而使Java程序具有很高的抵抗堆栈破坏的能力。

尽管Java安全体系结构在许多情况下可以帮助保护用户和系统免受恶意代码或行为不当的攻击,但它无法防御可信任代码中发生的错误。也就说如果是用户本身代码的漏洞,java安全体系是无法进行判断的。

这些错误可能会绕过java本身的安全体系结构。在严重的情况下,可能会执行本地程序或禁用Java安全性。从而会被用来从计算机和Intranet窃取机密数据,滥用系统资源,阻止计算机的有用操作,协助进一步的攻击以及许多其他恶意活动。

所以,最大的安全在程序员本身,不管外部机制如何强大,如果核心的程序员出了问题,那么一切都将归于虚无。

接下来,我们看下java程序员应该遵循一些什么行为准则,来保证程序的安全性呢?

安全第一,不要写聪明的代码

我们可能会在很多教科书甚至是JDK的源代码中,看到很多让人惊叹的代码写法,如果你真的真的明白你在做什么,那么这样写没什么问题。但是很多情况下我们并不是很了解这样写的原理,甚至不知道这样写会出现什么样的问题。

并且现代系统是一个多人协作的过程,如果你写了这样的聪明代码,很有可能别人看不懂,最后导致未知的系统问题。

给大家举个例子:

:(){:|:&};:

上面是一个shell下面的fork炸弹,如果你在shell下面运行上面的代码,几秒之后系统就会宕机或者运行出错。

怎么分析上面的代码呢?我们把代码展开:

:()
{:|:&
};
:

还是不明白? 我们把:替换成函数名:

fork()
{fork|fork&
};
fork
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

上面的代码就是无限的fork进程,通过几何级数的增长,最后导致程序崩溃。

java设计的很多大神把他们跳跃般的思想写到了JDK源代码里面,大神们的思想经过了千锤百炼,并且JDK是Java的核心,里面的代码再优化也不为过。

但是现在硬件技术的发展,代码级别的优化可能作用已经比较少了。为了避免出现不可知的安全问题,还是建议大家编写一眼就能看出逻辑的代码。虽然可能不是那么快,但是安全性有了保证。除非你真的知道你在做什么。

在代码设计之初就考虑安全性

安全性应该是一个在编写代码过程中非常重要的标准,我们在设计代码的时候就应该考虑到相关的安全性问题,否则后面重构起来会非常费事。

举个例子:

        public final class SensitiveClass {private final Behavior behavior;// Hide constructor.private SensitiveClass(Behavior behavior) {this.behavior = behavior;}// Guarded construction.public static SensitiveClass newSensitiveClass(Behavior behavior) {// ... validate any arguments ...// ... perform security checks ...return new SensitiveClass(behavior);}}

上面的例子中我们使用了final关键字来防止我们的某些关键类被继承扩展。因为没有扩展性,所以安全性判断会更加容易。

同时,java提供了SecurityManager和一系列的Permission类,通过合理的配置,我们可以有效的控制java程序的访问权限。

避免重复的代码

和重复代码相关的一个关键词就是重构。为什么会出现重复代码呢?

很简单,最开始我们在实现一个功能的时候写了一段代码逻辑。结果后面还有一个方法要使用这段代码逻辑。然后我们为了图方便,就把代码逻辑拷贝过去了。

看起来问题好像解决了。但是一旦这段业务逻辑要修改,那可就是非常麻烦的一件事情。因为我们需要找到程序中所有出现这段代码的地方,然后一个一个的修改。

为什么不把这段代码提取出来,做成一个单独的方法来供其他的方法调用呢?这样即使后面需要修改,也只用修改一处地方即可。

在现实的工作中,我们经常会遇到这种问题,尤其是那种年久失修的代码,大家都不敢修改,因为牵一发而动全身。往往是修改了这边忘记了那边,最后导致bug重重。

限制权限

JDK专门提供了一个SecurityManager类,来显示的对安全性进行控制,我们看下SecurityManager是怎么使用的:

SecurityManager security = System.getSecurityManager();if (security != null) {security.checkXXX(argument, ...);}

SecurityManager提供了一系列的check方法,来对权限进行控制。

权限分为以下类别:文件、套接字、网络、安全性、运行时、属性、AWT、反射和可序列化。管理各种权限类别的类是 :
  java.io.FilePermission、
  java.net.SocketPermission、
  java.net.NetPermission、
  java.security.SecurityPermission、
  java.lang.RuntimePermission、
  java.util.PropertyPermission、
  java.awt.AWTPermission、
  java.lang.reflect.ReflectPermission
  java.io.SerializablePermission

JDK本身已经使用了很多这些权限控制的代码。比如说我们最常用的File:

    public boolean canRead() {SecurityManager security = System.getSecurityManager();if (security != null) {security.checkRead(path);}if (isInvalid()) {return false;}return fs.checkAccess(this, FileSystem.ACCESS_READ);}

上面是File类的canRead方法,我们会首先去判断是否配置了SecurityManager,如果配置了,则去检查是否可以read。

如果我们在写代码中,遇到文件、套接字、网络、安全性、运行时、属性、AWT、反射和可序列化相关的操作时,也可以考虑使用SecurityManager来进行细粒度的权限控制。

构建可信边界

什么是可信边界呢?边界主要起拦截作用,边界里边的我们可以信任,边界外边的我们就不能信任了。

对于不能信任的外边界请求,我们需要进行足够的安全访问控制。

比如说web客户端来访问web服务器。web客户端是在全球各地的,各种环境都有,并且是不可控的,所以web客户端访问web服务器端的请求需要进行额外的安全控制。

而web服务器访问业务服务器又是不同的,因为web服务器是我们自己控制的,所以安全程度相对较高,我们需要针对不同的可信边界做不同的控制。

封装

封装(Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。通过对接口进行访问控制,可以严格的包含类中的数据和方法。

并且封装可以减少耦合,并且隐藏实现细节。

写文档

最后一项也是非常非常重要的一项就是写文档。为什么接别人的老项目那么痛苦,为什么读源代码那么困难。根本的原因就是没有写文档。

如果不写文档,可能你自己写的代码过一段时间之后也不知道为什么当时这样写了。

所以,写文档很重要。

 

原文链接
本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Gartner:70%新应用由低代码开发,AI热潮后小数据崛起

作者 | 宋慧 出品 | CSDN云计算 头图 | 付费下载于东方IC 国际研究机构Gartner在近日发布了2021年十大数据和分析趋势。纵观这十个趋势,基本可以归纳为三类主题,分别是: 加速数据和分析变革:运用AI创新、经过改进的可组合性以及…

Sentinel 1.8.0 年度版本发布,熔断降级重构升级!

在经过数月的打磨后,Sentinel 1.8.0 版本正式发布!该版本是本年度最重要的版本之一,包含大量特性改进与 bug 修复,尤其是针对熔断降级特性的完善升级(支持任意统计时长、慢调用比例降级策略、熔断器事件监听&#xff0…

清华大学-美团数字生活联合研究院成立

转载自清华新闻网 4月12日,清华大学-美团数字生活联合研究院(以下简称“清华美团数字生活研究院”)揭牌仪式暨管委会第一次会议在清华大学举行。仪式上,清华大学副校长杨斌与美团联合创始人王慧文共同为联合研究院揭牌。 杨斌表…

SpringCloud 应用在 Kubernetes 上的最佳实践 — 高可用(熔断)

前言 阿里巴巴十多年的双十一,锤炼出来了一套业界领先的高可用技术,有一些已经商业化(云产品 PTS、AHAS),也有的开源了如:Sentinel、ChaosBlade。我们这一系列的高可用章节也主要介绍这方面的内容。今天介…

shadingjdbc实战分表分库

文章目录一、问题汇总1. 水平与垂直拆分之间的区别?2. 单表达到多大量开始进行分库分表?3. 基于客户端与服务端实现分表分库区别?4. 数据库分表分库策略有哪些?5. 自定义范围分表算法实现分表?二、整合ShardingSphere实现分表2.1…

阿里云机器学习怎么玩?这本新手入门指南揭秘了!

想知道我是怎样免费在阿里云上玩机器学习的吗? 不慌,这就告诉你答案~ 它来了--阿里云向个人免费开放云端深度学习开发环境DSW(DataScienceWorkshop),还有免费GPU资源可以使用,实验的数据还会免费保存30天&a…

华为庞鑫:闪存3.0时代,四大变化激发全闪存数据中心潜能释放

从2005年到2019年间,中国数字经济总体规模由2.6万亿元增加至35.8万亿元,数字经济在GDP的占比也由14.2%提升至36.2%。随着数字经济蓬勃发展,数据也成为当之无愧的关键生产要素,是基础性资源和战略性资源。数据洪流的到来进一步驱动…

基于RabbitMQ订单未支付30分钟自动取消

文章目录一、原理实现1. 超时消费流程图2. 死信队列的架构原理3. 订单超时30分钟实现原理二、核心代码实战2.1. 记录订单待支付数据2.2. 超时消费者监听2.3. 订单核对校验一、原理实现 1. 超时消费流程图 2. 死信队列的架构原理 相同点: 死信队列和普通队列区别不…

蚂蚁mPaaS:有人修建高楼,有人重构城市

简介: 纵览这时代的先声,在高楼之巅,在海天之外。 2018年2月,春运拉开序幕。 这是人类史上最大规模的迁徙活动,3.82亿人坐进车厢,被31万趟车次送往不同的目的地。如果有一台摄影机从高空对准中国大地&…

全场景闪存加速、全场景数据保护,华为助力医院实现智能化转型

数字经济时代的来临,是影响当今医疗健康服务领域最重要的大趋势。在这种大背景下,新时期的智能医疗必将在医疗行业内掀起一阵浪潮。2020年,新冠疫情的肆虐势必推进浪潮的提前到来。 首都医科大学附属北京同仁医院,始建于1886年&a…

从Cloudflare事件,看DNS服务的重要性

简介: 美国时间7月17日,美国知名的网络安全服务提供商Cloudflare,出现了突发网络服务故障。通过这个事件,和大家聊聊关于网络安全稳定的思考,以及稳定、安全的DNS服务的重要性。 7.17事件 美国时间7月17日下午&#…

基于Redis订单未支付30分钟自动取消

文章目录一、原理实现1. 超时消费流程图2. 订单超时30分钟实现原理二、核心代码实战2.1. 记录订单待支付数据2.2. redis配置2.3. 超时消费者监听一、原理实现 1. 超时消费流程图 2. 订单超时30分钟实现原理 ①用户下单之后,投递一个订单号码存放到redis服务端&…

面向 K8s 设计误区

作者 | 姬望来源 | 阿里巴巴中间件头图 | 下载于视觉中国K8s 设计模式Kubernetes 是一个具有普遍意义的容器编排工具,它提供了一套基于容器构建分布式系统的基础依赖,其意义等同于 Linux 在操作系统中的地位,可以认为是分布式的操作系统。自定…

安装docker-compose插件

文章目录一、安装docker-compose插件1. 下载docker-compose插件2. 赋予权限3. 验证一、安装docker-compose插件 1. 下载docker-compose插件 curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/…

突围数字化转型,让特步同比增长24.8%的全渠道中台

简介: 多年前,曾有媒体向丁水波提问:“对于你个人来说,转型过程中最痛苦的部分是什么?”“最关键的是市场意识的转变。耳听为虚眼见为实,做起来给外界看到了,他们才会明白和接受。很多东西得做完…

赠书 | 什么是 Knative?

作者 | 李志伟、游杨来源 | 华章计算机头图 | 下载于视觉中国✎ 导读 什么是Knative?本文将对Knative的产生背景及发展历程,架构设计,受众群体等做详细介绍。Knative是由谷歌发起,有Pivotal、IBM、Red Hat等公司共同参与开发的Ser…

canal kafka 实现mysql与es/redis 数据同步

文章目录一、原理实现1. 方案设计流程图2. 实现原理二、mysql开启binlog模式2.1. 配置my.ini2.2. 重启mysql服务2.3. 验证binlog模式2.4. 创建canal账号2.5. 账号验证三、docker-compose环境搭建3.1. 环境总览3.2. 编写docker-compose.yml3.3. 安装docker-compose3.4. 构建环境…

免费下载!《阿里工程师的自我修养》公开10位阿里大牛解决问题的思维方式

简介: 今天,阿里技术公布一波阿里P8、P9技术大牛的思维模型,将他们的思维模式呈现出来。你可以在阿里资深专家职业生涯的真切感悟中,找到应对危机的最佳方法。《阿里工程师的自我修养》现已正式公开,可免费下载阅读。 …

云原生时代消息中间件的演进路线

简介: 本文整理自作者于 2020 年云原生微服务大会上的分享《云原生时代的消息中间件演进》,主要探讨了传统的消息中间件如何持续进化为云原生的消息服务。 作者 | 周礼(不铭) 阿里巴巴集团消息中间件架构师 导读:本文…

四大“化学融合”、两大核心平台能力,华为首次系统解读OneStorage

4月14日,在2021华为全球分析师大会期间,华为举办数据存储专场Session,面向全球分析师全面解读下一代数据存储解决方案OneStorage,引领数据存储产业迈向全场景智能和多云融合。同时,在此期间华为首次向业界系统性地诠释…