Some time ago, I found a mechanism to protect
- the control flow
- and all parameters
of web-application (controllers) against highjacking.
The technique provides this:
- All parameters of request are kept at the server side
- No parameter ever reaches any URL
- The control flow of an application strictly gets controlled by server-side state
The base principle is this:
- Define a controller FlowController
- If a web page needs to include a link to another controller with certain parameters, askFlowController to prepare the link
- FlowController does not provide the link directly, but maintains a server side state, which keeps all link-related information [controller class to be called, arguments to get passed]
- Ultimately, FlowController returns not an actual link, but a random hash-value, which identifies the server side’s state
- Once a hashed link comes back from the browser, it gets passed to FlowController, which looks up the related state and manages to instantiate the controller and pass arguments
Consequences:
- No link can be predicted.
- Thus, no controller can be called without before getting authorization by FlowController.
- All parameters retrieved form FlowController managed state passed to controllers can safely be trusted.
Moreover:
- FlowController manages link states using a stack
- FlowController provides set-back points: FlowControler::TerminateFlow() forces the application to re-establish the last set-back point.
- If FlowController gets asked to start a non-top flow, it automatically deletes all flows above. Thus, if you return to an earlier state of the application, all follow-up states automatically get invalidated.
Consequences: One can call certain workflows – sequences of controllers – in a pure subroutine fashion: Request a set-back point to get set. Run the first controller of the workflow. Eventually, some controller will call FlowControler::TerminateFlow() and the control-flow will return to the caller’s environment.
Note, that the first called controller – more general the whole workflow of several controllers - doesn’t know which other part of of the applications requested its execution. The initiator of the workflow started it using a fire-and-forget fashion: The workflow will eventually come back to me. At a certain point, the workflow signals, that it is done. Important: It does not request a certain continuation controller. Thus, the workflow is fully decoupled from any caller.
Comments?