Как защитить REST API от CSRF, когда интерфейс и API находятся на одном сервере Go? - PullRequest
0 голосов
/ 19 октября 2018

Я работаю над веб-сайтом, созданным на Go.

Доступ к нему возможен как через веб (страницы на стороне сервера, созданные с помощью шаблонов golang), так и через REST API (для внешних пользователей, которые хотят интегрироваться)собственное программное обеспечение).Сервер Go обрабатывает оба типа запросов, с помощью подчиненного маршрутизатора, который обрабатывает API при отправке вызовов на подпуть «my-url-root / api».

  • На веб-страницах используются безопасные файлы cookie
  • API не имеет состояния: нет файлов cookie (каждый метод API должен получать в заголовке токен аутентификации, полученный с помощью специального метода входа в систему)

Я успешно применил gorilla / csrf для защиты веб-страницот атак csrf, но эта модификация (необходимая, прежде чем я начну работать) в настоящее время создает проблему с API.

Мой вопрос Когда CSRF реализован, все запросы GET отправляются в APIURL работают должным образом, но любой другой отправленный запрос (например, POST к методу для добавления чего-либо через мой REST API) генерирует html-ответ, который обычно гласит «запрещенный - недействительный токен csrf».

Есть ли прямолинейныйКстати, что мне не хватает?Я искал ответы, но ни один из них не применим к случаю, когда API обслуживается одним и тем же сервером, и больше всего он не имеет состояния.Должен ли я проверить, могу ли я «отключить» защиту gorilla csrf для подчиненного маршрутизатора (хотя я даже не знаю, возможно ли это и безопасно ли это ...)?

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 24 октября 2018

Хорошо, поэтому я попытался применить приведенные выше предложения, и я нашел решение своей проблемы.

Я проверил, что это работает, проверив вызовы web и api по моим URL-адресам и суб-URL с помощью ибез защиты CSRF.

Просто пояснение к моему предыдущему комментарию.Чтобы быть более точным, порядок, в котором я создавал субмиксы, не имел значения, но, конечно, я тогда следовал правильному порядку, когда записывал строки для обработки каждого пути.

Итак, порядок важен.

Это то, что я сделал (только биты кода).

Я использовал goji в качестве маршрутизатора и gorilla / csrf для защиты csrf.

ПРИМЕЧАНИЕ: я не сделалвключите весь мой код, но только самые важные части, чтобы описать то, что я сделал.

1) Я создал мультиплексирование, используя

mux := goji.NewMux()

2), так как мои API обслуживаются по URL "/api "и связанных под URL, я создал Submux для api

apiMux := goji.SubMux()

3) Я назначил страницы, которые соответствуют пути" / api "и" / api * "этому subMux

Обратите внимание, что я НЕ включил какую-либо защиту csrf

mux.Handle(pat.New("/api/*"), apiMux)

mux.Handle(pat.New("/api"), apiMux)

4) Я создал Submux для веб-страниц моего сайта

webMux := goji.SubMux()

5) Я назначил страницы, которые соответствуютПуть "/" и "/ *" к этому subMux

Обратите внимание, что здесь, в моем коде, я связал промежуточное ПО для защиты csrf

mux.Handle(pat.New("/"), csrf.Protect(csrfKey, csrf.Secure(true))(webMux))
mux.Handle(pat.New("/*"), csrf.Protect(csrfKey, csrf.Secure(true))(webMux))

6) Для моего удобства я создал другоеSubMuxes для обработки других путей, таких как "/ users", "/ users / 1", "/ users / addform".Этот шаг важен: я назначил этот «userMux» для webMux, а не для основного mux, созданного на шаге 1.

Таким образом, защита csrf наследуется.Пример:

usersMux := goji.SubMux()

webMux.Handle(pat.New("/users/*"), usersMux)

webMux.Handle(pat.New("/users"), usersMux)

В двух словах, это было решением моей проблемы:

I) Я назначил этот "apiMux" основному мультиплексору, созданному на шаге 1.

Я не назначил его никаким другим мультиплексорам.Я НЕ назначил его webMux, который обрабатывает корневые URL "/" и "/ *"

II). Порядок важен, поэтому я реализовал код для URL-адресов API, а затем код для веба.urls

Надеюсь, это поможет.И больше всего я надеюсь, что объяснение было ясным ... (если не просто дайте мне знать).Спасибо, что указал мне правильное направление

...