Уязвимость безопасности проверки кучи

Я запустил свое java-приложение против инструмента checkmarx на предмет уязвимости безопасности, и он постоянно выдает проблему - проверка кучи для моего поля пароля, для которого я использую массив символов. Это не дает больше объяснений, чем просто указание объявления поля пароля.

private char[] passwordLength;

Может ли кто-нибудь помочь мне здесь, что еще я могу найти для решения этой проблемы?


person Gaurav Sachdeva    schedule 20.05.2015    source источник


Ответы (4)


Heap Inspection — это конфиденциальная информация, хранящаяся в памяти компьютера в незашифрованном виде, поэтому, если злоумышленник выполнит дамп памяти (например, ошибка Heartbleed), эта информация будет скомпрометирована. Таким образом, простое хранение этой информации делает ее уязвимой.

Это можно смягчить, сохранив такую ​​конфиденциальную информацию безопасным способом, например, объект GuardedString вместо строки или массива символов, или зашифровав ее и очистив оригинал вскоре после этого.

Для получения дополнительной информации см. эту CWE (описывает C/C++, но такая же релевантность для Java ).

person Checkmarx Support    schedule 26.05.2015

См. этот ответ на security.stackexchange.com на вопрос "Более безопасно чтобы перезаписать значение char[] в строке".

TLDR: Вы ничего не можете с этим поделать.

PS: Поскольку это родственный сайт обмена стеками, я не копирую здесь ответ (к тому же он слишком длинный). Если модератор не согласен, скопируйте/вставьте его.

person David Balažic    schedule 04.04.2019

Уязвимость Checkmarx Heap Inspection Security Привет всем, я столкнулся с этим, когда использовал переменную типа String в качестве пароля в своем приложении Spring. Как ниже

  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. Создан пользовательский редактор свойств как:

    импортировать java.beans.PropertyEditorSupport; импортировать 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. Зарегистрируйте этот пользовательский редактор свойств в файле spring-bean.xml как:

person Devendra Singraul    schedule 27.05.2020
comment
Шаг 3: ‹!--автоматически преобразует 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› - person Devendra Singraul; 27.05.2020
comment
После этого используйте тип SecureString вместо String для пароля. - person Devendra Singraul; 27.05.2020

Example approach to store secret information in JVM memory

ИМХО, вы должны использовать 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

person de-jcup    schedule 19.11.2019