ゴランにおける認証セッションの理解と構築
22461 ワード
導入
Webアプリの認証セッションは、悪意のある脅威に対する防衛の中心です.したがって、セキュリティテスターのためのreconの最初のポイントの一つです.
この記事では、GO開発者は、認証セッションでの認証セッション、認証セッションの脆弱性、デザインの欠陥、セッションベースとトークンベースの認証方法の違い、および各アプリケーションを適用するときに啓発されます.
両方のメソッドの例を使用します.
認証セッション
Webアプリケーションの認証プロトコルがセッション中です.以下の手順に従います.
HTMLフォームの使用
HTMLフォームは、ユーザー名とパスワードが収集され、アプリケーションに送信されるWebアプリケーションを認証する最も一般的なメソッドです.このメカニズムは、インターネットで利用できるアプリケーションの90 %以上を説明します.
多因子機構の使用
より多くのセキュリティが必要なプラットフォームでは、オンライン決済システムのように、マルチステージフォーム充填セッションが開始され、ユーザーは追加の資格情報を提供するよう命令されます.銀行アプリでは、物理トークンがしばしば必要です.これらのトークンは、通常、1回のパスコード(OTPS)のストリームを生成するか、またはユーザーからの入力を必要とする課題を提供する.
親指の規則は、高感度データのためにOTPSを利用することです.
クライアントSSL証明書
いくつかのWebアプリケーションは、SSLの証明書や暗号化メカニズムを使用します.このプロセスには以下が含まれる:
HTTP認証
HTTPベースの認証は、インターネットの採用で非常にまれです.それはイントラネットベースでより使用されます.認証の最も基本的な形式です.HTTP認証では、クライアントのログイン資格情報がリクエストヘッダで送信されます.
Authorization: Basic YWxqY2U6cGE2NXdbcmQ=
基本認証は、ユーザ名とパスワードに暗号化を使用しません.このように、アプリケーションは、低値データがある場合に限られており、簡単にアクセスする必要があります.それでも、使うのはお勧めです.
-- https接続で
-本当に強いパスワードで
-速度制限を加えて、自傷攻撃を防ぐ
認証サービス
認証サービスは、アプリケーションと信頼性に関して重くなっています.一般的で広く使用されている認証認証サービスは、Auth 0です.Auth0 開発者の間で幅広い人気と使用を得ている実装、適応可能な認証と認可プラットホームは簡単です.
ウェブトークン
JWT、またはJSONのWebトークンは、クライアントとサーバーの2つの当事者間のセキュリティ情報を共有するために使用されるオープン標準認証プロトコルです.クライアント資格情報は、この場合、サーバーに格納されませんが、保管と再利用のためにクライアントに戻されます.
認証セッションにおける脆弱性
HTMLフォームで可能である脆弱性と攻撃は、ほとんどアップグレードを加えて、ほとんどの認証方法で動作します.
攻撃で利用できるデザイン欠陥を見てみましょう.
Webアプリケーションにおける設計欠陥
弱パスワード
弱いパスワードは、まだこの時代のものです.彼らは短いパスワード、予測可能な単語、簡単に社会工学、単語や母音を表す明らかなシンボルを持つ名前を介して得ることができるユーザーの名前の形を取る.
開発
ハッカーが行う最初のことは、Webアプリケーションにログインを試み、パスワードボックスを埋める際にソフトウェアによって指定された規則に注意を払うことです.
パスワード変更機能
ウェブ開発者は、しばしば彼らのアプリでパスワード変更機能を提供することができません.この機能は、2つの特別な理由のために、しかし、Webアプリケーションで非常に重要です
Goで認証セッションを構築する方法を学びましょう.
Basic HTTP Authentication in Golang
先に説明したように、基本的なHTTP認証方法は安全ではありません.しかし、次のようにハッシュ化して実装できます.
func basicAuth(next http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
if ok {
usernameHash := sha256.Sum256([]byte(username))
passwordHash := sha256.Sum256([]byte(password))
expectedUsernameHash := sha256.Sum256([]byte("username"))
expectedPasswordHash := sha256.Sum256([]byte("password"))
usernameMatch := (subtle.ConstantTimeCompare(usernameHash[:], expectedUsernameHash[:]) == 1)
passwordMatch := (subtle.ConstantTimeCompare(passwordHash[:], expectedPasswordHash[:]) == 1)
if usernameMatch && passwordMatch {
next.ServeHTTP(w, r)
return
}
}
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
})
}
ユーザー名とパスワードが保管のためにハッシュされていないことを強調することは重要です.それらは一定時間で比較できる2つの等しい長さバイトスライスを得るためにハッシュされます.HTTP基本認証のこのメソッドを使用する場合、インポートされるパッケージには次のものがあります.
import (
"crypto/sha256"
"crypto/subtle"
"fmt"
"log"
"net/http"
"os"
"time"
)
struct型のアプリケーションインスタンスを作成するには、ユーザ名とパスワードを入力します.type application struct {
username string
password string
}
主な機能は、全体の操作とサーバーインスタンスを含みます:func main() {
webapp := new(application)
webapp.auth.username = os.Getenv("AUTH_USERNAME")
webapp.auth.password = os.Getenv("AUTH_PASSWORD")
if webapp.auth.username == "" {
log.Fatal("Illegal username provided")
}
if webapp.auth.password == "" {
log.Fatal("Illegal password provided")
}
mux := http.NewServeMux()
mux.HandleFunc("/unprotected", webapp.unprotectedHandler)
mux.HandleFunc("/protected", webapp.basicAuth(app.protectedHandler))
srv := &http.Server{
Addr: ":8080",
Handler: mux,
IdleTimeout: time.Minute,
ReadTimeout: 10 * time.Second,
WriteTimeout: 30 * time.Second,
}
log.Printf("starting server on %s", srv.Addr)
err := srv.ListenAndServeTLS("./localhost.pem", "./localhost-key.pem")
log.Fatal(err)
}
Golangにおけるセッションベース認証セッション
セッションベースの認証システムは、サーバー側のテンプレートを実装するWebアプリケーションでしばしば使用されます.OAuthとOpenIDはさらにアプリケーションを安全に追加することができます.
ゴングでは、人気Gorilla Mux
パッケージは
package that can be used to create authentication sessions.
Hence, the first step in creating an authentication session is to install the
```gorilla/mux```
and
```gorilla/sessions```
packages.
```Shell
go get github.com/gorilla/mux
go get github.com/gorilla/sessions
その後、プロジェクトのローカルディレクトリを作成します.
次に、インポート
package as well as other important packages.
```Go
package main
import (
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
)
APIエンドポイントのためのセッションベースの認証を作成していることを見て、我々は
method in the sessions package we imported.
```Go
var store =sessions.NewCookieStore([]byte(os.Getenv("SESSION_SECRET")))
ダッシュボードにログインしていると仮定すると、必要なAPIエンドポイントは以下の通りです.
-
-
```/dashboard```
-
```/logout```
There will be a list of users having their own dashboards, so the server must have a map it can search for yours in. Initializing an example user credentials:
```Go
var users = map[string]string{
"Mac": "username",
"admin": "password"
}
ログインハンドラ関数は、クライアントの要求、資格証明のマッチング、および/ダッシュボードエンドポイントの復帰を担当します.
この関数は最初にポストフォームを解析します.その後、クライアントの資格情報を取得します.
func LoginHandler(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, "Please pass the data as URL form encoded",
http.StatusBadRequest)
return
}
username := r.PostForm.Get("username")
password := r.PostForm.Get("password")
}
この関数は、収集したデータとサーバーに格納されているデータとを一致させます.この関数は既存のマッチを認証し、一致しない場合にエラーを返します.
//continued in the LoginHandler function
if originalPassword, ok := users[username]; ok {
session, _ := store.Get(r, "session.id")
if password == originalPassword {
session.Values["authenticated"] = true
session.Save(r, w)
} else {
http.Error(w, "Invalid Credentials",
http.StatusUnauthorized)
return
}
} else {
http.Error(w, "User is not found", http.StatusNotFound)
return
}
w.Write([]byte("Logged In successfully"))
サーバーの資格情報ストアのクライアントの可用性に応じて、ログインは成功します.
一方、LOG OUTセッションはGETリクエストを受け取り、
method to false.
```Go
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session.id")
session.Values["authenticated"] = false
session.Save(r, w)
w.Write([]byte(""))
}
The
method saves the cookie state after modification.
Next, it is important to create the
```/dashboard```
API endpoint. The
```/dashboard```
function would return the time of login:
```Go
func DashboardHandler(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session.id")
if (session.Values["authenticated"] != nil) && session.Values
["authenticated"] != false {
w.Write([]byte(time.Now().String()))
} else {
http.Error(w, "Forbidden", http.StatusForbidden)
}
}
エンドポイントを書き終えたら、次のステップは
function. This function will connect and start up all endpoints, and the server at an open port:
```Go
main() {
server := mux.NewRouter().StrictSlash(True)
server.HandleFunc("/login", LoginHandler)
server.HandleFunc("/dashboard", DashboardHandler)
server.HandleFunc("/logout", LogoutHandler)
http.Handle("/", server)
srv := &http.Server{
Handler: server,
Addr: "127.0.0.1:8080",
// Good practice: enforce timeouts for servers you create!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
これでセキュア認証セッションが完了します.コマンドの実行go run main.go
localhostのサーバを起動します.
ゴランにおけるトークンベース認証セッション
このトークンまたはセッションベースの認証システムの欠点の1つは、それがプログラムメモリに、またはredisのような特別なサーバソフトウェアに資格情報を格納するということです.
しかしながら、JWTはこれに解決策を提出します.JWTは、データベースに格納するクライアントにログイン資格情報を再送信する方法です.以下、手順を説明する.
package that can be used to create authentication sessions.
Hence, the first step in creating an authentication session is to install the
```gorilla/mux```
and
```gorilla/sessions```
packages.
```Shell
go get github.com/gorilla/mux
go get github.com/gorilla/sessions
package as well as other important packages.
```Go
package main
import (
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
)
method in the sessions package we imported.
```Go
var store =sessions.NewCookieStore([]byte(os.Getenv("SESSION_SECRET")))
-
```/dashboard```
-
```/logout```
There will be a list of users having their own dashboards, so the server must have a map it can search for yours in. Initializing an example user credentials:
```Go
var users = map[string]string{
"Mac": "username",
"admin": "password"
}
func LoginHandler(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, "Please pass the data as URL form encoded",
http.StatusBadRequest)
return
}
username := r.PostForm.Get("username")
password := r.PostForm.Get("password")
}
//continued in the LoginHandler function
if originalPassword, ok := users[username]; ok {
session, _ := store.Get(r, "session.id")
if password == originalPassword {
session.Values["authenticated"] = true
session.Save(r, w)
} else {
http.Error(w, "Invalid Credentials",
http.StatusUnauthorized)
return
}
} else {
http.Error(w, "User is not found", http.StatusNotFound)
return
}
w.Write([]byte("Logged In successfully"))
method to false.
```Go
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session.id")
session.Values["authenticated"] = false
session.Save(r, w)
w.Write([]byte(""))
}
method saves the cookie state after modification.
Next, it is important to create the
```/dashboard```
API endpoint. The
```/dashboard```
function would return the time of login:
```Go
func DashboardHandler(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session.id")
if (session.Values["authenticated"] != nil) && session.Values
["authenticated"] != false {
w.Write([]byte(time.Now().String()))
} else {
http.Error(w, "Forbidden", http.StatusForbidden)
}
}
function. This function will connect and start up all endpoints, and the server at an open port:
```Go
main() {
server := mux.NewRouter().StrictSlash(True)
server.HandleFunc("/login", LoginHandler)
server.HandleFunc("/dashboard", DashboardHandler)
server.HandleFunc("/logout", LogoutHandler)
http.Handle("/", server)
srv := &http.Server{
Handler: server,
Addr: "127.0.0.1:8080",
// Good practice: enforce timeouts for servers you create!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
このトークンまたはセッションベースの認証システムの欠点の1つは、それがプログラムメモリに、またはredisのような特別なサーバソフトウェアに資格情報を格納するということです.
しかしながら、JWTはこれに解決策を提出します.JWTは、データベースに格納するクライアントにログイン資格情報を再送信する方法です.以下、手順を説明する.
トークン
RESTful APIについては、トークンベースの認証は、それがステートレスであることを前提に最善かつ推奨されるアプローチです.
GOでJWTトークンベースのセッションを作成するには
jwt-go
パッケージがインポートされます.これは、署名メソッドとクレームマップを受け入れるnewwithRequestメソッドを持っています.GWTでJWTを実装する上での素晴らしいガイドはAuth0 blog .
結論
この時点で、読者は認証セッションがどのようなカバーの下にあるか、認証において可能な脆弱性の種類、Webアプリケーションを認証する際の一般的なオプション、およびセッションとトークンベースの認証セッションの違いと方法に注意しなければなりません.
Reference
この問題について(ゴランにおける認証セッションの理解と構築), 我々は、より多くの情報をここで見つけました
https://dev.to/theghostmac/understanding-and-building-authentication-sessions-in-golang-1c9k
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
Reference
この問題について(ゴランにおける認証セッションの理解と構築), 我々は、より多くの情報をここで見つけました https://dev.to/theghostmac/understanding-and-building-authentication-sessions-in-golang-1c9kテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol