diff --git a/README.md b/README.md
index 1ac3fe7610e83bb2433129778dbcd8e4c252299c..c6372048f053cf122c8a16745a5c8d88cf083e57 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ All of the servers here are based on node.js, and some number of 3rd party node
 * vows (>= 0.5.8)
 * bcrypt (>= 0.2.3)
 * ejs (>= 0.4.3)
+* express-csrf (>= 0.3.2)
 
 ## Getting started:
 
diff --git a/browserid/app.js b/browserid/app.js
index c685e4915292b37d4f94e7d662ea80243517dda5..62193ab387997950e3e757946f2debe417b7678e 100644
--- a/browserid/app.js
+++ b/browserid/app.js
@@ -5,14 +5,16 @@ const          fs = require('fs'),
 var VAR_DIR = path.join(__dirname, "var");
 try { fs.mkdirSync(VAR_DIR, 0755); } catch(e) { };
 
-const         url = require('url'),
-            wsapi = require('./lib/wsapi.js'),
-        httputils = require('./lib/httputils.js'),
-        webfinger = require('./lib/webfinger.js'),
-         sessions = require('cookie-sessions'),
-          express = require('express'),
-          secrets = require('./lib/secrets.js'),
-               db = require('./lib/db.js');
+const
+  url = require('url'),
+  wsapi = require('./lib/wsapi.js'),
+  httputils = require('./lib/httputils.js'),
+  webfinger = require('./lib/webfinger.js'),
+  sessions = require('cookie-sessions'),
+  express = require('express'),
+  secrets = require('./lib/secrets.js'),
+  db = require('./lib/db.js'),
+  csrf = require('express-csrf');
 
 // looks unused, see run.js
 // const STATIC_DIR = path.join(path.dirname(__dirname), "static");
@@ -41,6 +43,7 @@ function router(app) {
   app.get('/register_iframe', internal_redirector('/dialog/register_iframe.html'));
 
   app.get('/', function(req,res) {
+      console.log("CSRF: " + req.session.csrf);
       res.render('index.ejs', {title: 'A Better Way to Sign In', fullpage: true});
     });
 
@@ -114,6 +117,13 @@ exports.setup = function(server) {
 
   server.use(express.bodyParser());
 
+  // we make sure that everyone has a session, otherwise we can't do CSRF properly
+  server.use(function(req, resp, next) {
+      if (typeof req.session == 'undefined')
+        req.session = {};
+      next();
+    });
+
   // a tweak to get the content type of host-meta correct
   server.use(function(req, resp, next) {
     if (req.url === '/.well-known/host-meta') {
@@ -128,6 +138,13 @@ exports.setup = function(server) {
       next();
     });
 
+  // setup CSRF protection
+  //server.use(csrf.check());
+
+  server.dynamicHelpers({
+      csrf: csrf.token
+        });
+  
   // add the actual URL handlers other than static
   router(server);
 }
diff --git a/browserid/lib/wsapi.js b/browserid/lib/wsapi.js
index 53c2096c4ab365acdd7de3d352a5a3d603f87386..57bccb035e72245d1b78649cf006a3017d9f4587 100644
--- a/browserid/lib/wsapi.js
+++ b/browserid/lib/wsapi.js
@@ -214,7 +214,7 @@ function setup(app) {
       }
     });
 
-  app.get('/wsapi/logout', function(req,resp) {
+  app.post('/wsapi/logout', function(req,resp) {
       req.session = {};
       httputils.jsonResponse(resp, "ok");
     });
diff --git a/browserid/static/dialog/controllers/dialog_controller.js b/browserid/static/dialog/controllers/dialog_controller.js
index 59b9e2b38516e2773525e51dfbe43a2201c9a51e..fe771e70f1ad53f078c7d436bf645e6b1ea0c81f 100644
--- a/browserid/static/dialog/controllers/dialog_controller.js
+++ b/browserid/static/dialog/controllers/dialog_controller.js
@@ -116,7 +116,7 @@ $.Controller("Dialog", {}, {
     "#notme click": function(event) {
       clearEmails();
       var self = this;
-      $.get("/wsapi/logout", function() {
+      $.post("/wsapi/logout", function() {
           self.doAuthenticate();
       });
     },
diff --git a/browserid/tests/forgotten-email-test.js b/browserid/tests/forgotten-email-test.js
index ecd259c8eabba3d83d9aa67187b1e77c244960ce..469978e75dd25862236dae90ff16a3de6e8afb5c 100755
--- a/browserid/tests/forgotten-email-test.js
+++ b/browserid/tests/forgotten-email-test.js
@@ -159,6 +159,12 @@ suite.addBatch({
       assert.strictEqual(JSON.parse(r.body), true);
     }
   },
+  "logout": {
+    topic: wsapi.post('/wsapi/logout', {}),
+    "should work": function(r, err) {
+      assert.strictEqual(JSON.parse(r.body), "ok");
+    }
+  },
   "second email, first pass good": {
     topic: wsapi.get('/wsapi/authenticate_user', { email: 'second@fakeemail.com', pass: 'firstfakepass' }),
     "should work": function(r, err) {
diff --git a/browserid/tests/lib/wsapi.js b/browserid/tests/lib/wsapi.js
index f4ff2c051518103dc7c8b548dd57efa952a50a61..2a15fc7b99c3ce44d0fa29735627109c06ca0303 100644
--- a/browserid/tests/lib/wsapi.js
+++ b/browserid/tests/lib/wsapi.js
@@ -46,3 +46,55 @@ exports.get = function (path, getArgs) {
     });
   };
 };
+
+// FIXME: dedup code
+
+// A macro for wsapi requests
+exports.post = function (path, postArgs) {
+  return function () {
+    var cb = this.callback;
+    if (typeof postArgs === 'object')
+      body = querystring.stringify(postArgs);
+
+    var headers = {
+      'content-type': 'application/x-www-form-urlencoded'
+    };
+
+    if (Object.keys(cookieJar).length) {
+      headers['Cookie'] = "";
+      for (var k in cookieJar) {
+        headers['Cookie'] += k + "=" + cookieJar[k];
+      }
+    }
+
+    var req = http.request({
+        host: '127.0.0.1',
+        port: '62700',
+        path: path,
+        headers: headers,
+        method: "POST"
+      }, function(res) {
+        // see if there are any set-cookies that we should honor
+        if (res.headers['set-cookie']) {
+          res.headers['set-cookie'].forEach(function(cookie) {
+              var m = /^([^;]+)(?:;.*)$/.exec(cookie);
+              if (m) {
+                var x = m[1].split('=');
+                cookieJar[x[0]] = x[1];
+              }
+            });
+        }
+        var body = '';
+        res.on('data', function(chunk) { body += chunk; })
+        .on('end', function() {
+            cb({code: res.statusCode, headers: res.headers, body: body});
+          });
+      }).on('error', function (e) {
+          cb();
+        });
+
+    // send the POST
+    req.write(body);
+    req.end();
+  };
+};