# CSRF on /login security alert from security scans

**URL:** https://meta.discourse.org/t/csrf-on-login-security-alert-from-security-scans/104667
**Category:** Self-hosting
**Created:** [December 19, 2018, 1:23pm UTC](https://meta.discourse.org/t/csrf-on-login-security-alert-from-security-scans/104667 "2018-12-19T13:23:42Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![jlaura](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@jlaura](https://meta.discourse.org/u/jlaura)
#### Post date: [December 19, 2018, 1:23pm UTC](https://meta.discourse.org/t/csrf-on-login-security-alert-from-security-scans/104667/1 "2018-12-19T13:23:43Z")

</div>

I am using discourse via docker containers in a local docker swarm. The installation went smoothly and we have been able to get a working prototype deployed within a super short period of time. Thanks for the great docs!

We then needed to get our business security scans run to be able to set up the proper proxies for getting discourse accessible via the outside world. All went well, except for a missing CSFR protection on /login. We have the local logins enabled and are being alerted that the `/login` url (looks like it is linked to the nice login window that is presented over the main page on login request) does not appear to have CSRF protection.

We are deployed behind a firewall, so access to Github to use the Git OAuth is not possible. That said, I have enabled it because we can watch the authentication attempt as the request hits Github and then see the failure logged in production.log (expected because Git has not access back to our discourse install). I mention this because the login attempt to GitHub includes CSRF protection, but the local login does not.

Local:

```
Started GET "/login.html?_=1545151335383" for xxx.xxx.xxx.xxx at 2018-12-18 16:42:15 +0000
Processing by StaticController#show as HTML
  Parameters: {"_"=>"1545151335383", "id"=>"login"}
  Rendering static/login.html.erb
  Rendered static/login.html.erb (19.5ms)

```

GitHub:

```
Started GET "/auth/github" for xxx.xxx.xxx.xxx at 2018-12-18 18:34:32 +0000
(github) Setup endpoint detected, running now.
(github) Request phase initiated.
Started GET "/auth/github/callback?code=AUTHCODE" for xxx.xxx.xxx.xxx at 2018-12-18 18:34:52 +0000
(github) Setup endpoint detected, running now.
(github) Callback phase initiated.
(github) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected
Started GET "/auth/failure?message=csrf_detected&strategy=github" for xxx.xxx.xxx.xxx at 2018-12-18 18:34:52 +0000
Processing by Users::OmniauthCallbacksController#failure as HTML
  Parameters: {"message"=>"csrf_detected", "strategy"=>"github"}
  Rendering users/omniauth_callbacks/failure.html.erb within layouts/no_ember
  Rendered users/omniauth_callbacks/failure.html.erb within layouts/no_ember (0.7ms)
  Rendered layouts/_head.html.erb (7.4ms)
  Rendered common/_discourse_stylesheet.html.erb (0.2ms)
  Rendered application/_header.html.erb (0.1ms)

```

Is /login missing CSRF protection or have we missed an installation step?

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [December 19, 2018, 1:34pm UTC](https://meta.discourse.org/t/csrf-on-login-security-alert-from-security-scans/104667/2 "2018-12-19T13:34:27Z")

</div>

You mention that GitHub OAuth is not possible due to your firewall, so I’m not sure what the logs are supposed to be illustrating. The CSRF error on GitHub login would be expected if you have not configured it correctly.

> [@jlaura](#):
>
> All went well, except for a missing CSFR protection on /login

What do you mean by this? If you’re being told this by an automated security scanner, then it is very likely to be a false positive.

---

<div class="post-metadata">

### Author: ![jlaura](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@jlaura](https://meta.discourse.org/u/jlaura)
#### Post date: [December 19, 2018, 1:36pm UTC](https://meta.discourse.org/t/csrf-on-login-security-alert-from-security-scans/104667/3 "2018-12-19T13:36:45Z")

</div>

@David Thanks. I suspected it might be a false positive. What I was trying to illustrate is that the Github login appears to have CSRF protection, while the local login does not. I do not see any csrf\_detected notifications in the log when using the local login.

I need to prove to the security team that the /login page is actually protected.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [December 19, 2018, 1:45pm UTC](https://meta.discourse.org/t/csrf-on-login-security-alert-from-security-scans/104667/4 "2018-12-19T13:45:54Z")

</div>

> [@jlaura](#):
>
> I need to prove to the security team that the /login page is actually protected.

The full source code is available at [GitHub - discourse/discourse: A platform for community discussion. Free, open, simple. · GitHub](https://github.com/discourse/discourse)

From our [security document](https://github.com/discourse/discourse/blob/master/docs/SECURITY.md#csrf):

> [@](#):
>
> [CSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) allows malicious sites to perform HTTP requests in the context of a forum user without their knowledge – mostly by getting users who already hold a valid forum login cookie to click a specific link in their web browser.
> 
> Discourse extends the built-in Rails CSRF protection in the following ways:
> 
> 1. By default any non GET requests ALWAYS require a valid CSRF token. If a CSRF token is missing Discourse will raise an exception.
> 2. API calls using the secret API bypass CSRF checks.
> 3. Certain pages are “cachable”, we do not render the CSRF token ( `<meta name='csrf-token' ...` ) on any cachable pages. Instead when users are about to perform the first non GET request they retrieve the token just in time via `GET session/csrf`

---

<div class="post-metadata">

### Author: ![jlaura](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@jlaura](https://meta.discourse.org/u/jlaura)
#### Post date: [December 19, 2018, 1:49pm UTC](https://meta.discourse.org/t/csrf-on-login-security-alert-from-security-scans/104667/5 "2018-12-19T13:49:10Z")

</div>

@David Thanks! I have seen that documentation and forwarded along to the security team. I will dig into the source. I was surprised not see an csrf session logging into the production logs, but will look at the source to also forward the code block to them. Appreciated.

---

<div class="post-metadata">

### Author: ![jlaura](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@jlaura](https://meta.discourse.org/u/jlaura)
#### Post date: [December 19, 2018, 5:39pm UTC](https://meta.discourse.org/t/csrf-on-login-security-alert-from-security-scans/104667/6 "2018-12-19T17:39:00Z")

</div>

@David We did some more digging and monitoring of the requests and responses. It looks like the the CSRF token is not granted until the user logs in. When visiting the site the CSRF token is not being assigned. This is what our security folks are flagging - no CSRF token until logged in therefore, on initial visit we do not have a CSRF token. Is this intentional?

If we are logged in we see the following in the response:

```
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="TOKEN" />

```

Here is a get/response when not logged in. We do not see a meta tag with the csrf.

```
GET / HTTP/1.1
Host: astrodiscuss.usgs.gov
Connection: close
Purpose: prefetch
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Wed, 19 Dec 2018 17:07:47 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Vary: Accept-Encoding
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
X-Discourse-Route: list/latest
Cache-Control: no-cache, no-store
X-Discourse-Cached: true
X-Request-Id: 2df19db3-ca64-4920-a909-073854ab2b03
X-Runtime: 0.001948
X-Discourse-TrackView: 1
Strict-Transport-Security: max-age=31536000
Content-Length: 57226

<!DOCTYPE html>
<html lang="en" class="desktop-view not-mobile-device anon">
  <head>
    <meta charset="utf-8">
    <title>AstroDiscuss</title>
    <meta name="description" content="USGS Astrogeology Discussion">
    <meta name="discourse_theme_ids" content="1">
    <meta name="discourse_current_homepage" content="latest">
    <meta name="author" content="">
<meta name="generator" content="Discourse 2.2.0.beta5 - https://github.com/discourse/discourse version 414aa1fe7a8e968b00a8bd8e103ce34a42a25028">
<link rel="icon" type="image/png" href="/images/default-favicon.ico">
<link rel="apple-touch-icon" type="image/png" href="https://astrodiscuss.usgs.gov/images/default-apple-touch-icon.png">
<meta name="theme-color" content="#111111">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=yes">

<script type="application/ld+json">{"@context":"http://schema.org","@type":"WebSite","url":"https://astrodiscuss.usgs.gov","potentialAction":{"@type":"SearchAction","target":"https://astrodiscuss.usgs.gov/search?q={search_term_string}","query-input":"required name=search_term_string"}}</script>
<link rel="search" type="application/opensearchdescription+xml" href="https://astrodiscuss.usgs.gov/opensearch.xml" title="AstroDiscuss Search">
...(more HTML)

```

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [December 19, 2018, 5:42pm UTC](https://meta.discourse.org/t/csrf-on-login-security-alert-from-security-scans/104667/7 "2018-12-19T17:42:00Z")

</div>

> [@jlaura](#):
>
> It looks like the the CSRF token is not granted until the user logs in

From our security doc:

> [@](#):
>
> Certain pages are “cachable”, we do not render the CSRF token ( `<meta name='csrf-token' ...` ) on any cachable pages. Instead when users are about to perform the first non GET request they retrieve the token just in time via `GET session/csrf`

And the relevent piece of the code which fetches the CSRF code before performing the request:

[https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/ajax.js.es6#L149-L166](https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/ajax.js.es6#L149-L166)
