diff --git a/lib/wsapi.js b/lib/wsapi.js
index 8b7c2881a750fa4c94462e883f3ac69a8d83052b..8df4ff9aca5077991229e8474787774bb9ac602e 100644
--- a/lib/wsapi.js
+++ b/lib/wsapi.js
@@ -179,29 +179,20 @@ exports.setup = function(options, app) {
             cookieSessionMiddleware(req, resp, function() {
               // only on POSTs
               if (req.method === "POST") {
-                var denied = false;
 
-                if (req.session === undefined) { // there must be a session
-                  denied = true;
-                  logger.warn("CSRF validation failure: POST calls to /wsapi require an active session");
-                }
-
-                // the session must have a csrf token
-                else if (typeof req.session.csrf !== 'string') {
-                  denied = true;
-                  logger.warn("CSRF validation failure: POST calls to /wsapi require an csrf token to be set");
+                if (req.session === undefined || typeof req.session.csrf !== 'string') { // there must be a session
+                  logger.warn("POST calls to /wsapi require a cookie to be sent, this user may have cookies disabled");
+                  return httputils.badRequest(resp, "no cookie");
                 }
 
                 // and the token must match what is sent in the post body
                 else if (!req.body || !req.session || !req.session.csrf || req.body.csrf != req.session.csrf) {
-                  denied = true;
                   // if any of these things are false, then we'll block the request
                   var b = req.body ? req.body.csrf : "<none>";
                   var s = req.session ? req.session.csrf : "<none>";
                   logger.warn("CSRF validation failure, token mismatch. got:" + b + " want:" + s);
+                  return httputils.badRequest(resp, "CSRF violation");
                 }
-
-                if (denied) return httputils.badRequest(resp, "CSRF violation");
               }
               return next();
             });
diff --git a/tests/lib/wsapi.js b/tests/lib/wsapi.js
index 0ec1997ab0d7984c84eed5f1384166ba211eee94..0bfd9989cce0914e027b4603a3cfdf0a61a73c1b 100644
--- a/tests/lib/wsapi.js
+++ b/tests/lib/wsapi.js
@@ -32,3 +32,10 @@ exports.post = function (path, postArgs) {
     wcli.post(configuration, path, context, postArgs, this.callback);
   };
 };
+
+exports.getCSRF = function() {
+  if (context && context.session && context.session.csrf_token) {
+    return context.session.csrf_token;
+  }
+  return null;
+};
\ No newline at end of file
diff --git a/tests/no-cookie-test.js b/tests/no-cookie-test.js
new file mode 100755
index 0000000000000000000000000000000000000000..6a030d218fd27499e63d6746c5591b90419bc431
--- /dev/null
+++ b/tests/no-cookie-test.js
@@ -0,0 +1,104 @@
+#!/usr/bin/env node
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+require('./lib/test_env.js');
+
+const
+assert = require('assert'),
+vows = require('vows'),
+start_stop = require('./lib/start-stop.js'),
+wsapi = require('./lib/wsapi.js'),
+http = require('http');
+
+var suite = vows.describe('registration-status-wsapi');
+
+// ever time a new token is sent out, let's update the global
+// var 'token'
+var token = undefined;
+
+// start up a pristine server
+start_stop.addStartupBatches(suite);
+
+// now start a registration
+suite.addBatch({
+  "start registration": {
+    topic: wsapi.post('/wsapi/stage_user', {
+      email: 'first@fakeemail.com',
+      site:'fakesite.com'
+    }),
+    "returns 200": function(err, r) {
+      assert.strictEqual(r.code, 200);
+    }
+  }
+});
+
+// wait for the token
+suite.addBatch({
+  "a token": {
+    topic: function() {
+      start_stop.waitForToken(this.callback);
+    },
+    "is obtained": function (t) {
+      assert.strictEqual(typeof t, 'string');
+      token = t;
+    }
+  }
+});
+
+suite.addBatch({
+  "completing user creation": {
+    topic: function() {
+      wsapi.post('/wsapi/complete_user_creation', { token: token, pass: 'firstfakepass' }).call(this);
+    },
+    "works": function(err, r) {
+      assert.equal(r.code, 200);
+      token = undefined;
+    }
+  }
+});
+
+suite.addBatch({
+  "attempt to auth without cookie": {
+    topic: function() {
+      var cb = this.callback;
+
+      var req = http.request({
+        host: '127.0.0.1',
+        port: 10002,
+        path: '/wsapi/authenticate_user',
+        headers: { 'Content-Type': 'application/json' },
+        method: "POST",
+        agent: false // disable node.js connection pooling
+      }, function(res) {
+        var body = '';
+        res.on('data', function(chunk) { body += chunk; })
+          .on('end', function() {
+            cb(null, {code: res.statusCode, headers: res.headers, body: body});
+          });
+      }).on('error', function (e) {
+        cb(e);
+      });
+      req.write(JSON.stringify({
+        csrf: wsapi.getCSRF(),
+        email: 'first@fakeemail.com',
+        pass: 'firstfakepass'
+      }));
+      req.end();
+    },
+    "returns a 400 with 'no cookie' as the body": function(err, r) {
+      assert.equal(err, null);
+      assert.equal(r.code, 400);
+      assert.equal(r.body, 'Bad Request: no cookie');
+    }
+  }
+});
+
+// shut the server down and cleanup
+start_stop.addShutdownBatches(suite);
+
+// run or export the suite.
+if (process.argv[1] === __filename) suite.run();
+else suite.export(module);