使用高階合成方法

這個主題說明如何使用高階合成方法的一些主要特性。如需完整資料,請參閱 Framework for Frameworks API 類別及方法 Javadoc 說明文件。

建立高階合成方法

如果要建立高階合成方法,並將它新增至 F4FActions 物件 actions,請使用如下的程式碼:

HighLevelSyntheticMethod m = HighLevelSyntheticMethod.make();
actions.addHighLevelSyntheticMethod(m);

您可以將 VDB 方法簽章傳給 HighLevelSyntheticMethod.make(),以指定合成方法的名稱、參數類型及傳回類型。

建立區域變數

您可以使用下列方式建立高階合成方法 m 的新區域變數:

Local l = m.newLocal("java.lang.String");

合成方法中不需要呼叫建構子。根據上方的程式碼,可知將後續陳述式新增至合成方法時,l 會參照非空值的 String 物件。

新增呼叫

高階合成方法中的大部分陳述式都是透過 addCall() 方法而新增的方法呼叫。傳給 addCall() 的參數代表要呼叫的方法、呼叫的檔案位置資訊,以及呼叫時要傳遞的參數。以下是將呼叫新增至 setter 方法 sample.BeanType.setName() 的範例,其中假設 F4FApp 物件 app

Collection<IMethod> setterMethods =
   app.getClassMethods("sample.BeanType", "setName");
// assume there is exactly one "setName" method in BeanType
IMethod setter = setterMethods.iterator().next();
HighLevelSyntheticMethod m = HighLevelSyntheticMethod.make();
Local l = m.newLocal("sample.BeanType");
m.addCall(setter, null, l, Taint.taint());

依上述方式將適當的呼叫新增至合成方法,就可以在某種程度上將 MVS 架構中處理用戶端表單提交的步驟 2-5(如高階合成方法中的概述)全部建模。

呼叫的參數由下列任何一個類型 Param 的物件來代表:

  • Local 物件,代表區域變數
  • Taint 物件,代表未信任或受污染的資料。
  • EnclosingFormal 物件,代表高階合成方法的正規參數。例如,如果您的合成方法具有簽章 synthMethod(int):voidEnclosingFormal.FIRST 會參照方法的 int 參數。
  • Global 物件,代表廣域變數(在廣域變數中討論)。
註: 在非靜態實例方法中,要以 this 傳遞的值必須提供給 addCall()。在上方範例中,l 中的值會以 this 傳給 setName()

新增回覆值

合成方法可以利用 setReturnedValue() 方法來傳回值。回覆值對產生標記方法來建立複雜的架構驗證模型非常有用。例如,如果您使用的架構會先對受影響的 HTTP 要求值執行複雜的驗證,再將它傳給模型物件的 setter 方法,您可以利用如下的程式碼,顯現對 AppScan® 來源 所探索的追蹤資料所做的驗證:

String validatorSig =
   "Synth.validatorModel(java.lang.String):
   java.lang.String";
HighLevelSyntheticMethod validator =
   HighLevelSyntheticMethod.make(validatorSig);
// just return the parameter passed in
validator.setReturnedValue(EnclosingFormal.FIRST);
HighLevelSyntheticMethod m = ...;
Local validated = m.addCall(validatorSig, null, Taint.taint());
// now, validated can be passed to a setter

合成方法 Synth.validatorModel() 只會傳回傳給它作為參數的 String。然後,呼叫 Synth.validatorModel() 會在另一個合成方法中新增,並傳遞受汙染的值作為引數。這個呼叫的結果會儲存在 validated 中,其可在後續的呼叫中傳給 setter 方法(如 新增呼叫 中的範例所述)。包含這個受汙染資料的追蹤會包括 Synth.validatorModel() 的呼叫,且如果驗證已足夠,AppScan® 來源 使用者可以選擇過濾追蹤。

廣域變數

廣域變數是進階特性,可用來公開應用程式各不同組件之間的流程。例如,廣域變數可以透過要求或階段作業屬性,將控制器至視圖之間的資料流建模。建立和存取廣域變數的主要作業如下:

  • 如果要建立代表廣域變數的 Global 物件,請使用 F4FActions.createGlobal()
  • 如果要寫入廣域變數,請使用 HighLevelSyntheticMethod.addGlobalWrite()
  • 如果要讀取廣域變數,請在 HighLevelSyntheticMethod.addCall() 呼叫中以 Param 參數傳遞 Global 物件,或透過 HighLevelSyntheticMethod.setReturnedValue() 從合成方法傳回此物件。

範例:控制器類別將使用者的名字寫入要求屬性 firstName,然後由視圖讀取這個要求屬性,並將值呈現給回應。以高階方式,這個流程可以建模為:

Global firstNameGlobal = actions.createGlobal
   ("firstName", "java.lang.String", true);
HighLevelSyntheticMethod controller = ...;
Local firstNameLocal = controller.newLocal("java.lang.String");
controller.addGlobalWrite(firstNameGlobal, firstNameLocal, null);
HighLevelSyntheticMethod view = ...;
view.addCall("Response.write(java.lang.String):void",
   null, firstNameGlobal);

在控制器合成方法中新增 firstNameGlobal 的寫入,然後在 view 合成方法中將 firstNameGlobal 傳給 Response.write(),就會公開從控制器至視圖的資料流。

註: 這個範例簡化許多部分。所以,完整版本需要將適當的資料流公開給 firstNameLocal