《Java编码指南:编写安全可靠程序的75条建议》—— 指南7:防止代码注入-阿里云开发者社区

开发者社区> 异步社区> 正文

《Java编码指南:编写安全可靠程序的75条建议》—— 指南7:防止代码注入

简介: 当有不可信的输入注入动态构造的代码中时,会引起代码注入攻击。一个明显的潜在漏洞是在Java代码中使用JavaScript代码。javax.script包定义了Java脚本引擎的接口和类,以及在Java代码中使用这些接口和类的框架。
+关注继续查看

本节书摘来异步社区《Java编码指南:编写安全可靠程序的75条建议》一书中的第1章,第1.7节,作者:【美】Fred Long(弗雷德•朗), Dhruv Mohindra(德鲁•莫欣达), Robert C.Seacord(罗伯特 C.西科德), Dean F.Sutherland(迪恩 F.萨瑟兰), David Svoboda(大卫•斯沃博达),更多章节内容可以访问云栖社区“异步社区”公众号查看。

指南7:防止代码注入

当有不可信的输入注入动态构造的代码中时,会引起代码注入攻击。一个明显的潜在漏洞是在Java代码中使用JavaScript代码。javax.script包定义了Java脚本引擎的接口和类,以及在Java代码中使用这些接口和类的框架。javax.script API的滥用,会导致攻击者在目标系统上执行任意代码。

这条指南是《The CERT® Oracle® Secure Coding Standard for Java™》[Long 2012]的“IDS00-J. Sanitize untrusted data passed across a trust boundary”的一个实例。

违规代码示例

下面的违规代码示例将不可信的用户输入嵌入了负责打印输入的JavaScript语句中。

private static void evalScript(String firstName)
  throws ScriptException {
 ScriptEngineManager manager = new ScriptEngineManager();
 ScriptEngine engine = manager.getEngineByName("javascript");
 engine.eval("print('"+ firstName + "')");
}```
攻击者可以传入一个别有用心的输入值,用以注入恶意的JavaScript代码。下面的这个示例展示了一个恶意的字符串,该字符串包含的JavaScript代码可以在目标系统上创建或覆盖现有的文件。

dummy');
var bw = new JavaImporter(java.io.BufferedWriter);
var fw = new JavaImporter(java.io.FileWriter);
with(fw) with(bw) {
 bwr = new BufferedWriter(new FileWriter("config.cfg"));
 bwr.write("some text"); bwr.close();
}
// ;`
这个示例中的脚本首先打印“dummy”,然后将“some text”写入一个名为config.cfg的配置文件中。这是一个可以导致任意代码执行的真实漏洞。

合规解决方案(白名单)

最好的防御代码注入漏洞的方式就是阻止包含可执行代码的用户输入。任何用于动态代码的用户输入,都必须进行无害化处理,例如,确保用户输入只包含白名单里的有效字符。最好是在数据输入后,通过使用用于存储和处理数据的提取方法,立即执行数据无害化处理。更多细节请参考“IDS00-J. Sanitize untrusted data passed across a trust boundary”[Long 2012]。如果用户名中必须包含某些特殊字符,那么必须先对它们进行标准化,然后再对它们进行表单输入验证处理。下面的合规解决方案使用了白名单来防止脚本引擎对未经处理的输入进行解析。

