龙空技术网

软件开发安全编码规范

枫桥夜航 143

前言:

目前看官们对“java语言编码标准标识是什么”都比较重视,各位老铁们都需要知道一些“java语言编码标准标识是什么”的相关文章。那么小编在网摘上网罗了一些关于“java语言编码标准标识是什么””的相关知识,希望看官们能喜欢,姐妹们一起来了解一下吧!

1、 安全规范

1 安全编码原则

1. 保持简单,程序只实现指定的功能。

2. 坚持最小权限,把可能造成的危害降到最低。

3. 默认不信任,采用白名单机制,只放行已知的操作。

4. 永远不要相信用户的输入,对所有输入进行前台和后台两次检查。

2 常见WEB潜在问题

输入验证:嵌入到查询字符串、表单字段、cookie 和 HTTP 头中的恶意字符串的攻击。这些攻击包括命令执行、跨站点脚本(XSS)、SQL 注入和缓冲区溢出攻击。身份验证:标识欺骗、密码破解、特权提升和未经授权的访问。授权验证:访问保密数据或受限数据、篡改数据以及执行未经授权的操作。配置管理:对管理界面进行未经授权的访问、具有更新配置数据的能力以及对用户帐户和帐户配置文件进行未经授权的访问。敏感数据:泄露保密信息以及篡改数据。会话管理:捕捉会话标识符,从而导致会话劫持及标识欺骗。加密管理:访问保密数据或帐户凭据,或二者均能访问。参数操作:路径遍历攻击、命令执行以及绕过访问控制机制,从而导致信息泄漏、特权提升和拒绝服务。异常管理:拒绝服务和敏感的系统级详细信息的泄漏。审核和记录:不能发现入侵迹象、不能验证用户操作,以及在诊断时出现困难。

3 基本开发安全规范3.1 跨站点脚本(XSS)防范

XSS的类型:反射型XSS、存储型XSS、DOM型XSS。

跨站点脚本防范的基本原则:

1. 一切的输入/输出都是有害的,不要信任任何输入/输出数据。

2. 所有传递过程都不能保障无侵入,执行前、存储前、显示前都要进行"数据清洗"。

3. 所有的数据校验、处理工作要在前端和服务器端两次进行。

4. 目前所有的XSS通过com.keegoo.core.util.XSSUtil来过滤。

DOM-based XSS的防范当操作页面中DOM对象的时候,要对其输入的参数进行处理,防止XSS的注入。可采用escape、encodeURI、encodeURIComponent或自定义方法进行处理。示例:

