堆检查安全漏洞
Heap Inspection Security Vulnerability
我有 运行 我的 java 应用程序针对安全漏洞的 checkmarx 工具,它不断出现问题 - 堆检查,我使用字符数组的密码字段。除了指出密码字段的声明之外,它没有给出任何解释。
private char[] passwordLength;
任何人都可以帮我解决这个问题吗?
堆检查是关于存储在未加密的机器内存中的敏感信息,因此如果攻击者执行内存转储(例如,Heartbleed 错误),该信息就会泄露。因此,仅仅持有这些信息就会使其变得脆弱。
可以通过以安全的方式存储此类敏感信息来缓解这种情况,例如使用 GuardedString 对象而不是 String 或 char 数组,或者对其进行加密并在短时间内擦除原始信息。
有关详细信息,请参阅 this CWE(描述 C/C++ 但与 Java 的相关性相同)。
请参阅 security.stackexchange.com 上的 this answer 以了解问题 "Is it more secure to overwrite the value char[] in a String"。
TLDR:你对此无能为力。
PS: 由于是姊妹stackexchange站点,这里就不复制答案了(另外,太长了)。如果版主不同意,请随意 copy/paste 它。
在 JVM 内存中存储秘密信息的示例方法
恕我直言,您应该使用 SealedObject
来存储在 JVM 内存中加密的凭据数据。
您需要以下软件包:
- java.security.SecureRandom
- javax.crypto.Cipher
- javax.crypto.KeyGenerator
- javax.crypto.SealedObject
- javax.crypto.SecretKey
所以你创造了
- 创建密钥的初始化密钥生成器
- 由密钥和安全随机数初始化的密码
- 然后你使用密码创建一个新的密封对象
- 您的凭据的所有存储和(临时)加载都已完成to/from 替换您的字符数组的密封对象。
Checkmarx 堆检查安全漏洞
大家好,当我在 Spring 应用程序中使用 String 类型变量作为密码时,我遇到了这个问题。喜欢下面
class User {
private String username;
private String password;
//setter
//getter
}
然后为了解决这个问题我做了以下步骤:
1. 创建 SecureString class 如下所示:
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;
}
}
}
已创建自定义 属性 编辑器:
进口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));
}
}
}
将此自定义 属性 编辑器注册到 spring-bean.xml 文件中:
我有 运行 我的 java 应用程序针对安全漏洞的 checkmarx 工具,它不断出现问题 - 堆检查,我使用字符数组的密码字段。除了指出密码字段的声明之外,它没有给出任何解释。
private char[] passwordLength;
任何人都可以帮我解决这个问题吗?
堆检查是关于存储在未加密的机器内存中的敏感信息,因此如果攻击者执行内存转储(例如,Heartbleed 错误),该信息就会泄露。因此,仅仅持有这些信息就会使其变得脆弱。
可以通过以安全的方式存储此类敏感信息来缓解这种情况,例如使用 GuardedString 对象而不是 String 或 char 数组,或者对其进行加密并在短时间内擦除原始信息。
有关详细信息,请参阅 this CWE(描述 C/C++ 但与 Java 的相关性相同)。
请参阅 security.stackexchange.com 上的 this answer 以了解问题 "Is it more secure to overwrite the value char[] in a String"。
TLDR:你对此无能为力。
PS: 由于是姊妹stackexchange站点,这里就不复制答案了(另外,太长了)。如果版主不同意,请随意 copy/paste 它。
在 JVM 内存中存储秘密信息的示例方法
恕我直言,您应该使用 SealedObject
来存储在 JVM 内存中加密的凭据数据。
您需要以下软件包:
- java.security.SecureRandom
- javax.crypto.Cipher
- javax.crypto.KeyGenerator
- javax.crypto.SealedObject
- javax.crypto.SecretKey
所以你创造了
- 创建密钥的初始化密钥生成器
- 由密钥和安全随机数初始化的密码
- 然后你使用密码创建一个新的密封对象
- 您的凭据的所有存储和(临时)加载都已完成to/from 替换您的字符数组的密封对象。
Checkmarx 堆检查安全漏洞 大家好,当我在 Spring 应用程序中使用 String 类型变量作为密码时,我遇到了这个问题。喜欢下面
class User {
private String username;
private String password;
//setter
//getter
}
然后为了解决这个问题我做了以下步骤: 1. 创建 SecureString class 如下所示:
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;
}
}
}
已创建自定义 属性 编辑器:
进口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)); } } }
将此自定义 属性 编辑器注册到 spring-bean.xml 文件中: