我正在学习安全性并着眼于明确存储机密。
当我检索私有字段的内容时,它返回一个Object。我的错误代码正确地假设并将Object转换为int,但是如果我将字段类型从int secretInt = 42;
更改/解析为String secretInt = (new Integer(42).intValue()).tostring
,则Mal代码会失败。
编辑:异常包装(new Integer(42).intValue()).tostring
由自动解析器创建,不是由程序员编写的。
如何为Mal代码添加健壮性,以便删除返回类型的假设。这可能吗?我需要将此值用作int参数。
编辑:'字符串'是一个示例,但解析器可能选择的数据结构与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参数传递。
HOWEVER:
如果解析器选择将secretInt
表示为byte []类型,则字符串值将是疯狂的,并且将错误地输入错误代码。有人建议对此产生稳健性吗?
答案 0 :(得分:0)
Field.get()的返回类型是一个Object。如果你需要知道它的类,你可以调用Field.getType()
,但通常你不需要知道类型,只需要知道所包含的信息。
你可以做到
String secret = "42";
或
@Override
public boolean isSecretInt(int check) {
return check / 6.0 == 7;
}
不要使用Integer来比较值,因为这会比较对象,而不是它们的值。
较短的实施
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);
}
}
System.out.println(Integer.toString(6 * 9, 13));
打印
42
)
答案 1 :(得分:0)
您可以随时使用:
String value = String.valueOf(field.get(o));
为了避免关心类型是什么,总是给你一个字符串。
答案 2 :(得分:0)
CREDIT: Peter Lawrey
如果你知道答案是不恰当的,那么在代码中一般不能这样做。您需要读取isSecretInt
的字节代码以了解它是如何完成的,为此人类是最简单的解决方案;) -