ruby-on-railswebsocketcsrffaye

request.session['_csrf_token'] and meta tag csrf_token doesn't match


I have implemented real-time chat using websockets with Faye in Rails 4.2

Right now I can publish a message to channels using curl like:

curl http://localhost:3000/faye -d message={"channel":"/mychannel", "data": "my message"}'

To prevent this, I followed the guide http://faye.jcoglan.com/security/csrf.html

But client always got 401 error

[,…]
0: {id: "8l", channel: "/meta/handshake", error: "401::Access denied", successful: false, version: "1.0",…}
advice: {reconnect: "handshake"}
channel: "/meta/handshake"
error: "401::Access denied"
id: "8l"
successful: false
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket", "eventsource",…]
version: "1.0"

I also debug token variables inside CsrfProtection extension. They always differ.

Started POST "/faye" for 127.0.0.1 at 2016-02-20 02:53:59 +0600
session_token: "nICoUB0sDiwmNqbRpr1kUM7LtyBybCiddThnZceU7UI="
message_token: "PO5gD5tPwVMZifrUCsk8xnJXUIRZkhOU/vQ+ujbmQAugbshfhmPPfz+/XAWsdFiWvJznpCv+OwmLzFnf8XKtSQ=="

Why they differ and how do I implement csrf protection?


Solution

  • The method from Rails code may help: token validation

    Idea: on the page you have Base64 encoded value and you need to decode it