Window.location=encodeURI(";);

对输入/输出进行Encode 将输入/输出进行转义成HTML实体编码(ISO 8859-1 Latin1)或其他编码,使得其在浏览器中不可自动执行。

不要在html元素和属性中使用未经转义的不安全内容。

3.2 防SQL注入规范

1. 防SQL注入基本原则:所有用户输入都必须进行合法性校验。所有数据库SQL操作必须参数化。

2. 回收开发人员等操作生产库权限:减少开发人员、非DBA操作生产库的权限;数据库数据查询要有权限分级和审核。

3. 尽量使用PreparedStatement代替Statement,一方面,在大多数情况下,使用PreparedStatement的性能将优于使用Statement,另外一方面,可以最大限度的减少SQL注入发生的可能行。

4. 用户提交的数据都应该做合法性校验,避免用户输入',"",-,%,#,&,|,@,+等有可能导致SQL注入的危险字符给系统造成危害。

3.3 页面组件安全防范

1. 页面标签必须关闭,属性值必须加引号。在页面中使用的标签不关闭,属性值不加引号往往成为被攻击点,攻击者很容易的利用这些漏洞进行注入。避免这些漏洞的出现可以提高被攻击的可能。

2. Form提交方式必须选用POST。Form默认的提交方式是Get,这种方式将表单中数据的按照variable=value的形式,使用"?"添加至Action所指向的URL后面,各个变量之间使用"&"连接。所要传递的信息量除受URL长度限制之外,信息内容都显示暴露。

在使用Form的时候必须将提交方式置为POST。示例:

<form action="…" method="post" target="_blank">…</form>

3. 所有的非ASCII字符在URL中传递时都需要按照协商好的编码方式做URL编码。推荐使用encodeURI、encodeURIComponent或者自定义encode实现。encodeURI、encodeURIComponent默认都返回UTF8编码的URL,区别在于encodeURI方法不会对下列字符进行编码: ":"、"/"、";" 和 "?"。而encodeURIComponent则会对这些字符进行编码处理。

4. 尽量使用对象的innerText,不要使用innerHtml属性。对象的innerText属性默认会对输入的数据进行encode,使得如果数据的数据还有html可执行标记时不会直接执行,而如果使用innerHtml属性的话不会保障。

5. 输入框设置最大长度、输入数据类型限制。输入框一般是攻击者比较钟意的攻击对象,攻击者可以通过输入框限制不足的弱点进行数据窃取(比如SQL注入)、或者制造迫害(如比XSS)。我们可以通过对输入框最大长度、输入数据类型的限制,从一定程度上防范这样的攻击。我们可以根据实际需求,对一些输入框限定只允许输入字母、数字等。同时对输入的数据长度做限制。

6. 关闭客户端自动完成功能,减少驻留在客户端数据。

7. 设置<Frame>/<iFrame>受限,防止脚本执行。将<Frame>/<iFrame>中security属性设置为restricted后, Frame中的脚本将不能执行(仅限于IE)。

3.4 敏感数据的安全防范

1. 不能任意在Cookie、Session、ServletContext中存放数据,对于这些对象中存放的数据,必须有统一定义、说明、Lifecycle的管理等。

2. 对于敏感信息都必须保障其私密性。在页面显示、操作交互中不可避免的会有一些如用户的标识信息、密码、帐号信息、涉及的金额信息等敏感数据(保密性的数据)的存在。为保障这些数据不被曝露而提高安全性,我们要做到所有敏感信息必须进行加密处理,不能以明文的形式存在于任何网络、内存及其它持久化介质中(如:数据库、文件磁盘系统等)。

3. 所有的密码、key、帐号等机密信息都不能在URL中传递。

4. 所有的密码、key、银行账号等机密信息都不能存储到Cookie,Session、ServletContext中。

5. 防止信息泄漏:

1. 在系统上线使用的log level对应的日志输出中不允许包含任何密码、key、账号等机密信息。

2. SVN集成分支上的代码中不允许存留可用的system.out/err.print语句。

3. 在测试/调试阶段所使用的测试页面、单元测试模块等不允许提交到SVN集成分支上。

4. 不允许将系统产生的错误异常信息直接显示给用户,需要有统一的错误处理。

6. 尽量减少不必要的信息传递。在信息的传递过程中,如果当前Step中的对象、对象的属性、参数等在下一个Step中不需要,则不要再做传递,甚至可以显式的销毁。这样可以有效的减少信息被截获的机率,特别是敏感数据(例如用户密码、账户信息等等)。

3.5 WEB安全防范

1. Cookie的安全防范:

(1)存储于cookie中的敏感数据必须加密。

(2)没有特殊要求下,尽量使用会话cookie(非持久化)。

(3)如果使用持久化cookie应该设置cookie超时。

(4)激活cookie安全传输,表示创建的 cookie 只能在https连接中被浏览器传递到服务器端进行会话验证,如果是http连接则不会传递该信息。

2. 必须设置session的超时时间。web.xml中配置示例:

<session-config>

<session-timeout>10</session-timeout>

</session-config>

3. 必须构建统一的错误处理页面。web.xml示例:

<error-page>

<error-code>500</error-code>

<location>/error.jsp</location>

</error-page>

4. 多线程中线程安全的防范:

1. 尽量少用静态(static)变量和static方法。(除了静态常量:static final constants)。

2. 尽量多线程框架(java.util.concurrent)构建多线程同步机制。

3. 使用ThreadLocal避免多个线程之间类成员的共享冲突。

4. 如非必要,不要使用synchronized关键字。必须要使用synchronized时,应将同步范围最小化,即将同步作用到最需要的地方,避免大块的同步块或方法等。

5. 增加Referer的检查,防止非法访问。Referer是HTTP Header中的一个字段,当浏览器想服务器发送请求时,Referer用来通知服务器请求发起的位置。

2、 编码规范

1. 排版规范

1.1 规则

1.1.1 代码块要采用缩进风格编写,缩进长度为4个空格,如果使用tab缩进请在IDE中将tab设置为4个空格。使用默认的tap缩进会导致代码在其他编辑器中不对齐。

1.1.2 大括号使用约定:如果大括号内为空,则写成{}即可;如果非空代码块则:

1. 左大括号前不换行

2. 左大括号后换行

3. 右大括号前换行

4. 右大括号后还有else等代码则不需要换行;表示终止的右大括号后必须换行。

正例:

1.1.3 左小括号与字符之间不出现空格,同样,右小括号与字符之间也不出现空格。

反例:if(空格a == b空格)

1.1.4 单行字符数不超过80个,超出需要换行

1. 换行要在低优先级操作符出划分新行,操作符与下行一起换行。

2. 第二行相对第一行缩进4个空格,从第三行开始不再缩进。

3. 方法调用时多个参数需要换行的话,在逗号后换行。

4. 不要在逗号前换行。

1.1.5 不允许把多个短句写在同一行中,即一行一句代码。

反例:String cplx; String cpmc;

1.1.6 If,for,do,while等语句的执行语句不论多少行都要加{}。

反例:if(a == b) String c=b;

1.1.7 两个以上的变量,关键字,常量进行对等操作时,他们之间的操作符前后加空格,进行非对等操作时,如果是关系密切的立即操作符(如.),后不应加空格。由于留空格产生的清晰性是相对的,所以在已经非常清晰的语句中没有必要加空格,如果语句已足够清晰则括号的内侧(即左括号后面和右括号前面)不需要加空格,多重括号间不必加空格,因为在java中括号已经是最清晰的标志了。

示例:

1. 逗号,分号只在后面加空格

2. 比较操作符,赋值操作符"="、"+=",算术操作符"+"、"%",逻辑操作符"&&"、"&",位域操作符"<<","^"等双目操作符前后加空格。

3."!","~","++","--","&"等单目操作符前后不加空格

1.1.8 方法参数在定义和传入时,多个参数逗号后面必须加空格。

1.2 建议

1.2.1 类属性和类方法的定义不要交叉放置,同一类东西放在一起

格式:

2. 注释规范

2.1 类,类属性, 类方法的注释必须使用javadoc规范,即/** 内容*/格式,不得使用// xxxx的方式。

说明:javadoc方式在eclipse中调用方法时会提示相关的注释,不进人方法即可悬浮提示参数,返回值的意义等,提高阅读效率。

2.2 所有的抽象方法(包括接口中的方法)必须使用javadoc注释,除了返回值、参数、异常说明外,还必须指出该方法做什么事,实现什么功能。

2.3 所有类必须注释创建者,创建时间。

2.4 方法内部单行注释,在被注释代码上面另起一行,使用//注释;方法内部多行注释使用/* */;注意与代码对齐。

2.5 所有的枚举类型字段必须要有注释,说明每一项的用途。

2.6 代码修改的同时,注释也要修改,尤其是参数,返回值 ,核心逻辑等。

2.7 如果要注释代码,请在上面详细说明;如果是无用的代码,请删掉,不要注释掉。

2.8 注释的要求:第一、能准确的反应设计思想和代码逻辑;第二、能够描述业务含义,是别的程序员能够迅速了解该段代码的意义,不要怕字多,不是说只要自己能看懂就行,必须保证另外一个人拿到你这段代码看了注释就知道你在干什么。

2.9 注释也不是越多越好,应该力求精简准确、表达到位;过多过滥的注释,一旦代码逻辑修改,那么修改注释将是一个不小的负担。

如:setCpmc(cpmc),方法名setCpmc加上一个有意义的变量名cpmc,已经说明了这是在什么,语义清晰的代码不需要额外的注释。

2.10 特殊注释标记,请注明标记人,标记时间,预计处理时间。注意及时处理。

1. 待办事项(TODO):表示需要实现,但是目前还没有实现的功能。

2. 错误,不能工作(FIXME): 表示代码是错误的,不能工作,需要及时的纠正。

2.11 顺序实现流程的说明使用1、2、3、4在每个实现步骤部分的代码前面进行注释。

2.12 避免在注释中使用缩写单词。

3. 命名规范

3.1 类名使用UpperCamelCase风格,遵从驼峰形式,在哪个包下就以那个包的名字做后缀。

正例:action层的类CpglAction

反例:cpglAction

3.2 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从 驼峰形式。

正例:getUserMessage();

3.3 常量名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。

正例:MAX_STOCK_COUNT

反例:MAX_COUNT

3.4 中括号的数组类型的一部分,数组定义如下:String[] args;

反例:String args[];

3.5 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词或中文首字母。包名统一使用单数形式,但是类名可以使用复数形式。

正例:应用工具类包名为com.ddkj.util、类名为 MessageUtils

3.6 杜绝完全不规范的缩写,避免望文不知义。

反例:AbstractClass"缩写"命名成 AbsClass;condition"缩写"命名成 condi,此类随 意缩写严重降低了代码的可阅读性。

3.7 为了达到代码自解释的目标,任何自定义编程元素在命名时,使用尽量完整的单词 组合来表达其意。

反例:int name;

3.8 Service/DAO 层方法命名规约:

1. 获取对象的方法用get做前缀

2. 获取多个对象的方法用get做前缀,List做后缀

3. 获取分页对象的方法用get做前缀,Page做后缀

4. 获取统计值的方法用count做前缀

5. 插入方法用save/insert做前缀

6. 删除方法用remove/delete做前缀

7. 更新方法用update做前缀

4. 编码规范

4.1 一个函数仅完成一件功能,即使简单的功能也应该编写方法实现。

4.2 明确类的功能,精确地实现类的设计。一个类仅实现一组相近的功能。划分类的时候,应该尽量把逻辑处理、数据和显示分离,实现类功能的单一性。

4.3 自己抛出的异常必须填写详细的描述信息。

示例:

4.4 注意运算符的优先级,用括号明确表达式的操作顺序,不要使用默认优先级。避免不必要的误解。

示例:下面的表达式

如果写成

虽然不会报错,但是语句不易理解,造成判断条件出错。

4.5 避免使用不易理解的数字,用有意义的标识来代替。例如含有物理意义的常量可以用静态变量代替。

4.6 尽量不要使用难懂的技巧性很高的语句,除非必须要用的时候。

4.7 集合中的数据如果不使用了应该及时释放,尤其是可重复使用的集合。因为集合保存了对象的句柄,垃圾收集器不会回收。

5. 异常处理

5.1 runtimeException可以通过预先检查进行规避,不应该通过catch来处理,比如:IndexOutOfBoundsException,NullPointException等等。无法通过预先检查的异常除外,比如要解析一个外部传过来的字符串类型的数字,可以通过捕获NumberFormatException来实现。

5.2 捕获异常后需要对异常进行处理,如果不想处理请将它抛给它的调用者,最外层使用者必须处理异常,将其转化为用户可以理解的内容。

5.3 Finally块必须对资源对象,流对象进行关闭,有异常也要try-catch。

5.4 不能在finally块中使用return,因为finally中的return执行后将不再执行try中的return。

5.5 捕获异常和抛异常必须是完全匹配的,比如一个方法抛出一个NumberFormatException,那么调用它时捕获的异常类型必须是NumberFormatException。

5.6 调用方法需要进行null判断,防止NullPointException。

级联调用obj.getA().getB().getC()易产生NullPointException。

3、 数据库规范

1、数据库命名规范

采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线'_'组成,命名简洁明确,多个单词用下划线'_'分隔,一个项目一个数据库

2、数据库表命名规范2.1数据表命名规范

(1)采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线'_'组成,命名简洁明确,多个单词用下划线'_'分隔

(2)全部小写命名,禁止出现大写

(3)禁止使用数据库关键字,如:name,time ,datetime,password等

(4)表名称不应该取得太长(一般不超过三个英文单词)

(5)表的名称一般使用名词或者动宾短语

(6)用单数形式表示名称,例如,使用 employee,而不是 employees

明细表的名称为:主表的名称+字符dtl(detail缩写)

例如:采购定单的名称为:po_order,则采购定单的明细表为:po_orderdtl

(7)表必须填写描述信息(使用SQL语句建表时)

2.2命名规范

①模块_+功能点 示例:alllive_log alllive_category

②功能点 示例:live message

③通用表 示例:all_user

2.3待优化命名示例

①冗余:

错误示例:yy_alllive_video_recomment yy_alllive_open_close_log

说明:去除项目名,简化表名长度,去"yy_"

②相同类别表命名存在差异,管理性差

错误示例:yy_all_live_category yy_alllive_comment_user

说明:去除项目名,统一命名规则,均为"yy_alllive_"开头即可

③命名格式存在差异

错误示例:yy_showfriend yy_user_getpoints yy_live_program_get

说明:去除项目名,统一命名规则,动宾短语分离且动宾逻辑顺序统一

3、数据库字段命名规范3.1字段命名规范

(1)采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线'_'组成,命名简洁明确,多个单词用下划线'_'分隔

(2)全部小写命名,禁止出现大写

(3)字段必须填写描述信息

(4)禁止使用数据库关键字,如: time ,datetime等

(5)字段名称一般采用名词或动宾短语

(6)采用字段的名称必须是易于理解,一般不超过三个英文单词

(7)在命名表的列时,不要重复表的名称

例如,在名employe的表中避免使用名为employee_lastname的字段

(8)不要在列的名称中包含数据类型

(9)字段命名使用完整名称,禁止缩写

3.2命名规范

①名词 示例:user_id user_name sex

②动宾短语 示例:is_friend is_good

3.3待优化命名示例

①大小写规则不统一

错误示例:user_id houseID

说明:使用统一规则,修改为"user_id","house_id"

②加下划线规则不统一

错误示例:username userid isfriend isgood

说明:使用下划线进行分类,提升可性,方便管理,修改为"user_name","user_id","is_friend","is_good"

③字段表示不明确

错误示例:uid pid

说明:使用完整名称,提高可读性,修改为"user_id","parent_id"

3.4字段类型规范

(1)所有字段在设计时,除以下数据类型timestamp、image、datetime、smalldatetime、uniqueidentifier、binary、sql_variant、binary 、varbinary外,必须有默认值,字符型的默认值为一个空字符值串'',数值型的默认值为数值0,逻辑型的默认值为数值0

(2)系统中所有逻辑型中数值0表示为"假",数值1表示为"真",datetime、smalldatetime类型的字段没有默认值,必须为NULL

(3)用尽量少的存储空间来存储一个字段的数据

使用int就不要使用varchar、char,

用varchar(16)就不要使varchar(256)

IP地址使用int类型

固定长度的类型最好使用char,例如:邮编(postcode)

能使用tinyint就不要使用smallint,int

最好给每个字段一个默认值,最好不能为null

(4)用合适的字段类型节约空间

字符转化为数字(能转化的最好转化,同样节约空间、提高查询性能)

避免使用NULL字段(NULL字段很难查询优化、NULL字段的索引需要额外空间、NULL字段的复合索引无效)

少用text类型(尽量使用varchar代替text字段)

3.5数据库中每个字段的规范描述

(1)尽量遵守第三范式的标准(3NF)

表内的每一个值只能被表达一次

表内的每一行都应当被唯一的标示

表内不应该存储依赖于其他键的非键信息

(2)如果字段事实上是与其它表的关键字相关联而未设计为外键引用,需建索引

(3)如果字段与其它表的字段相关联,需建索引

(4)如果字段需做模糊查询之外的条件查询,需建索引

(5)除了主关键字允许建立簇索引外,其它字段所建索引必须为非簇索引

4、SQL语言编码规范4.1大小写规范

(1)所有关键字必须大写,如:INSERT、UPDATE、DELETE、SELECT及其子句,IF……ELSE、CASE、DECLARE等

(2)所有函数及其参数中除用户变量以外的部分必须大写

(3)在定义变量时用到的数据类型必须小写

4.2注释

注释可以包含在批处理中,在触发器、存储过程中包含描述性注释将大大增加文本的可读性和可维护性,本规范建议:

(1)注释以英文为主,实际应用中,发现以中文注释的SQL语句版本在英文环境中不可用,为避免后续版本执行过程中发生某些异常错误,建议使用英文注释

(2)注释尽可能详细、全面创建每一数据对象前,应具体描述该对象的功能和用途,传入参数的含义应该有所说明,如果取值范围确定,也应该一并说明,取值有特定含义的变量(如boolean类型变量),应给出每个值的含义

(3)注释语法:单行注释、多行注释

单行注释:注释前有两个连字符(--)对变量、条件子句可以采用该类注释

多行注释:符号之间的内容为注释内容,对某项完整的操作建议使用该类注释

(4)注释简洁,同时应描述清晰

(5)函数注释:

编写函数文本--如触发器、存储过程以及其他数据对象--时,必须为每个函数增加适当注释,该注释以多行注释为主,主要结构如下:

CREATE PROCEDURE sp_xxx

标签: #java语言编码标准标识是什么