查看原文
其他

七个安全编码之最佳实践

洛逸 21CTO 2022-05-25

导读:如今软件的安全性比以往任何时间都要重要。本文为各位提供了多个编码最佳实践,各位在编码时可以有效利用。


背景


在当今世界,软件的安全性比以往任何时候都重要。如果我们将安全实时嵌入到应用程序的开发中,不仅有利于应用程序的整体安全,还可以在软件级别上创建多个安全检查点。


在本文中,我们会提供多个实时安全编码的例子,这些例子在开发现代软件时必须应用。本文中使用 Java 来展示实例,但这些示例可以用任何一种编程语言编写。


1、用户输入转义


有几种类型的攻击行为,最严重的是 SQL 注入攻击。这种攻击者在输入文字时混入了数据库查询指令,用来糊弄 SQL 执行引擎,向攻击者提供更多有用的信息,甚至有可能被控制。


要避免此类攻击,要在用户输入处理中加入转义,避免解析命令,而将其视为普通文本——经典的方法就是将数据库存储的数据进行转义。


在一些场景中,有一些用户在发帖时输入了 JavaScript 脚本,用来取得 Cookie,如果未加文章转义,JavaScript 将被执行,为攻击者提供更多的信息控制。如下代码示例:


有风险的代码:


String query = "SELECT user_id FROM user_data WHERE user_name = '"
+ req.getParameter("userID")
+ "' and user_password = '" + req.getParameter("pwd") +"'";
try {
Statement statement = connection.createStatement( … );
ResultSet results = statement.executeQuery( query );
}



去除风险的代码:


Codec ORACLE_CODEC = new OracleCodec();
String query = "SELECT user_id FROM user_data WHERE user_name = '"
+ ESAPI.encoder().encodeForSQL( ORACLE_CODEC, req.getParameter("userID"))
+ "' and user_password = '"
+ ESAPI.encoder().encodeForSQL( ORACLE_CODEC, req.getParameter("pwd")) +"'";



2.避免使用自增长序列


在某些情况下,攻击者试图获取比其应有的更多信息。比如,如果API的用户允许查看ID为1-100的用户。现在,如果系统使用自增长 ID序列,那么下一个用户将是101。


此攻击者可以利用此漏洞来获取有关用户并不应该获得的信息。


代码示例:


潜在风险代码


String sqlIdentifier = "select TESTING_SEQ.NEXTVAL from dual";
PreparedStatement pst = conn.prepareStatement(sqlIdentifier);
synchronized( this ) {
ResultSet rs = pst.executeQuery();
if(rs.next())
long myId = rs.getLong(1);



去除风险的代码:


// This example is for Oracle
String sqlIdentifier = "select TESTING_SEQ.NEXTVAL from dual";
PreparedStatement pst = conn.prepareStatement(sqlIdentifier);
synchronized( this ) {
ResultSet rs = pst.executeQuery();
if(rs.next())
long myId = rs.getLong(1) + UUID.random();



3、运用极简主义方法


为了减少网络攻击行为,系统应该采用最小空间占用的原则——从本质上讲,系统不应该暴露相关的权限。我们来举个例子,如果有一项业务,系统需要使用200 HTTP 编码来响应资源已经存在,比如 REST API 提供了 GET 方法,则会增加攻击者的范围。


正确的方法是,系统应该只有 HTTP 协议的 head 方法,该方法只提供相关存在的信息。


代码示例:


有风险的代码:

//Get is allowed where we need to just check user existhttp://localhost:8080/User/id/1



无风险的代码:

http://localhost:8080/User/id/1Head



4、最低权限原则 


假设以某种方法,客户服务部门的一位用户权限被攻击,本来她只以访问订单数据API,但他却被分配了超级管理员的角色。


攻击者利用其身份掩护,对系统发起一系列攻击。为了减少攻击维度,应根据角色需要来对 API 授权,不应该有可以访问所有内容的超级用户概念。


5、一直使用 HTTPS


不要使用 HTTP协议发布自己的站点和 API,浏览器会对此发出安全警告。


6、不要使用不安全和弱加密算法


随着计算能力的提升,弱的密钥已经无法对抗暴力破解。某些公司已经将一些加密算法列入不可使用清单之列。


- SHA-1

- 1024位 RSA 或 DSA

- 160位 ECDSA 

- 80/112-bit 2TDEA 

- MD5


7、以白名单方式处理可执行代码


如果在流程中会存在一些代码运行,它们是由 APP 或 API 的用户传入的,也可能是用户输入后生成的,这些都需要我们将要执行的命令列入白名单。


例如,要列出服务器上的目录:ls /dir,此时 API 应该处理白名单后转义用户输入的标签。


总结


我们可以大多数的安全编码实践分为4-5个范式,包括但不限于加密、缗码、白名单、最低权限,不要信任用户的输入内容。


如果你的团队采用了这些编码最佳实践,可大降低应用软件安全威胁之风险。 


编译:洛逸

来源:https://dzone.com/articles/practical-secure-coding-practices


相关阅读:


App开放接口API安全:Token签名Sign的设计与实现

OAuth2 与 JWT:如何设计安全的API

一个脚本就把系统升级到 HTTPS,还永久免费!


关于21CTO

21CTO.com是开发者的综合服务平台。为CTO、技术总监,技术专家,架构师、技术经理,高级研发工程师、PM等提供学习成长,教育培训,工作机会、人脉影响力等产品,同时为企业提供人才招聘,企业培训,软件研发等服务。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存