1、应用系统安全开发技术规范(版本号 V1.3)朗新科技股份二一五年十二月更改履历版本号修改编号更改时间更改图表和章节号更改简明描述更改人同意人0.5-11-24初稿施伟施伟1.0-11-19修改宋月欣陈志明1.1-11-30修改宋月欣陈志明1.2-12-3修改宋月欣施伟1.3-12-3修改施伟注:更改人除形成初稿,以后每次修改在未同意确定前均需采取修订方法进行修改。目录1背景与目标12安全编程概念12.1安全编程12.2结构化编程22.3脆弱性22.4可信计算22.5安全可信模块32.6不可信任模块32.7敏感信息32.8特权32.9信息隐藏32.10中间件32.11死锁42.12可信边界42.
2、13元字符42.14参数化查询42.15UNIX JAIL环境42.16临时文件42.17信息熵52.18SSL52.19TLS52.20HTTPS52.21Http会话52.22Cookie62.23HttpOnly Cookie63安全编程原则63.1统一的安全规范63.2模块划分63.3最小化功能73.4最小化特权73.5对多任务、多进程加以关注73.6界面输出最小化73.7使代码简单、最小化和易于修改83.8避免高危的服务、协议83.9数据和代码分离83.10关键数据传输保护83.11禁止赋予用户进程特权83.12使用适当的数据类型93.13使用经过验证的安全代码93.14使用应用中间
3、件93.15设计错误、 异常处理机制93.16提供备份机制93.17检查传递变量的合法性93.18检查所有函数返回代码93.19修改面向用户的操作的反馈缺省描述93.20文件操作的要求103.21其他编码原则104应用安全分析114.1安全需求114.2安全威胁114.2.1Web安全漏洞114.2.2拒绝服务攻击124.2.3嗅探攻击124.2.4中间人攻击124.3安全约束135安全编程要求135.1输入处理135.1.1建立可信边界135.1.2验证各种来源的输入145.1.3保证所有的输入信息是被验证过的145.1.4对输入内容进行规范化处理后再进行验证155.1.5选择合适的数据验证
4、方式155.1.6防范元字符攻击155.1.7拒绝验证失败的数据155.1.8在服务端进行验证155.1.9建立统一的输入验证接口165.1.10控制写入日志的信息165.1.11从服务器端提取关键参数165.2输出处理165.2.1限制返回给客户的信息165.2.2建立错误信息保护机制165.3数据库访问165.3.1合理分配数据库访问权限165.3.2合理存放数据库连接帐号和密码信息175.3.3使用参数化请求方式175.3.4对 SQL 语句中来自于不可信区域的输入参数进行验证185.3.5对数据库操作的返回数据进行验证185.3.6分次提取数据185.3.7通过 row(行)级别的访问
5、控制来使用数据库185.3.8确保数据库资源被释放185.4文件操作195.4.1对上传文件进行限制195.4.2把文件名以及文件内容作为不可信的输入对待195.4.3安全的使用文件名195.4.4使用文件系统访问控制195.4.5注意文件访问竞争条件195.4.6安全使用临时文件205.4.7确保文件系统资源被释放206安全特征206.1关注应用的对象重用206.2用户访问控制信息的机密性206.3不要在客户端存放敏感数据206.4避免内存溢出216.5可配置数据保护216.6禁止在源代码中写入口令216.7随机数216.8使用可信的密码算法226.9异常管理227应用安全设计规范237.1
6、应用安全规划237.2数据安全等级划分237.3数据库规划237.3.1用户权限237.3.2数据源设计237.3.3外部系统访问237.4角色划分247.5URL规划247.6程序文件目录规划247.6.1数据及程序分离247.6.2静态程序资源247.6.3程序文件分类247.7Cookie247.8文件安全257.8.1文件存储257.8.2文件操作257.8.3文件类型257.9第三方组件安全257.9.1组件兼容性257.9.2组件安全及成熟度257.9.3组件配置257.10Web Service257.11RESTful Web Service267.12应用安全关注点277.1
7、3应用安全限制应对方案297.13.1外网隔离297.13.2外网文件操作297.13.3正向和反向隔离装置(国网系统)298应用安全开发规范308.1Java及Web安全编程规范308.1.1不信任未知308.1.2数据层开发308.1.3会话管理328.1.4Cookie338.1.5输入验证338.1.6输入文件名的验证348.1.7输出处理348.1.8敏感信息处理368.1.9异常信息处理378.1.10特殊页面跳转378.1.11文件操作378.1.12资源释放388.1.13内存控制388.1.14外部程序调用漏洞388.1.15整数溢出398.2C+安全编程规范398.2.1不
8、信任未知398.2.2免缓存区溢出408.2.3免缓整数溢出428.2.4域名合法性检查458.2.5检查返回值468.2.6产生随机数478.2.7验证输入文件名488.2.8类设计注意事项488.2.9外部程序调用漏洞508.2.10临时文件处理501 背景和目标在Internet大众化及Web技术飞速演变今天,Web安全所面临挑战日益严峻。黑客攻击技术越来越成熟和大众化,针对Web攻击和破坏不停增加,Web安全风险达成了前所未有高度。很多程序员不知道怎样开发安全应用程序,开发出来Web应用存在较多安全漏洞,这些安全漏洞一旦被黑客利用将造成严重甚至是灾难性后果。这并非危言耸听,类似网上事故
9、举不胜举,企业Web产品也曾数次遭黑客攻击,甚至有黑客利用企业Web产品漏洞敲诈运行商,造成极其恶劣影响。本规范为处理Web应用系统安全问题,对关键应用安全问题进行分析,并有针对性从设计及开发规范、开发管理、安全组件框架、安全测试方面提供整体安全处理方案。使本组织能以标准、规范方法设计和编码。经过建立编码规范,以使每个开发人员养成良好编码风格和习惯;并以此形成开发小组编码约定,提升程序可靠性、可读性、可修改性、可维护性和一致性等,促进团体间交流,并确保软件产品质量。 2 安全编程概念2.1 安全编程安全编程是指开发人员首先需要含有一定安全知识,然后识别数据在流转(输入、处理和输出)过程中可能面
10、正确威胁,对这些威胁进行分析得出其利用漏洞,经过合理地编写代码消除这些漏洞,降低软件面临风险。本规范对开发人员编码提出统一安全要求, 关键包含输入处理、 输出处理、 数据库访问、 文件操作、异常管理等方面,以下图: 输入处理部分能指导开发者避免用户不良输入;输出处理能指导开发者对输出内容进行过滤; 数据库访问、 文件操作部分则能指导开发者进行数据库查询, 写入文件等操作时进行防护; 而异常管理、敏感数据保护、对象重用等技术则指导开发者改善软件本身缺点。 WEB 开发规范部分则指导用户在WEB 系统( B/S 架构应用)研发方面时怎样增加对应用软件保护。 2.2 结构化编程结构化编程,一个编程典
11、范。它采取子程序、程式码区块、for循环和while循环等结构,来替换传统goto。期望借此来改善计算机程序明晰性、品质和开发时间,而且避免写出面条式代码。2.3 脆弱性脆弱性指计算机系统安全方面缺点,使得系统或其应用数据保密性、完整性、可用性、访问控制、监测机制等面临威胁。2.4 可信计算可信计算行为会更全方面地遵照设计,而实施设计者和软件编写者所严禁行为概率很低。2.5 安全可信模块审计和访问控制模块是唯一安全可信模块。2.6 不可信任模块除审计和访问控制模块外其它全部模块均为不可信模块。2.7 敏感信息系统敏感信息包含用户身份信息、认证信息、授权信息、交易过程中私密或隐私信息、其它敏感信
12、息。2.8 特权特权只是许可去做并不是每个人全部能够做事情。2.9 信息隐藏信息隐藏指在设计和确定模块时,使得一个模块内包含特定信息(过程或数据),对于不需要这些信息其它模块来说,是不可访问。信息隐藏基础原理框图:2.10 中间件中间件是提供系统软件和应用软件之间连接软件,方便于软件各部件之间沟通.中间件技术创建在对应用软件部分常见功效抽象上,将常见且关键过程调用、分布式组件、消息队列、事务、安全、连结器、商业步骤、网络并发、HTTP服务器、Web Service等功效集于一身或分别在不一样品牌不一样产品中分别完成。2.11 死锁死锁是操作系统或软件运行一个状态:在多任务系统下,当一个或多个进
13、程等候系统资源,而资源又被进程本身或其它进程占用时,就形成了死锁。2.12 可信边界可信边界能够被认为是在程序中划定一条分隔线,一边数据是不可信而另一边则是可信。当数据要从不可信一侧到可信一侧时候,需要使用验证逻辑进行判定。 2.13 元字符元字符就是在编程语言中含有特定含义字符或字符串。比如在 SQL 查询中,单引号()是危险字符;在文件系统路径中两个点号(.)是危险字符; 在命令 shell 中,分号(;)和双 &(&)符号一样是危险字符,而换行符(n) 对日志文件很关键。2.14 参数化查询参数化查询(Parameterized Query 或 Parameterized Stateme
14、nt)是指在设计和数据库链接并访问数据时,在需要填入数值或数据地方,使用参数 (Parameter) 来给值,这个方法现在已被视为最有效可预防SQL注入攻击 (SQL Injection) 攻击手法防御方法。2.15 UNIX JAIL环境一个被改变根目录程序不能够访问和命名在被改变根目录外文件,那个根目录叫做“chroot监狱(chroot jail,chroot prison)”。2.16 临时文件创建临时文件程序会在完成时将其删除。2.17 信息熵信息熵指信息不确定性,一则高信息度信息熵是很低,低信息度熵则高。2.18 SSL安全套接层(Secure Sockets Layer,SSL)
15、,一个安全协议,是网景企业(Netscape)在推出Web浏览器首版同时提出,目标是为网络通信提供安全及数据完整性。SSL在传输层对网络连接进行加密。SSL采取公开密钥技术,确保两个应用间通信保密性和可靠性,使用户和服务器应用之间通信不被攻击者窃听。它在服务器和用户机两端可同时被支持,现在已成为互联网上保密通讯工业标准。现行Web浏览器亦普遍将HTTP和SSL相结合,从而实现安全通信。此协议和其继任者是TLS。2.19 TLSSSL(Secure Sockets Layer)是网景企业(Netscape)设计关键用于Web安全传输协议。这种协议在Web上取得了广泛应用。IETF(.org)将S
16、SL作了标准化,即RFC2246,并将其称为TLS(Transport Layer Security),其最新版本是RFC5246,版本1.2。从技术上讲,TLS1.0和SSL3.0差异很微小。2.20 HTTPS超文本传输安全协议(缩写:HTTPS,英语:Hypertext Transfer Protocol Secure)是超文本传输协议和SSL/TLS组合,用以提供加密通讯及对网络服务器身份判定。HTTPS连接常常被用于万维网上交易支付和企业信息系统中敏感信息传输。HTTPS不应和在RFC 2660中定义安全超文本传输协议(S-HTTP)相混。2.21 Http会话在计算机科学领域来说,
17、尤其是在网络领域,会话(session)是一个持久网络协议,在用户(或用户代理)端和服务器端之间创建关联,从而起到交换数据包作用机制,session在网络协议(比如telnet或FTP)中是很关键部分。在不包含会话层(比如UDP)或是无法长时间驻留会话层(比如HTTP)传输协议中,会话维持需要依靠在传输数据中高等级程序。比如,在浏览器和远程主机之间HTTP传输中,HTTP cookie就会被用来包含部分相关信息,比如session ID,参数和权限信息等。当用户端在多个服务器调取数据时,保持会话状态一致性是需要注意,用户端需用同时保持和某一个主机连接,或多个服务器端需要共享一个储存会话信息文件
18、系统或数据库。不然,当用户在一个新而不是一开始保留会话信息主机上提交访问请求时候,主机会因为无法获知原来主机会话访问状态而产生问题。2.22 CookieCookie(复数形态Cookies),汉字名称为小型文本文件或小甜饼,指一些网站为了分辨用户身份而储存在用户当地终端(Client Side)上数据(通常经过加密)。定义于RFC2109。为网景企业前雇员Lou Montulli在1993年3月所发明。2.23 HttpOnly CookieHttpOnly是包含在Http 响应头信息Set-Cookie中一个额外标志,假如浏览器支持HttpOnly标志话,在生成Cookie时使用HttpO
19、nly标志可帮助减轻用户端脚本访问受保护Cookie时带来风险(用户端脚本不能访问HttpOnly Cookie)。3 安全编程标准3.1 统一安全规范每个软件项目在设计阶段全部应明确在项目实施过程中项目组应遵照统一规范,具体包含:1. 命名规则、组件使用规范、异常处理规范、日志处理规范、工具使用要求、 代码集成规范。2. 针对本规范提出关键代码脆弱性应进行对应防范设计,具体内容应在软件概要设计中表现或有单独文档表现。3.2 模块划分1. 软件应该根据安全性划分模块,审计和访问控制模块为安全可信模块,其它模块为不可信任模块。只有安全可信模块才能够实施安全控制功效,其它模块不能访问安全可信模块安
20、全信息、功效或权限。安全可信模块应该和其它模块分离,由经授权内部专员进行管理。2. 只有安全可信模块,才能以高安全等级访问系统敏感信息,对于其它模块限制其访问敏感信息。3.3 最小化功效依据“没有明确许可就默认严禁”标准, 软件应只包含那些为达成某个目标而确实需要功效,不应包含只是在未来某个时间需要但需求说明书中没有功效。 软件在最小化功效建设方面应遵照以下标准:1. 只运行明确定义功效。2. 系统调用只在确实需要时候。3. 一次只实施一个任务。4. 只有在上一个任务完成后才开始下一个任务。5. 只在确实需要时候访问数据。3.4 最小化特权1. 只为程序中需要特权部分授和特权。2. 只授和部分
21、绝对需要具体特权。3. 将特权有效时间或能够有效时间限制到绝对最小。3.5 对多任务、多进程加以关注软件开发应尽可能使用单任务程序。假如软件需要使用多任务和多进程,应该认真分析研究多任务和多进程会不会发生冲突,同时全部进程和任务以避免冲突。 同时作为结构化编程, 每个原子化组件全部要确保一个入口和一个出口。假如进程之间需要交互,则这些交互操作应同时。对于每一个可能交互情况全部要考虑相关安全策略。3.6 界面输出最小化软件应保持用户界面只提供必需功效,没有多出、无须要功效,确保用户不能经过用户界面直接访问数据或直接访问被保护对象。3.7 使代码简单、最小化和易于修改开发时应尽可能使代码简单、最小
22、化和易于修改。使用结构化编程语言,尽可能避免使用递归和 Goto 申明。使用简单代码,清除无须要功效,预防采取信息隐藏方法进行数据保护。3.8 避免高危服务、协议软件应尽可能避免使用不加保护及已被证实存在安全漏洞服务和通信协议传输文件,如FTP 、SMTP。3.9 数据和代码分离软件应该把数据和程序放置在不一样目录中,这里数据包含远程下载文件等。3.10 关键数据传输保护1. 软件在传输关键数据时,使用加密算法确保数据在通信过程不被破译,使用数字署名确保数据在传输过程中一致性和不可否认性。相关加密算法和署名技术等应符合国家相关法律法规要求。2. 信息隐藏是不可靠、 效率低做法,软件应该使用正确
23、安全保护方法,不要依靠隐藏进行数据保护。3.11 严禁给予用户进程特权用户进程授权应采取最小授权法,对于软件一般用户进程,严禁给予该类进程特权用户权限。特权用户类型包含:1. 超级用户。2. 直接操作数据库用户。3. 安全管理用户。 3.12 使用合适数据类型应该小心使用数据类型,尽可能使用占用内存较小数据类型,如可用整型数据不用实型,尤其是在程序接口部分。比如,在部分编程语言中signed 和 unsigned 数据类型是视为不一样(如C或C+语言)。3.13 使用经过验证安全代码使用经过验证安全代码模块和外部源程序,预防潜在安全风险。3.14 使用应用中间件中间件作为一个应用层架构,软件设
24、计应尽可能使用中间件,中间件选型时应选择成熟、业界主流中间件产品。3.15 设计错误、 异常处理机制软件设计开发时应建立预防系统死锁机制,异常情况处理和恢复机制,具体包含错误和异常检测、数据回滚、安全错误通知、错误和异常统计、断点保护等。3.16 提供备份机制为确保运行数据完整性和可用性,软件开发应设计有效备份策略,依据业务和系统维护需要提供定时或不定时、自动或手动方法备份机制。3.17 检验传输变量正当性应检验全部传输给系统函数调用(System Calls)或当地调用(Native Calls)变量正当性。3.18 检验全部函数返回代码应检验全部函数调用返回代码(错误代码),对每个期望返回
25、值设置对应处理程序。3.19 修改面向用户操作反馈缺省描述应对面向用户操作反馈缺省描述进行必需封装,删除相关后台系统或其它敏感信息。3.20 文件操作要求在需要进行文件操作时,应预先设定现在工作路径(全路径名),使用全路径名表示文件位置。3.21 其它编码标准1. 当一个进程对敏感对象(包含秘密信息或包含不可更改信息)使用完后,应立即擦除对象敏感信息,然后再删除对象。任何不需要使用资源应立即释放。2. 确保全部用来指示数组下标数据(或指针)全部指向了一个有效数组元素。 假如某个函数不能确保下标所指向元素有效性,或根本不去检验边界时,不要使用该函数,应该寻求一个安全函数,或自己重新编写一个或封装
26、一个不安全函数,加上必需判定条件,使它安全。3. 当输入不可信任数据时,要在该数据内容和格式上同时加以检验。对于整数,应该检验数据大小是否超出了能够表示范围;对于输入字符串,要确保长度没有溢出,确保每一个字符全部是有效。4. 对常常使用类似 SQL 语句应使用绑定变量方法,避免数据库实施类似 SQL 语句时反复解析、反复访问数据文件行为。5. 程序编码结束后,应对代码进行优化,提升应用处理 SQL 性能。6. 严禁使用通配符方法进行数据插入操作。7. 采取数据库作为系统间接口方法时,应建立独立接口表,并按最小化特权标准进行授权。4 应用安全分析4.1 安全需求系统安全本质上属于信任问题,要确保
27、应用安全,就必需将处理多种操作过程中不可信问题。安全多个基础要素为机密性、完整性、可用性、可审计性、不可抵赖性等方面安全要求。机密性要求保护数据内容不能泄露,加密是实现机密性要求常见手段。完整性要求保护数据内容是完整、没有被篡改。可用性要求保护资源是可被根据需要访问。可审计性对出现安全问题提供调查依据和手段。不可抵赖性建立有效责任机制,预防用户否认其行为。4.2 安全威胁4.2.1 Web安全漏洞依据结合国网系统安全检测项目常见安全问题及OWASP组织公布安全漏洞,系统中存在需要处理安全风险以下:序号安全威胁产生步骤1SQL注入编码2失效身份认证及会话管理设计、编码3跨站脚本(XSS)编码4点
28、击劫持(ClickJacking)编码4不安全直接对象引用编码5安全配置错误配置实施6敏感信息泄露设计、编码7功效级访问控制缺失(失败URL访问权限限制)设计8跨站请求伪造(CSRF)编码9使用含有已知漏洞组件管理、设计10未验证重定向和转发编码11传输层保护不足设计、编码12文件上传漏洞编码13不安全加密存放设计、编码4.2.2 拒绝服务攻击分布式拒绝服务攻击(英文:Distributed Denial of Service,缩写:DDoS)亦称洪水攻击。顾名思义,即是利用网络上已被攻陷电脑作为“僵尸”,向某一特定目标电脑发动密集式“拒绝服务”式攻击,用以把目标电脑网络资源及系统资源耗尽,使
29、之无法向真正正常请求用户提供服务。黑客经过将一个个“丧尸”或称为“肉鸡”组成僵尸网络,就能够发动大规模DDoS或SYN洪水网络攻击,或将“丧尸”们组到一起进行带有利益刷网站流量、Email垃圾邮件群发,瘫痪预定目标受雇攻击竞争对手等商业活动。4.2.3 嗅探攻击利用计算机网络接口截获目标地为其它计算机数据报文一个技术。它工作在网络底层,把网络传输全部数据统计下来. 嗅探器能够帮助网络管理员查找网络漏洞和检测网络性能。嗅探器能够分析网络流量,方便找出所关心网络中潜在问题。证实你网络有嗅探器有两条经验:1. 网络通讯丢包率很高:经过部分网管软件,能够看到信息包传送情况,最简单是ping命令。它会告
30、诉你掉了百分之多少包。假如你网络结构正常,而又有2030数据包丢失以致数据包无法顺畅流到目标地。就有可能有些人在监听,这是因为嗅探器拦截数据包造成。2. 网络带宽出现反常:经过一些带宽控制器,能够实时看到现在网络带宽分布情况,假如某台机器长时间占用了较大带宽,这台机器就有可能在监听。应该也能够觉察出网络通讯速度改变。4.2.4 中间人攻击在密码学和计算机安全领域中,中间人攻击 ( Man-in-the-middle attack,通常缩写为MITM )是指攻击者和通讯两端分别建立独立联络,并交换其所收到数据,使通讯两端认为她们正在经过一个私密连接和对方直接对话,但实际上整个会话全部被攻击者完全
31、控制。在中间人攻击中,攻击者能够拦截通讯双方通话并插入新内容。在很多情况下这是很简单(比如,在一个未加密Wi-Fi 无线接入点接收范围内中间人攻击者,能够将自己作为一个中间人插入这个网络)。 一个中间人攻击能成功前提条件是攻击者能将自己伪装成每一个参与会话终端,而且不被其它终端识破。中间人攻击是一个(缺乏) 相互认证攻击。大多数加密协议全部专门加入了部分特殊认证方法以阻止中间人攻击。比如,SSL协议能够验证参与通讯一方或双方使用证书是否是由权威受信任数字证书认证机构颁发,而且能实施双向身份认证。4.3 安全约束序号限制1外网不许可布署数据库2外网仅提供HTTP、HTTPS访问,不提供FTP、S
32、FTP等3外网访问内网必需经过强隔离装置,仅支持TNS协议(国网系统要求)4外网应用不许可直接访问内网关键业务系统数据库5其它系统标准上全部不许可直接连接营销系统数据库5 安全编程要求5.1 输入处理5.1.1 建立可信边界需要在程序中定义清楚可信边界。 在部分代码中用于保留可信数据数据结构,不能被用来在其它代码中存放不可信数据。使数据穿越可信边界次数降到最低。当程序混淆了可信和不可信数据界限时会造成安全边界发生问题,最轻易造成这种错误情况是把可信和不可信数据混合在一个数据结构里。以下例:该例中程序接收一个 http 请求并将 usrname 参数放在 HTTP session 里, 不过并未
33、检验用户是否被授权。usrname =request.getParameter(usrname);if(session.getAttribute(ATTR_USR)= null)session.setAttribute(ATTR_USR,usrname);因为开发者全部知道用户是不能直接访问 session 对象,所以很轻易信任来自 session 全部信息,不过假如在该 session 中混合存放了可信和不可信数据, 就会违反完全可信边界标准,带来安全隐患。假如不能很好建立和维护可信边界,开发者将不可避免混淆未被验证和已验证数据,从而造成部分数据在未经验证时就被使用。假如输入数据在处理前经过
34、部分用户交互发生了改变, 可信边界就会碰到一定问题,因为它很可能在全部数据进入之前不能做出完全输入验证。在这种情况下,维护一个可信边界就尤为关键,不可信数据应该单独存放在专门存放不可信数据数据结构内,在经过验证以后才被放在可信区域。 这么在看一段代码时,就很轻易识别数据是在可信边界哪一侧。5.1.2 验证多种起源输入不要将软件安全性寄托在配置、使用和维护人员敏锐了解力、深刻洞察力或良好意愿上,不仅需要验证用户输入,而且还要验证全部来自于软件之外输入,这些输入应该包含下列内容,但并不仅仅局限于此:1. HTTP 请求消息全部字段,包含 GET 数据、 POST 数据、 COOKIE 和 Head
35、er 数据等。2. 不可信起源文件。3. 第三方接口数据。4. 从数据库中检索出数据。5. 对来自命令行、 环境和配置文件输入。6. 网络服务。7. 注册表值。8. 系统性能参数。9. 临时文件。 5.1.3 确保全部输入信息是被验证过确保在输入验证之前,新输入数据不能被添加到程序中(输入数据不能进入程序代码中被实施)。也就是说,程序默认情况下要对全部输入信息进行验证,不能经过验证数据将会被拒绝。5.1.4 对输入内容进行规范化处理后再进行验证当输入数据包含文件名、路径名、URL 等数据时,应先对输入内容进行规范化处理后再进行验证,如文件路径、URL 地址等数据,需要规范化为标准格式后再进行验
36、证。5.1.5 选择适宜数据验证方法应依据情况综合采取多个输入验证方法,包含:1. 检验数据是否符合期望类型。2. 检验数据是否符合期望长度。3. 检验数值数据是否符合期望数值范围,比如检测整数输入最大值和最小值。4. 检验数据是否包含特殊字符,如: 、 、 、 %、 (、)、 &、 +、 、 、 等。5. 应使用正则表示式进行白名单检验尽可能避免使用黑名单法。5.1.6 防范元字符攻击攻击者通常会使用元字符对应用程序提议攻击。攻击者能够经过对同一个元字符采取多个编码方法或依据语言特征采取多个实现方法,所以应过滤输入数据中那些含有特定含义字符,如单引号、双引号、圆括号、分号等。5.1.7 拒绝
37、验证失败数据应拒绝验证失败输入数据,不试图对其进行修复(如处理密码域时自动剪裁掉超出最大长度输入,替换掉在输入框输入 JavaScript 字符等)。输入验证本身就很复杂,假如和自动错误恢复代码混合在一起话,将会造成更大复杂性,自动错误恢复代码很可能改变请求含义或截断验证逻辑。假如我们能够引导用户,使她们提交请求能够经过输入验证,就会比专注于自动错误恢复代码有效得多。在验证失败时,安全做法是不试图修复一个未能经过输入验证请求,直接拒绝掉。5.1.8 在服务端进行验证仅在用户端进行验证是不安全,尤其是在 WEB 应用系统中,用户端验证大多采取脚本(如JavaScript)来完成,用户端验证很轻易
38、被绕过,安全做法是在用户端验证同时,在服务器端也进行验证。5.1.9 建立统一输入验证接口应建立统一输入验证接口,为整个应用系统提供一致验证方法,这么能够避免分散验证带来代码管理混乱,而且能够降低遗漏。5.1.10 控制写入日志信息因为日志数据价值,它也成为了攻击者目标。 假如攻击者能够控制写进日志文件信息, 她们就能够在输入中混入伪造日志条目来伪造系统事件, 更严重是,假如负责进行日志分析代码存在漏洞,特定有恶意输入数据很可能触发该漏洞,并引发愈加严重危害。假如日志数据中包含输入数据,应对输入数据进行验证,严禁攻击者能够写任意数据到日志中。5.1.11 从服务器端提取关键参数需要获取参数时,
39、应该从服务器端提取关键参数,严禁从用户端输入,比如产品价格、用户角色、鉴权标志等,假如关键参数许可从用户端输入提供,攻击者可经过伪造或篡改输入数据造成程序关键逻辑错误。5.2 输出处理5.2.1 限制返回给用户信息编码时应该限制返回给用户和业务处理无关信息,严禁把关键保护数据返回给不信任用户,避免信息外泄。5.2.2 建立错误信息保护机制开发人员在编码时,严禁将具体错误信息直接反馈到用户端,具体错误信息中包含系统信息、文件和目录绝对路径信息,应对错误信息进行规整和清理后再返回到用户端,提议只向用户端返回错误码,具体错误信息能够统计在后台服务器。5.3 数据库访问 5.3.1 合理分配数据库访问
40、权限应根据“最小化标准” 为应用程序分配数据库访问权限。 避免为应用程序分配过大或无须要数据库权限,严禁将数据库 DBA 权限分配给应用程序。5.3.2 合理存放数据库连接帐号和密码信息严禁在应用程序代码和配置文件明文存放数据库连接帐号和密码信息,提议对数据库连接账户和密码信息加密后再保留在配置文件中。5.3.3 使用参数化请求方法使用参数化 SQL 请求是预防 SQL 注入有效方法。造成 SQL 注入漏洞原因就是攻击者能够改变 SQL 请求内容,攻击者提交数据变成了 SQL 实施命令一部分。在结构 SQL 请求时,开发者应该知道哪些应该被翻译为数据而哪些应该被翻译为命令一部分。假如正确使用参
41、数化 SQL 语句,就能够经过不许可数据指向改变方法来防御几乎全部 SQL 注入攻击。参数化 SQL 语句通常是由 SQL 字符结构,不过来自用户数据是需要和部分绑定参数组合在一起。也就是说,开发者使用这些绑定参数来正确向数据库指出哪些应该被看成数据,哪些应该被看成命令。当程序要实施该语句时候,它就会通知数据库这些绑定参数运行值,这么就避免了数据被认为是命令语句而被实施错误。 不过,以下是 SQL 请求中包含字符串拼接造成 SQL 注入漏洞例子:这是一个 java web 应用程序,让用户在数据库中搜索部分信息,用户能够指定要搜寻对象名称,并用以下代码实施这些查询:.Stringitem =r
42、equest.getParamater(item);String q=SELECT * FROM records WHERE item=+item;PreparedStatementstmt= conn.prepareStatement(q); ResultSetresults=stmt.execute();. 即使本例 程序 使用 了 参数化 接口 , 不过它 犯了 一个很常见 错误: 把用 户 输入作 为 prepareStatement() 参数传入,假如许可用户控制 PreparedStatement 内容,参数化 SQL 提供安全特征就会失去效果,很多 SQL 注入攻击关键字也会被包
43、含在之前结构语句中。合理使用参数化 SQL 代码以下: .Stringitem =request.getParamater(item);String q=SELECT *FROM records WHEREitem=?;PreparedStatementstmt= conn.prepareStatement(q);stmt.setString(1,item);ResultSetresults=stmt.execute();.5.3.4 对 SQL 语句中来自于不可信区域输入参数进行验证 在部分复杂情况会出现要求输入影响 SQL 语句结构情况,譬如要求在 where 子句里增加一个动态约束,这时
44、应对来自不可信区域输入参数进行验证。 5.3.5 对数据库操作返回数据进行验证 不应盲目信任来自数据库数据,提议对来自数据库数据进行验证,确保其格式正确且能够安全使用:1. 检验 SQL 请求返回统计数, SQL 请求预期结果为单值数据,但存在多行结果时,表明 SQL 请求中被可能被攻击者插入了注入语句,此时应中止后续处理并统计日志。2. 未来自数据库数据做为输入数据时,也应进行验证。 5.3.6 分次提取数据 对于数据库查询操作,假如查询返回结果较多时,应设计成份次提取, 应避免一次提取过多数据。5.3.7 经过 row(行)等级访问控制来使用数据库不要依靠应用程序访问控制能够保护数据库数据,限制每个请求使用户只能访问她们自己数据。经过 row 等级访问控制是预防用户信息泄露“最终防线”了。 限制 SQL 请求只向目前认证用户返回结果。当用户要实施 SQL 语句时,依据用户提交用户名或 ID 进行判定是否含有实施该 SQL 语句操作权限,来限制攻击者越权来实施 SQL 语句。5.3.8 确保数据库资源被释放确保数据库访问在不需