private static void evalScript(String firstName)
  throws ScriptException {
 // Allow only alphanumeric and underscore chars in firstName
 // (modify if firstName may also include special characters)
 if (!firstName.matches("[\\w]*")) {
  // String does not match whitelisted characters
  throw new IllegalArgumentException();
 }

 ScriptEngineManager manager = new ScriptEngineManager();
 ScriptEngine engine = manager.getEngineByName("javascript");
 engine.eval("print('"+ firstName + "')");
}```
####合规解决方案(安全沙盒)
另一种方式是使用安全管理器创建一个安全的沙盒(参见指南20)。应用程序应该阻止执行任意命令的脚本,如查询本地文件系统。双参数版本的doPrivileged()方法可用于处理更低特权的操作,这种情况下,应用程序本身必须执行更高特权的操作,但脚本引擎决不能拥有这样的特权。对于默认策略文件中那些新创建的保护域,RestrictedAccessControlContext类减少了授予它们的权限。这些有效权限是新创建的保护域和系统安全策略二者权限的交集。有关doPrivileged()方法的更多细节,请参考指南16。

下面的合规解决方案演示了如何在双参数版本的doPrivileged()中使用AccessControlContext。

class ACC {
 private static class RestrictedAccessControlContext {
  private static final AccessControlContext INSTANCE;

  static {
   INSTANCE =
    new AccessControlContext(
     new ProtectionDomain[] {
      new ProtectionDomain(null, null) // No permissions
     });
  }
 }

 private static void evalScript(final String firstName)
   throws ScriptException {
  ScriptEngineManager manager = new ScriptEngineManager();
  final ScriptEngine engine =
   manager.getEngineByName("javascript");
  // Restrict permission using the two-argument
  // form of doPrivileged()
  try {
   AccessController.doPrivileged(
    new PrivilegedExceptionAction

     public Object run() throws ScriptException {
      engine.eval("print('" + firstName + "')");
      return null;
     }
    },
    // From nested class
    RestrictedAccessControlContext.INSTANCE);
    } catch (PrivilegedActionException pae) {
     // Handle error
    }
  }
}`
将这个方法和白名单结合在一起使用,可以获得更高的安全性。

适用性

未能防止代码注入可能导致任意代码的执行。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
DES安全编码组件
  DES安全编码组件   支持 DES、DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR)   DES           key size must be equal to 56   DESede(TripleDES) key size must be equal to 112 or 168   AES      
991 0
java面试题:写代码使得分别出现StackOverflowError和OutOfMemoryError
今天做了个笔试,这是其中的一道题目:写代码使得分别出现StackOverflowError和OutOfMemoryError。 1.StackOverflowError   堆栈溢出错误一般是递归调用嘛。
717 0
MyEclipse中防止代码格式化时出现换行
    辛苦写完的代码,被Eclipse一格式化以后,本来想放在一行上的东西却被自动转成了多行,虽然自动换行以后可以在编辑器中一眼就能看到全部的代码,但是可读性却大打折扣,比如方法名及参数我喜欢放在一行上,自动格式化时给我拆成三、四行看着太乱了,避免出现这种情况的办法是:     1.Java代码     打开Eclipse的Window菜单,然后Preferences->Java->Code Style->Formatter->Edit/Show(根据不同版本可用的按钮会不一样) ->Line Wrapping->Maximum line width:由80改成800就行了。
731 0
都2020年了,你还不会写简洁的Java代码!
都2020年了,你还不会写简洁的Java代码!
676 0
《Java安全编码标准》一第 1 章 概  述
本节书摘来自华章出版社《Java安全编码标准》一书中的第1章,作者 (美)Fred Long,Dhruv Mohindra,Robert C. Seacord,Dean F. Sutherland,David Svoboda,更多章节内容可以访问云栖社区“华章计算机”公众号查看
852 0
《Java安全编码标准》一1.3 敏感数据泄露
本节书摘来自华章出版社《Java安全编码标准》一书中的第1章,第1.3节,作者 (美)Fred Long,Dhruv Mohindra,Robert C. Seacord,Dean F. Sutherland,David Svoboda,更多章节内容可以访问云栖社区“华章计算机”公众号查看
1673 0
05.Java网络编程(代码实践)
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路链接起来,在网络操作系统,网络管理软件及网络通信协议的协调下,实现资源贡献和信息传递的计算机系统 网络编程就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换 网...
786 0
java编码转换的详细过程
 常见的JAVA程序包括以下类别:*直接在console上运行的类(包括可视化界面的类)*JSP代码类(注:JSP是Servlets类的变型)*Servelets类*EJB类*其它不可以直接运行的支持类 这些类文件中,都有可能含有中文字符串,并且常用前三类JAVA程序和用户直接交互,用于输出和输入字符,如:在JSP和Servlet中得到客户端送来的字符,这些字符也包括中文字符。
1021 0
+关注
异步社区
异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。
12049
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载
《2021云上架构与运维峰会演讲合集》
立即下载