{"action":"created","issue":{"url":"https://api.github.com/repos/elixir-lang/plug/issues/248","labels_url":"https://api.github.com/repos/elixir-lang/plug/issues/248/labels{/name}","comments_url":"https://api.github.com/repos/elixir-lang/plug/issues/248/comments","events_url":"https://api.github.com/repos/elixir-lang/plug/issues/248/events","html_url":"https://github.com/elixir-lang/plug/issues/248","id":81410004,"number":248,"title":"Mask CSRF token","user":{"login":"c-rack","id":169184,"avatar_url":"https://avatars.githubusercontent.com/u/169184?v=3","gravatar_id":"","url":"https://api.github.com/users/c-rack","html_url":"https://github.com/c-rack","followers_url":"https://api.github.com/users/c-rack/followers","following_url":"https://api.github.com/users/c-rack/following{/other_user}","gists_url":"https://api.github.com/users/c-rack/gists{/gist_id}","starred_url":"https://api.github.com/users/c-rack/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/c-rack/subscriptions","organizations_url":"https://api.github.com/users/c-rack/orgs","repos_url":"https://api.github.com/users/c-rack/repos","events_url":"https://api.github.com/users/c-rack/events{/privacy}","received_events_url":"https://api.github.com/users/c-rack/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-05-27T11:29:09Z","updated_at":"2015-06-03T12:58:37Z","closed_at":null,"body":"See http://breachattack.com/ for background information and https://github.com/lpomfrey/django-debreach for an implementation in Python.\r\n\r\nAs computing a random string on every request has a performance impact, we could either:\r\n\r\n1. introduce a new `get_masked_csrf_token` and leave `get_csrf_token` unaltered, or\r\n2. add an environment option to switch CSRF masking on/off\r\n\r\nThe CSRF token is only unmasked before validation if it contains a `$` symbol.\r\n\r\nSample code (maybe not the most efficient way):\r\n```elixir\r\nrequire Bitwise\r\n\r\ndefp generate_masked_csrf_token do\r\n  mask = :crypto.strong_rand_bytes(32)\r\n  encoded_mask = mask |> Base.encode64\r\n  masked_token = :crypto.strong_rand_bytes(32)\r\n    |> :erlang.binary_to_list\r\n    |> Stream.zip(mask |> :erlang.binary_to_list)\r\n    |> Enum.to_list\r\n    |> Enum.map(fn({x, y}) -> Bitwise.bxor(x, y) end)\r\n    |> :erlang.list_to_binary\r\n    |> Base.encode64\r\n  \"#{encoded_mask}$#{masked_token}\"\r\nend\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/elixir-lang/plug/issues/comments/108391379","html_url":"https://github.com/elixir-lang/plug/issues/248#issuecomment-108391379","issue_url":"https://api.github.com/repos/elixir-lang/plug/issues/248","id":108391379,"user":{"login":"c-rack","id":169184,"avatar_url":"https://avatars.githubusercontent.com/u/169184?v=3","gravatar_id":"","url":"https://api.github.com/users/c-rack","html_url":"https://github.com/c-rack","followers_url":"https://api.github.com/users/c-rack/followers","following_url":"https://api.github.com/users/c-rack/following{/other_user}","gists_url":"https://api.github.com/users/c-rack/gists{/gist_id}","starred_url":"https://api.github.com/users/c-rack/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/c-rack/subscriptions","organizations_url":"https://api.github.com/users/c-rack/orgs","repos_url":"https://api.github.com/users/c-rack/repos","events_url":"https://api.github.com/users/c-rack/events{/privacy}","received_events_url":"https://api.github.com/users/c-rack/received_events","type":"User","site_admin":false},"created_at":"2015-06-03T12:58:37Z","updated_at":"2015-06-03T12:58:37Z","body":"@josevalim Go ahead. I am currently very time constrained and could have a patch ready earliest tomorrow. If this is too late, feel free to do the patch. You may also use the code snippet above if you want. If tomorrow would be fine, I could also do it. You decide :smile: "}}