当字段类型未知时,对访问字段机密的反射改进 [英] Reflection improvements to access field secret, when field type is unknown
问题描述
我正在学习安全性并希望以明文方式存储机密.
当我检索私有字段的内容时,它返回一个对象.我的恶意代码正确地假定并将对象转换为 int,但是如果我将字段类型从 int secretInt = 42;
更改/解析为 String secretInt = (new Integer(42).intValue()).tostring
Mal 代码惨遭失败.
I am learning about Security and looking at storing secrets in the clear.
When I retrieve the contents of a private field, it returns an Object. My mal code correctly assumes and casts the Object as an int, however if I change/parse the field type from int secretInt = 42;
to String secretInt = (new Integer(42).intValue()).tostring
the Mal code fails miserably.
不寻常的包装 (new Integer(42).intValue()).tostring
是由自动解析器创建的,它不是由程序员编写的.
The unusual wrapping (new Integer(42).intValue()).tostring
is created by a automated parser, it is not written by a programmer.
如何为 Mal 代码添加健壮性,以便删除返回类型的假设.这可能吗?我需要将此值用作 int 参数.
how can I add robustness to Mal code so the assumption of the returned type is removed. Is this possible? I need to use this value as int param.
'String' 是一个例子,但解析器可能会选择一种不合适的数据结构,如 byte[]、char[].
'String' is one example but the parser may choose a data-structure as suitably-inappropriate as byte[], char[].
这是我的不合规代码.
public final class SecretInClear implements Check4SecretsInClear {
//Non-Compliant: Secret int stored in Clear.
private final int secretInt = 42;
@Override
public boolean isSecretInt(int check) {
return (check == secretInt);
}
}
这是我的恶意代码.
public class ReadClearSecret implements Tester {
//Example of running
public static void main(String[] args) {
String testResult = new ReadClearSecret().test(new SecretInClear());
System.out.println(testResult);
}
private Object readPrivateField(Object o, String fieldName) {
try {
Field field = o.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(o);
} catch(Exception e) {
throw new IllegalArgumentExecption(e);
}
@Override
public String test(final Object secretChecks) {
final Check4SecretsInClear check4SecretsInClear = (Check4SecretsInClear)secretChecks;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("class:").
append(check4SecretsInClear.getClass().getSimpleName());
boolean bSecretInt = false;
String s = "";
try {
int secretInt = (Integer)readPrivateField(check4SecretsInClear,"secretInt"); //<<< HERE! It's cast as an integer!!!
bSecretInt = check4SecretsInClear.isSecretInt(secretInt); //<<< HERE! Param must be an int.
} catch (ClassCastException e) {
s = "," + e.getClass().getSimpleName();
} finally {
stringBuilder.append(" int:").append(bSecretInt).append(s);
s = "";
}
return stringBuilder.toString();
}
}
而不是从 readPrivateField()
转换 (int).相反,我提取字符串值 String.valueOf(Object)
或 Object.toString()
.然后我可以将该字符串作为带有 new Integer(stringValue)
的 int 参数传递.
Instead of casting (int) from readPrivateField()
. Instead I extract the string value String.valueOf(Object)
or Object.toString()
. I can then pass that string as a int param with new Integer(stringValue)
.
然而:
如果解析器选择将 secretInt
表示为 byte[] 类型,则字符串值将是疯狂的,并且恶意代码将被篡改.有什么建议可以对此产生稳健性吗?
HOWEVER:
If the parser chooses to represent secretInt
as type byte[] the string value will be nuts and the mal code will be pwned. Any suggest to produce robustness against this?
推荐答案
CR Peter Lawrey
如果您知道答案是适当不合适的,则不能在代码中一般不使用.您需要阅读 isSecretInt
的字节码以了解它是如何完成的,为此,人类是最简单的解决方案 ;) –
CR Peter Lawrey
If it is suitably inappropriate you know the answer, it can't be don't generically in code. You need to read the byte code of isSecretInt
to see how it is done, and for that a human is the simplest solution ;) –
这篇关于当字段类型未知时,对访问字段机密的反射改进的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!