知識のリンク集

技術系アウトプット

SQLインジェクションとplaceholder機能を使った対応処理

SQLインジェクション

r.GET("/1/users/:Id"

上記のAPIをWebで叩くとき、WebではURLがブラウザの上部に表示され、下記のようにURLが表示される。
"https://domain.jp/users/id"

パラメーター部分(id)はURLを直接書き換えることで別の値に置き換えることができる。
データベースと連携して動作するWebサイトでは、外部から入力された値を元にSQL文を組み立てるため、
入力された値によって意図しないSQLが生成され、結果として不正にDBのデータが読み取られたり、データが改ざんまたは削除される恐れがある。

この手法の攻撃を"SQLの注入"という意味でSQLインジェクションと呼ぶ。

placeholder機能

SQLインジェクションの対応として、安全なパラメーターを使ってSQL文を生成するplaceholder機能を使うことができる。

Routes

func GetUser(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
 // パラメータをチェック
 Id, err := strconv.ParseInt(ps.ByName("id"), 10, 0) helpers.CheckErr(err, "Invalid Id")
 // 問題なければモデルの処理へ受けわたす
 R.JSON(w, http.StatusOK, models.GetUser(Id))
}

Models

func GetUser(Id int64) UserView { 
 query := UserQuery + ` 
  WHERE s.user_id = ? 
  AND s.user_deleted_date IS NULL
 `
 var user UserView 
 _, err := DbMap.Select(&user, query, id) 
 helpers.CheckErr(err, "Executing query failed")

 return user
}

"SELECT s.user_id = ? "の?には"_, err := DbMap.Select(&user, query, id) "によりidで渡ってきた値が代入されてSQL文が生成される。