堆检查安全漏洞

15

我已经对我的Java应用程序运行了Checkmarx工具以查找安全漏洞,但它一直出现Heap Inspection问题。该问题是针对我使用字符数组作为密码字段的声明而发生的,除了指出密码字段的声明外,它没有提供任何更多的解释。

private char[] passwordLength;

有人能帮我解决这个问题吗?还能找些什么来解决它?

4个回答

8
堆检查是指敏感信息以未加密的形式存储在机器内存中,因此如果攻击者执行内存转储(例如,Heartbleed漏洞),则该信息将被泄露。因此,仅持有该信息就使其易受攻击。
可以通过以安全方式存储此类敏感信息来减轻这种风险,例如使用GuardedString对象而不是String或char数组进行存储,或加密并在原始数据清除后处理。
有关更多信息,请参见此CWE(描述C/C++,但对Java同样适用):https://cwe.mitre.org/data/definitions/244.html

4

在JVM内存中存储秘密信息的示例方法

我认为您应该使用SealedObject将凭据数据加密存储在JVM内存中。

您需要以下软件包:

  • java.security.SecureRandom
  • javax.crypto.Cipher
  • javax.crypto.KeyGenerator
  • javax.crypto.SealedObject
  • javax.crypto.SecretKey

因此,您需要创建:

  • 初始化密钥生成器以创建一个密钥
  • 由密钥和安全随机数初始化的密码器
  • 然后使用密码器创建新的封闭对象
  • 所有凭据的存储和(临时)加载均通过封闭对象完成,该对象替换了字符数组。

可在以下位置找到工作示例:https://github.com/Daimler/sechub/blob/3f176a8f4c00b7e8577c9e3bea847ecfc91974c3/sechub-commons-core/src/main/java/com/daimler/sechub/commons/core/security/CryptoAccess.java


3

请看这个回答,针对“覆盖String中char[]的值是否更安全”的问题,来自security.stackexchange.com

简而言之:您无法为此做太多事情。

附言:因为那是一个姊妹站点,我不会在这里复制回答(而且太长了)。如果管理员不同意,请随意复制/粘贴。


1

Checkmarx堆检查安全漏洞 大家好,当我在我的Spring应用程序中使用String类型的变量作为密码时,我遇到了这个问题。如下所示:

  class User {
     private String username;
     private String password;
         //setter 
         //getter
     }

然后为了解决这个问题,我采取了以下步骤: 1. 创建如下的SecureString类:
   import java.security.SecureRandom;
   import java.util.Arrays;

   /**
    * This is not a string but a CharSequence that can be cleared of its memory.
    * Important for handling passwords. Represents text that should be kept
   * confidential, such as by deleting it from computer memory when no longer
   * needed or garbage collected.
   */

  /**
  * Created by Devendra on 16/04/2020
  */

  public class SecureString implements CharSequence {

    private final int[] chars;
    private final int[] pad;

    public SecureString(final CharSequence original) {
        this(0, original.length(), original);
    }

    public SecureString(final int start, final int end, final CharSequence original) {
        final int length = end - start;
        pad = new int[length];
        chars = new int[length];
        scramble(start, length, original);
    }

    @Override
    public char charAt(final int i) {
        return (char) (pad[i] ^ chars[i]);
    }

    @Override
    public int length() {
        return chars.length;
    }

    @Override
    public CharSequence subSequence(final int start, final int end) {
        return new SecureString(start, end, this);
    }

    /**
     * Convert array back to String but not using toString(). See toString() docs
     * below.
     */
    public String asString() {
        final char[] value = new char[chars.length];
        for (int i = 0; i < value.length; i++) {
            value[i] = charAt(i);
        }
        return new String(value);
    }

    /**
     * Manually clear the underlying array holding the characters
     */
    public void clear() {
        Arrays.fill(chars, '0');
        Arrays.fill(pad, 0);
    }

    /**
     * Protect against using this class in log statements.
     * <p>
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "Secure:XXXXX";
    }

    /**
     * Called by garbage collector.
     * <p>
     * {@inheritDoc}
     */
    @Override
    public void finalize() throws Throwable {
        clear();
        super.finalize();
    }

    /**
     * Randomly pad the characters to not store the real character in memory.
     *
     * @param start start of the {@code CharSequence}
     * @param length length of the {@code CharSequence}
     * @param characters the {@code CharSequence} to scramble
     */
    private void scramble(final int start, final int length, final CharSequence 
    characters) {
        final SecureRandom random = new SecureRandom();
        for (int i = start; i < length; i++) {
            final char charAt = characters.charAt(i);
            pad[i] = random.nextInt();
            chars[i] = pad[i] ^ charAt;
        }
    }

}
  1. Created custom property editor as :

    import java.beans.PropertyEditorSupport; import org.springframework.util.StringUtils;

    public class SecureStringEditor extends PropertyEditorSupport {
    
    
       @Override
        public String getAsText() {
           SecureString  value =(SecureString) getValue();
           SecureString  secStr = new SecureString(value);
            return (value != null) ? secStr.asString() : "";
        }
    
        @Override
        public void setAsText(String text) throws java.lang.IllegalArgumentException {
            if (StringUtils.isEmpty(text)) {
                setValue(null);
            } else {
                setValue(new SecureString(text));
            }
        }
    }
    
  2. Register this custom property editor to spring-bean.xml file as :


第三步在这里:<!--将自动将String转换为SecureString,反之亦然--> <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="customEditors"> <map> <entry key="com.test.utils.SecureString" value="com.test.utils.SecureStringEditor"/> </map> </property> </bean> - Devendra Singraul
之后使用SecureString类型代替String类型存储密码。 - Devendra Singraul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接