-
Notifications
You must be signed in to change notification settings - Fork 887
fix: relax csrf to exclude path based apps #11430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -315,3 +319,62 @@ func TestSwagger(t *testing.T) { | |||
require.Equal(t, "<pre>\n</pre>\n", string(body)) | |||
}) | |||
} | |||
|
|||
func TestCSRFExempt(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am working on a unit test to verify
Is it this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup. All of our existing unit tests bypass CSRF since the codersdk uses the HEADER method to auth, not the cookie.
coderd/coderd.go
Outdated
// CSRF only needs to apply to /api routes. It does not apply to GET requests | ||
// anyway, which is most other routes. We want to exempt any external auth or | ||
// application type routes. | ||
httpmw.CSRF(options.SecureAuthCookie), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a bunch of ExemptRegexp()
calls inside this middleware that may need to be reviewed after this change. It might be nicer to have those passed explicitly as arguments to httpmw.CSRF
instead of being hidden inside the middleware.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thing is, this will pretty quickly fail on someone when they add a new route if it breaks. The error is a CSRF error, which brings you to here. I prefer to have this all in 1 place, and this should never be configurable by a customer except maybe to disable it entirely.
I think the current exempts are overkill. I intentionally went a bit overkill because I was afraid of breaking anything. Some
The reason there are exempts like this is when I turned this back on, I was trying to error on the side of caution. I think we should have a PR to remove an exempt 1 by 1 when we determine they can never cause an issue.
An example is the /provisionerdaemons
ones. They are currently only GET requests, and I do not think the actual daemons are using cookies to authenticate. However I error-ed on the side of caution since these routes should never use CSRF anyway.
I can make follow up PRs to drop these with rational for each one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@johnstcn CSRF state is set via go template on page render. So the CSRF middleware has to be present for page loads. I just added this instead.
There is only an "exempt" syntax, rather than an "opt in" unfortunately. I think this is the easiest fix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. LGTM once the linter is happy and once there are some more test cases in TestCSRFExempt
coderd/httpmw/csrf_test.go
Outdated
}{ | ||
{ | ||
Name: "Root", | ||
Path: "/", | ||
Exempt: true, | ||
}, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can add some more test cases here
It is never happy 😄 |
Fixes #11406
I am working on a unit test to verify and make sure this does not break in future. Our current tests use the header auth method, which bypasses CSRF. My manual testing was just a fileserver which only used GET requests.