Skip to content
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

Add X-Requested-With header to prevent CSRF #48

Merged
merged 11 commits into from
Feb 5, 2021
Merged

Conversation

chenilim
Copy link
Contributor

@chenilim chenilim commented Feb 3, 2021

Add X-Requested-With=XMLHttpRequest header to all REST API requests, and check on the server.

@chenilim chenilim requested a review from jespino February 3, 2021 18:24
}

func (a *API) RegisterAdminRoutes(r *mux.Router) {
r.HandleFunc("/api/v1/admin/users/{username}/password", a.adminRequired(a.handleAdminSetPassword)).Methods("POST")
}

func (a *API) addHandler(r *mux.Router, path string, method string, f func(http.ResponseWriter, *http.Request)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a look like a middleware

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Jesus! I knew there was a cleaner way. Refactored to use Middleware.


r.HandleFunc("/api/v1/login", a.handleLogin).Methods("POST")
r.HandleFunc("/api/v1/register", a.handleRegister).Methods("POST")
a.addHandler(r, "/api/v1/login", "POST", a.sessionRequired(a.handleLogin))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are adding sessionRequired to the login and register ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack, fixed that. Much easier to see with the middleware pattern.

Copy link
Contributor

@jespino jespino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of changes proposed but otherwise looks good to me.

Copy link
Contributor

@jespino jespino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think is better to use a middleware in this case. and you moved the login/register api endpoints behind a sessionRequired.

files.Use(a.requireCSRFToken)

files.HandleFunc("/", a.sessionRequired(a.handleUploadFile)).Methods("POST")
files.HandleFunc("/{filename}", a.sessionRequired(a.handleServeFile)).Methods("GET")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure about the need of the CSRFToken check for the static files, actually I think it should be only for the API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't have much control over the image loading and files downloading in the browser to add that header.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I had refactored contentBlock to get the images with fetch, passing the session token and CSRF header. However, I removed the CSRF check for GET /files for now, as that (in theory) shouldn't be a CSRF vulnerability as no state is changed. We can think about this one more, and change later if needed.

r.HandleFunc("/api/v1/blocks", a.sessionRequired(a.handlePostBlocks)).Methods("POST")
r.HandleFunc("/api/v1/blocks/{blockID}", a.sessionRequired(a.handleDeleteBlock)).Methods("DELETE")
r.HandleFunc("/api/v1/blocks/{blockID}/subtree", a.attachSession(a.handleGetSubTree, false)).Methods("GET")
apiv1 := r.PathPrefix("/api/v1").Subrouter()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice touch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I smoke tested this and it looks ok, but please LMK if you see anything off.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, everything is looking great now

@chenilim chenilim merged commit 43c656c into main Feb 5, 2021
@cpanato cpanato deleted the requested-with-header branch June 16, 2021 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants