📜  标准做法在Java中保护敏感数据

📅  最后修改于: 2021-10-20 12:16:22             🧑  作者: Mango

Java平台提供了不同的权限级别和安全系统的强大的基础上执行代码的环境中通过诸如内存 安全。 Java语言和虚拟机使应用程序开发能够高度抵抗 C 和 C++ 编程语言中可能出现的常见编程错误、堆栈粉碎和缓冲区溢出攻击。但是,通过易受攻击的编程实践产生的错误可能会产生严重的安全后果,并且可能出现在堆栈的任何层中。在这篇文章中,我们将列出一些Java中的标准编程实践,以保护敏感数据。

安全编码指南包含以下参数:

  1. 释放资源
  2. 从异常中销毁敏感信息
  3. 避免动态 SQL
  4. 限制可访问性
  5. 限制可扩展性

让我们来讨论他们每个人的这些做法如何做到在保护我们的敏感数据在Java中的帮助,将与何地需要更好的理解性的示例代码帮助下讨论。

1. 释放资源

执行期间使用的应用程序资源,例如打开的文件、内存、对象和锁,如果在使用后不释放,可能会在处理过程中导致错误、重复和死锁。因此,资源应始终在使用后通过结合诸如 Execute Around Method(使用 lambda)和 try-with-resource 语法等技术来释放。

实施例1:示出了执行方法周边

// Main class
class GFG {

    // Main driver method
    public static void main(String[] args)
    {

        // Inserting code here

        // Execute Around pattern using Lambda
        // Clean-up is taken care of by lambda

        // Out lambda expression
        long sum = readFileBuffered(InputStream in -> {
            long current = 0;
            for (;;) {
                int b = in.read();
                if (b == -1) {
                    return current;
                }

                current += b;
            }
        });
    }
}

例2:龙虎斗试穿与资源语法

// Main class
class GFG {

    // Main driver method
    public static void main(String[] args)
    {

        // Inserting code here

        // Try-with-resource syntax
        public R readFileBuffered(
            InputStreamHandler handler) throws IOException
        {

            // Rry statement with one or more resources
            try (final InputStream in
                 = Files.newInputStream(path)) {
                handler.handle(new BufferedInputStream(in));
            }

            // By now the resource is closed
            // at the end of the statement execution
        }
    }
}

2. 从异常中销毁敏感信息

许多形式的攻击涉及猜测或了解文件的位置,例外情况可能包括有关系统配置和内部结构的敏感信息。抛出的异常诸如Java.io.FileNotFoundException的栈跟踪可包括可被攻击者利用回溯到系统文件和目标敏感数据的系统的文件路径。因此,在将内部异常传播给上游调用者之前,应该捕获并清理内部异常。

3.避免动态SQL

从不受信任的来源动态创建的 SQL 语句可能包含受命令注入影响的输入,这意味着通过 SQL 语句注入恶意代码以直接影响数据。相反,参数化的SQL语句,应使用诸如Java.sql.PreparedStatement或Java.sql.CallableStatement,这样的语句预编译,只需要参数,以便插入他们去执行。

样本

String sql = "SELECT * FROM User WHERE userId = ?"; 
PreparedStatement stmt = con.prepareStatement(sql); 
stmt.setString(1, userId); 
ResultSet rs = prepStmt.executeQuery();

4.限制无障碍

如果类成员、方法、构造函数和接口不是 API 的一部分,则应将它们声明为私有或受保护的,以避免暴露其实现。如果实现被封装并且不向外部实体公开,那么安全性将得到维护,因为外部人员将无法更改内部结构。

5.限制可扩展性

如果类或方法未声明为 final,则攻击者可以恶意覆盖它们。不允许继承的类更容易实现和验证它是安全的。更喜欢组合而不是继承。

例如,通过组成和最终极限类扩展

// Class 1
// Helper class- Book class
class Book {

    // Member variables of Book class
    public String title;
    public String author;

    // Parameterized constructor of Book class
    Book(String title, String author)
    {
        // This refers to current object itself
        this.title = title;
        this.author = author;
    }
}

// Class 2
// Helper class
// Unsubclassable class Library with composed behavior.
public final class Library {

    // Composition
    private final List books;

    // Hiding the constructor of this class
    // by declaring it private
    private Library(Book book)
    {
        books = new ArrayList();
    }

    // Method of this class
    // Guarded Construction of class methods
    private void createLibrary(Book book)
    {
        // ...validate any arguments...

        // ...perform security checks...

        // adding elements to the book
        books.add(book);
    }
} 

在本文中,我们解决了一些常见的陷阱和相关的解决方案。因此,最小化漏洞的最有效方法是明显没有缺陷而不是没有明显缺陷。这些都是一些多实践,Java程序员能够坚持以生产安全的Java应用程序。