Skip to content

I have Implemented secure REST API only login and signup in Go

Notifications You must be signed in to change notification settings

keiya01/rest-api-secure-auth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

97 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rest API Secure Auth

About

  • golangでセキュアな認証システムを実装した
  • 認証には goth を使っており、今回は通常のログインとTwitterログインを実装した
  • SPAと組み合わせて使えるような REST API を意識して開発した
  • 自動でログインされるようにcookieを保持している
  • DB は Mock で作っており、メモリー上に情報を保持している(そのためSQL Injectionについて詳しく書いていないが、余力があれば実装していきたい)

Secure API

  • 以下に脆弱性対策やセキュティーを意識した開発をする上で最低限押さえておくべき対策を列挙した
  • 今回はGolangを用いて開発しており、gorilla関連のpackageを使用している
  • gorilla関連のpackageは様々な機能を小分けで提供してくれているため必要な物を組み合わせて安全に開発を行える

セッション・Cookie

  • セッション情報はCookieJWTなどに保存する
    • Cookie <- 場合にもよるがこっちの方が良さそう?
      • Cookieを使う場合はhttpOnlysecureなどのオプションから安全な設定を追加できるため、XSSからの攻撃を防ぐことできるが、CSRFは自前で実装して防ぐ必要がある
      • 安全に実装するならCookieのような気がする
    • JWT
      • JWTはブラウザのLocalStrageに保存することができ、JWTに情報を持たせることができるのでServerをステートレスに保つことができる
      • LocalStrageSame-Originの場合のみでしか、I/O処理を行うことができないためCSRFの問題はないが、XSSによって情報を抜き取られる可能性がある
      • XSSを100%含まないと言い切れるサイトはない?(https://techracho.bpsinc.jp/hachi8833/2019_10_09/80851)
  • Cookie の扱いに気をつける
    • Cookie を信用しすぎない設計にする
    • ユーザー情報の編集などの個人情報の編集には必ず Password を求めるようにする
  • 予測可能な情報をSessionIDに指定してはいけない
    • IDや日時など推測可能な値をSessionIDに指定すると、簡単に推測されて不正に情報をとられ、ログインなどの処理が可能になる
    • また推測可能な値をハッシュ化して指定することもよくない(時間をかければ推測される可能性があるため)
    • そのためSessionIDの生成には、言語が指定しているプログラムやフレームワークなどの機能を使うと良い
    • Goではgorilla/sessionsを使うと楽
  • SessionIDの固定化攻撃を防ぐ
  • SessionIDの固定化攻撃とは攻撃者が被害者に対して、SessionIDをなんらかの方法で指定することにより、指定されたSessionIDで被害者がログインすると、攻撃者は指定したSessionIDにより、ログイン状態となる脆弱性である。
  • また、ログインしていなくてもユーザーが入力した情報をSessionに逐一保存している場合、固定化攻撃によりSessionIDを指定されると、そのSessionに情報が蓄積されることで攻撃者に情報が抜き取られる可能性がある
  • 多くの場合は心配ないが、セッションアダプションというセッションを外部から指定できるような機能を持っている言語(PHPなど)で起きやすい。しかし、基本的にこれらの機能はデフォルトでfalseになっているはずなので心配はいらないはずである。
  • Cookie に SessionID を保存する(URLに保存しない)
  • 認証成功後に SessionID を変更する(変更できない場合はTokenによりSessionIDの認証を行う)
  • 認証前に機密情報をSessionに保存しない
  • CookieのhttpOnlysecuretrueにする(httpOnlyはJSからアクセス不可能にするためで、securehttpsでのみCookieを扱うことを指定する)
    • 開発の段階でsecuretrueにしているとlocalhostで使用できない可能性があるため、開発時はfalseで良い(公開する時にはtrueにすること)

CORS

  • CORSをちゃんと設定する(オリジン間リソース共有 (CORS))
    • Access-Control-Allow-Origin ... 許可するOriginを指定する(デフォルトは同じOriginが指定される)
    • Access-Control-Allow-Methods ... 許可するHTTP Methodを指定する(GET, POST, OPTIONS, HEADなど)
    • Access-Control-Allow-Headers ... 許可するヘッダーを指定する。プリフライトリクエストのレスポンスで使用される。(Content-Type, Authorizationなど)
    • Access-Control-Allow-Credentials ... 資格情報が必要なリクエストに対して、レスポンスを開示するかどうか(Cookieなどを含めるかどうか)
    • Access-Control-Expose-Headers ... 通常は特定のHeaderしかブラウザでは参照できないため、公開したいHeaderを指定することで参照できるようになる
    • Access-Control-Max-Age ... プリフライトリクエストを何度も呼ぶのはオーバーヘッドになるので、このヘッダーに時間を指定することでキャッシュさせることができる
    • 上記のCORSをしっかり設定した上でCSRF Tokenをレスポンスする
    • gorilla/muxでは、mux.Route.MethodOPTIONSを指定することでpreflight requestを許可する

Preflight Request

  • Preflight Requestとは、主にJSからのPOSTなどの副作用を保つメソッドに対するリクエストを行う時に、安全なリクエストを送るために事前にリクエストされる通信である
  • Preflight RequestによってAccess-Control-*のHeader情報が検証されることで安全なリクエストを行うことができる
  • Preflight RequestOPTIONSメソッドでリクエストされるので、OPTIONSで処理するように指定する

CSRF

  • CSRF対策をする

Content-Type: application/json

  • JSONを返す WEB API の場合、Content-Type: application/jsonを設定しないことでXSSが発生してしまう
  • Content-Type: application/jsonはブラウザにJSON形式のデータを返すことを伝えるヘッダーだが、これを設定しないことでContent-Type: text/htmlが設定されてしまう
  • Content-Type: text/htmlが設定されると、JSONをHTMLとして返すことをブラウザーに伝えるため、HTMLとして読み込むことでXSSが発生する
  • XSSを防ぐにはContent-Type: application/jsonの設定が必要であるが、IEの一部のバージョンではContent-Typeを書き換えられる仕様になっている
  • 書き換えを防ぐためにX-Content-Type-Optionsを設定する

X-Frame-Options

  • クリックジャッキングなどの脆弱性対策として必要
  • クリックジャッキングは、攻撃者が作成した偽サイトにiframeを使ってTwitterなどの一般的なサイトを表示し、その一般的なサイトの投稿ボタンなどの上に罠サイトへのリンクや、攻撃用のプログラムを含めておき、実行させるというものである。
  • この攻撃を防ぐためには、Originまたは指定されたOrigin以外のサイトではiframeを使用できないようにする必要がある。
  • それがX-Frame-Optionsである
  • これを含めることで、知らないサイトからiframeを使って自分のサイトを表示される事はなくなるため、脆弱性を防ぐことができる
  • 実際にTwitterをiframeから参照しようとするとRefused to display 'https://twitter.com/' in a frame because it set 'X-Frame-Options' to 'deny'というエラーが出力される
  • 参考: https://qiita.com/mejileben/items/39d897757d5c3a904721

X-XSS-Protection

  • XSSを検知した時に無害な出力に変換する
  • 各ブラウザでデフォルトでは有効になっているが、ユーザーの設定で無効にできるため、X-XSS-Protectionを設定することで矯正させることができる

X-Content-Type-Options

SameSite

  • SameSite属性はSet-Cookieに含まれる設定
  • SameSiteにはStrictLaxNoneがある
  • Strict ... 異なるDomainのサイトに対してはCookieを付与しない(この設定が最も堅牢)
  • Lax ... Get Method以外のリクエストにはCookieを含めない(Chrome80では何も指定しない場合にはこの値が設定される)
  • None ... どのようなリクエストであっても、Cookieを含める(Chrome79以前ではデフォルト、Chrome80ではSecure属性をつけなければLaxになる)
  • 参考: https://qiita.com/ahera/items/0c8276da6b0bed2b580c
  • 参考: https://blog.jxck.io/entries/2018-10-26/same-site-cookie.html

その他

  • SQL Injection
  • Passwordなどの見られてはいけない重要な情報を暗号化してからDBに保存する

About

I have Implemented secure REST API only login and signup in Go

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages