Access Control: SecurityManager Bypass
Explanation
使用通过即时调用者的类加载器检查执行任务的 Java API 时应小心谨慎。这些 API 会绕过可确保已向执行链中的所有调用者授予了必需安全权限的 SecurityManager 检查。由于这些 API 可能会削弱系统安全性,因此不应在不可信认的代码上调用它们。
在这种情况下:
1. 可以通过公用函数访问封闭函数。
2. 当前应用程序存在 Process Control 和/或 Unsafe JNI (Java Native Interface) 漏洞。上述两个结果表明当前应用程序从不可信认的来源或不可信认的环境中加载库。不可信认的库可以使用 JNI访问此易受攻击的 API,从而获取对受限制程序包的访问权限并执行任意代码,导致应用程序容易受到远程攻击。
注:只有当应用程序配置有 SecurityManager 且代码包含在具有特定权限的类中时,此结果才适用。有关SecurityManager 和此漏洞的更多详细信息,请参见“Secure Coding Guidelines for the Java Programming Language”中的准则 9。
Recommendation
确保这些敏感的 API 无法通过不可信认的代码进行访问,并且无法在不可信认的代码上进行调用。此外,不得将此方法返回的对象传播回不可信认的代码。有关此漏洞的更多详细信息,请参见“Secure Coding Guidelines for the Java Programming Language”中的准则 9。
Access Specifier Manipulation
Explanation
AccessibleObject API 允许程序员绕过由 Java 访问说明符提供的 access control 检查。特别是它让程序员能够允许反映对象绕过 Java access control,并反过来更改私有字段或调用私有方法、行为,这些通常情况下都是不允许的。
Recommendation
只能使用攻击者无法设置的参数,通过有权限的类更改访问说明符。所有出现的访问说明符都应仔细检查。
Android Bad Practices: Missing Component Permission
Explanation
任何应用程序都能访问在显式定义中未明确分配访问权限的公共组件。Android 应用程序中活动、接收者和服务组件的 exported 属性的默认值取决于 intent-filter 是否存在。如果存在 intent-filter,说明该组件可供外部使用。因此应将 exported 属性设为 true。这样该组件就能被 Android 平台上的其他任何应用程序访问。
Recommendation
没有明确的访问权限的组件应该为异常。除非该组件确实需要被所有应用程序访问,否则开发人员应该通过在显式文件中明确定义访问权限来保护组件,以免其被恶意应用程序滥用。
Code Correctness: Class Does Not Implement equals
Explanation
当比较对象时,开发人员通常希望比较对象的属性。然而,在没有明确实现 equals() 的类(或任何超类/接口)上调用 equals() 会导致调用继承自 java.lang.Object 的 equals() 方法。Object.equals()将比较两个对象实例,查看它们是否相同,而不是比较对象成员字段或其他属性。尽管可以合法地使用Object.equals(),但这通常表示存在错误代码。
例 1:
public class AccountGroup
{
private int gid;
public int getGid() { return gid; }
public void setGid(int newGid) { gid = newGid; } }
...
public class CompareGroup {
public boolean compareGroups(AccountGroup group1, AccountGroup group2) {
return group1.equals(group2); //equals() is not implemented in AccountGroup
}
}
Recommendation
验证 Object.equals() 的使用确实是您要调用的方法。如果不是,那么可实现 equals() 方法,或者使用其他方法来比较对象。
例 2:以下代码将 equals() 方法添加到“说明”部分中的示例。
public class AccountGroup
{
private int gid;
public int getGid()
{
return gid;
}
public void setGid(int newGid)
{
gid = newGid;
}
public boolean equals(Object o)
{
if (!(o instanceof AccountGroup))
return false;
AccountGroup other = (AccountGroup) o;
return (gid == other.getGid());
}
}
...
public class CompareGroup
{
public static boolean compareGroups(AccountGroup group1, AccountGroup
group2)
{
return group1.equals(group2);
}
}
Code Correctness: Double-Checked Locking
Explanation
许多才智卓越的人都试图使用 double-checked locking 方法来提高性能,并为此付出了大量的时间,但是无一成功。
例 1:乍一看,下列代码似乎既能避免不必要的同步又能保证线程的安全性。
if (fitz == null) {
synchronized (this) {
if (fitz == null) {
fitz = new Fitzer();
}
}
}
return fitz;
程序员希望保证仅分配一个 Fitzer() 对象,但又不希望每次调用该代码时都进行一次同步。这就是所谓的double-checked locking 方法。令人遗憾的是,它并不起作用,并且可以分配多个 Fitzer() 对象。有关更多详细信息,请参见 The
"Double-Checked Locking is Broken" Declaration [1]。
Recommendation
其实同步所花费的代价比想象中的要少。许多情况下,最好的方法就是采用最简单的解决方法。
例 2: 例 1 中的代码应该用以下方式重写:
synchronized (this) {
if (fitz == null) {
fitz = new Fitzer();
}
return fitz;
}
Insecure Randomness
Explanation
在对安全性要求较高的环境中,使用一个能产生可预测数值的函数