Tokenized REST API POST handler

POST requests typically modify server state, and are often vulnerable
to XSRF attacks.  For example, a site admin could be fooled into
clicking a button on a rogue website which causes his browser to run
REST commands against the server.

To prevent against this, REST POST requests should include a token
which is first retrieved by making a GET request to the same URL.
This token allows us to verify that the user visited the Gerrit site
and helps protect against XSRF.

An example use-case of this new API:

 token = $(curl --anyauth -u [user] http://review/a/rest-api | tail -n 1)
 curl --anyauth -u [user] -d $token http://review/a/rest-api

Signed-off-by: Brad Larson <bklarson@gmail.com>
Change-Id: I18f3ad2b6be4df2e5a6fa3262de5a2f4601fccea
This commit is contained in:
Brad Larson
2012-07-25 11:41:22 -05:00
committed by Shawn O. Pearce
parent 513e86debe
commit 3a6f077932
12 changed files with 575 additions and 71 deletions

View File

@@ -22,6 +22,7 @@ import com.google.gerrit.httpd.CacheBasedWebSession;
import com.google.gerrit.httpd.GitOverHttpModule;
import com.google.gerrit.httpd.HttpCanonicalWebUrlProvider;
import com.google.gerrit.httpd.RequestContextFilter;
import com.google.gerrit.httpd.SignedTokenRestTokenVerifier;
import com.google.gerrit.httpd.WebModule;
import com.google.gerrit.httpd.WebSshGlueModule;
import com.google.gerrit.httpd.auth.openid.OpenIdModule;
@@ -294,6 +295,7 @@ public class Daemon extends SiteProgram {
modules.add(new DefaultCacheFactory.Module());
modules.add(new SmtpEmailSender.Module());
modules.add(new SignedTokenEmailTokenVerifier.Module());
modules.add(new SignedTokenRestTokenVerifier.Module());
modules.add(new PluginModule());
if (httpd) {
modules.add(new CanonicalWebUrlModule() {

View File

@@ -85,5 +85,9 @@ class InitAuth implements InitStep {
if (auth.getSecure("registerEmailPrivateKey") == null) {
auth.setSecure("registerEmailPrivateKey", SignedToken.generateRandomKey());
}
if (auth.getSecure("restTokenPrivateKey") == null) {
auth.setSecure("restTokenPrivateKey", SignedToken.generateRandomKey());
}
}
}