本節書摘來異步社群《java編碼指南:編寫安全可靠程式的75條建議》一書中的第1章,第1.21節,作者:【美】fred long(弗雷德•朗), dhruv mohindra(德魯•莫欣達), robert c.seacord(羅伯特 c.西科德), dean f.sutherland(迪恩 f.薩瑟蘭), david svoboda(大衛•斯沃博達),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
回調提供一種注冊方法的手段,在其感興趣的事件發生時将會被調用(或回調。java在很多地方都使用了回調, 如applet技術、響應servlet的生命周期事件、awt和swing架構中的事件通知(如按鈕單擊事件),以及異步的讀寫操作等。甚至線上程的運作機制runnable.run()中,新起一個線程時,自動執行對應的run()方法都使用到了回調技術。
在java中,回調函數通常是使用接口來實作。下面是回調的一般結構:
public interface callback {
void callmethod();
}
class userlookupcallback implements callback {
private int uid;
private string name;
public userlookupcallback(int uid) {
this.uid = uid;
}
public string getname() {
return name;
public void callmethod() {
try (inputstream fis = new fileinputstream("/etc/passwd")) {
// look up uid & assign to name
} catch (ioexception x) {
name = null;
}
final class callbackaction {
private callback callback;
public callbackaction(callback callback) {
this.callback = callback;
public void perform() {
accesscontroller.doprivileged(new privilegedaction() {
public void run() {
callback.callmethod();
return null;
}
});
}<code>`</code>
這段代碼可以被用戶端安全地使用,如下所示:
class maliciouscallback implements callback {
// code here gets executed with elevated privileges
// client code
public static void main(string[] args) {
callback callback = new maliciouscallback();
callbackaction action = new callbackaction(callback);
action.perform(); // executes malicious code
合規解決方案(回調自己調用doprivileged塊)
根據oracle公司的安全編碼指南[scg 2010]:
按照慣例,privilegedaction的執行個體和privilegedexceptionaction的執行個體可以提供給不可信代碼,但不能以調用者提供的動作調用doprivileged。
下面的合規解決方案将doprivileged()的調用從callbackaction代碼中移到了它自己的回調裡。
final class userlookupcallback implements callback {
// ...
// remaining code is unchanged<code>`</code>
通過回調暴露敏感方法可能導緻特權誤用和任意代碼執行。