A brand new mechanism has been implemented to protect Simple HTTP API against CSRF attack. So far, the API was vulnerable to CSRF attack, server accepted all requests, including the malicious ones, which can be called from an arbitrary page (published on a different domain) and exploits CloverETL Server account of unsuspecting user to execute an action on the server (e.g. execute graph).
Example of the CSRF attack:
1) a user logs to CloverETL console
2) now he is able to execute Simple HTTP API methods, e.g. run graph: http://127.0.0.1:8080/clover/simpleHttpApi/graph_run?sandbox=default&graphID=graph%2Ftest.grf&nodeID=node1&verbose=MESSAGE
3) the user goes to an infected page, located on a different domain than CloverETL Server Console
4) the infected page contains e.g. image with source attribute _http://127.0.0.1:8080/clover/simpleHttpApi/graph_run?sandbox=default&graphID=graph%2Ftest.grf&nodeID=node1&verbose=MESSAGE_
5) loading the image executes graph, because the user is logged in the CloverETL Server Console
CSRF protection mechanism:
Since now, such a case is not possible anymore.
Each call to Simple HTTP API requires presence of a HTTP header called X-Requested-By. All requests without the header are marked as invalid and return with status 400 (Bad Request).
Example with curl:
Note: value of the header is not important.
The header can be added to AJAX request, but only when the source page (where is the request created) is located in the same domain as CloverETL Server (browsers don't permit cross domain AJAX requests by default).
There is another way how to call Simple HTTP API. CloverETL Server accepts parameter csrftoken, but it is intended to be used only within clover/httpapi.jsp page, because there is no API to obtain value of this parameter. Parameter is sent in the query string (links) or as a hidden field (forms).
It is possible to disable CRSFT protection via the security.csrf.protection.enabled server configuration property.
- simple HTTP API calls require presence of HTTP header "X-Requested-By". Value of the header is not important, can be set to any value
- if the HTTP header is not present, we return HTTP response code 400 (bad request)
- CRSF protection can be disabled via the security.csrf.protection.enabled server configuration property, by default it's enabled