Using high-level synthetic methods
This topic illustrates how to use some of the key features of high-level synthetic methods. For full details, see the Framework for Frameworks API classes and methods Javadoc™ documentation.
Creating a high-level synthetic method
To create a high-level synthetic method and add it
to the F4FActions object actions,
use code such as:
HighLevelSyntheticMethod m = HighLevelSyntheticMethod.make();
actions.addHighLevelSyntheticMethod(m);You can specify
the name, parameter types, and return type of the synthetic method
by passing a VDB method signature to HighLevelSyntheticMethod.make().
Creating locals
A new
local variable for a high-level synthetic method m can
be created in this manner:
Local l = m.newLocal("java.lang.String");Constructors
need not be invoked in synthetic methods. Given the above code, one
can assume that l refers to a non-null String object
when adding further statements to the synthetic method.
Adding calls
Most statements
in high-level synthetic methods will be method calls, added via the addCall() method.
The parameters to addCall() represent the method
to be invoked, file position information for the invocation, and parameters
to be passed at the invocation. This is an example for adding a call
to a setter method sample.BeanType.setName(), assuming
an F4FApp object 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());Steps 2-5 of handling client form submission in an MVC architecture (as outlined in High-level synthetic methods) can all be modelled to some degree by adding appropriate calls to a synthetic method in the manner shown above.
The parameters for a call
are represented by objects of type Param, which can
be any one of:
- A
Localobject, representing a local - A
Taintobject, representing untrusted or tainted data. - An
EnclosingFormalobject, representing a formal parameter of the high-level synthetic method. For example, if you have a synthetic method with signaturesynthMethod(int):void,EnclosingFormal.FIRSTrefers to theintparameter of the method. - A
Globalobject representing a global (discussed in Globals).
this must be provided to addCall().
In the above example, the value in l will be passed
as this to setName().Adding a return value
A
synthetic method can return a value by using the setReturnedValue() method.
Return values can be useful for generating marker methods to model
complex framework validation. For example, if you are using a framework
that performs complex validation of a tainted HTTP request value before
passing it to the setter method of a model object, you can expose
the validation on traces discovered by AppScan®
Source by
using code such as this:
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 setterThe synthetic
method Synth.validatorModel() simply returns the String that
is passed to it as a parameter. Then, a call to Synth.validatorModel() is
added in another synthetic method, passing a tainted value as an argument.
The result of this call is stored in validated, which
can be passed in a subsequent call to a setter method (as illustrated
by example in Adding calls).
Traces involving this tainted data will include the call to Synth.validatorModel(),
and an AppScan®
Source user
can choose to filter the traces if the validation is deemed sufficient.
Globals
Globals are an advanced feature that can be used to expose flow between disparate parts of an application. For example, globals can be used to model the flow of data from a controller to a view via request or session attributes. The key operations for creating and accessing globals are:
- To create a
Globalobject representing a global, useF4FActions.createGlobal(). - To write to a global, use
HighLevelSyntheticMethod.addGlobalWrite(). - To read from a global, pass the
Globalobject as aParamparameter in a call toHighLevelSyntheticMethod.addCall()- or have it returned from a synthetic method viaHighLevelSyntheticMethod.setReturnedValue().
Example: A controller class writes a user's first name
to the request attribute firstName, and then the
view reads this request attribute and renders the value to the response.
At a high level, one could model this flow as:
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);By adding a write to firstNameGlobal in
the controller synthetic method and then passing firstNameGlobal to Response.write() in
the view synthetic method, the data flow from controller
to the view is exposed.
firstNameLocal.