ホームページ >バックエンド開発 >Golang >Golang での生の SQL と ORM による SQL インジェクションの防止

Golang での生の SQL と ORM による SQL インジェクションの防止

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2025-01-15 20:22:43793ブラウズ

安全な Golang データベース インタラクション: SQL インジェクションの防止

今日の開発環境では、安全なコーディングの実践が最も重要です。 この記事では、データベースと対話する際の一般的な脅威である SQL インジェクションの脆弱性から Golang アプリケーションを保護することに焦点を当てています。生の SQL とオブジェクト リレーショナル マッピング (ORM) フレームワークの両方を使用した防止手法を検討します。


SQL インジェクションについて

SQL インジェクション (SQLi) は、Web セキュリティの重大な欠陥です。 攻撃者は、悪意のある SQL コードをデータベース クエリに挿入することでこれを悪用し、データの整合性とアプリケーションのセキュリティを侵害する可能性があります。

脆弱なクエリの例:

<code class="language-go">query := "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'"
rows, err := db.Query(query)</code>

username または password への悪意のある入力により、クエリのロジックが変更される可能性があります。

Preventing SQL Injection with Raw SQL and ORM in Golang

SQL インジェクションについてさらに詳しく理解するには、この他の投稿を参照してください。


生の SQL クエリの保護

SQL を直接操作する場合は、次のセキュリティ対策を優先してください:

1.プリペアド ステートメント: Go の database/sql パッケージは、SQLi に対する重要な防御手段であるプリペアド ステートメントを提供します。

脆弱な例:

<code class="language-go">query := "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'"
rows, err := db.Query(query) // Vulnerable to SQL injection</code>

安全なバージョン (準備されたステートメント):

<code class="language-go">query := "SELECT * FROM users WHERE username = ? AND password = ?"
rows, err := db.Query(query, username, password)
if err != nil {
    log.Fatal(err)
}</code>

準備されたステートメントはユーザー入力を自動的にエスケープし、インジェクションを防ぎます。

2.パラメーター化されたクエリ: パラメーター化されたクエリのプレースホルダーには db.Query または db.Exec を使用します:

<code class="language-go">query := "INSERT INTO products (name, price) VALUES (?, ?)"
_, err := db.Exec(query, productName, productPrice)
if err != nil {
    log.Fatal(err)
}</code>

動的クエリの場合は文字列の連結または fmt.Sprintf を避けてください。

3. QueryRow 単一レコードの場合: 単一行の取得の場合、QueryRow によりリスクが最小限に抑えられます:

<code class="language-go">query := "SELECT id, name FROM users WHERE email = ?"
var id int
var name string
err := db.QueryRow(query, email).Scan(&id, &name)
if err != nil {
    log.Fatal(err)
}</code>

4.入力の検証とサニタイズ: 準備されたステートメントを使用する場合でも、入力を検証してサニタイズします:

  • サニタイズ: 不要な文字を削除します。
  • 検証: 入力形式、タイプ、長さをチェックします。

入力検証の例:

<code class="language-go">func isValidUsername(username string) bool {
    re := regexp.MustCompile(`^[a-zA-Z0-9_]+$`)
    return re.MatchString(username)
}

if len(username) > 50 || !isValidUsername(username) {
    log.Fatal("Invalid input")
}</code>

5.ストアド プロシージャ: データベース ストアド プロシージャ内にクエリ ロジックをカプセル化します:

<code class="language-sql">CREATE PROCEDURE AuthenticateUser(IN username VARCHAR(50), IN password VARCHAR(50))
BEGIN
    SELECT * FROM users WHERE username = username AND password = password;
END;</code>

Go からの呼び出し:

<code class="language-go">_, err := db.Exec("CALL AuthenticateUser(?, ?)", username, password)
if err != nil {
    log.Fatal(err)
}</code>

ORM による SQL インジェクションの防止

GORM や XORM などの ORM はデータベースのやり取りを簡素化しますが、安全な方法が依然として重要です。

1.ゴーム:

脆弱な例 (動的クエリ):

<code class="language-go">db.Raw("SELECT * FROM users WHERE name = '" + userName + "'").Scan(&user)</code>

安全な例 (パラメータ化されたクエリ):

<code class="language-go">db.Raw("SELECT * FROM users WHERE name = ? AND email = ?", userName, email).Scan(&user)</code>

GORM の Raw メソッドはプレースホルダーをサポートしています。 Where:

のような GORM の組み込みメソッドを優先します。
<code class="language-go">query := "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'"
rows, err := db.Query(query)</code>

2.複雑なクエリでは生の SQL を避ける: 複雑な生のクエリでもプレースホルダーを使用します。

3.安全なマッピングのための構造体タグ: 安全な ORM マッピングのための構造体タグを使用します:

<code class="language-go">query := "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'"
rows, err := db.Query(query) // Vulnerable to SQL injection</code>

避けるべきよくある間違い:

  1. クエリでは文字列の連結を避けてください。
  2. 安全性チェックをバイパスする ORM 機能を回避します。
  3. 検証なしのユーザー入力を決して信頼しないでください。

結論

Golang は、安全なデータベース対話のための強力なツールを提供します。 準備されたステートメント、パラメーター化されたクエリ、ORM を正しく使用し、ユーザー入力を入念に検証してサニタイズすることで、SQL インジェクションの脆弱性のリスクを大幅に軽減できます。

次の方法で私と連絡を取ってください:

  • リンクトイン
  • GitHub
  • ツイッター/X

以上がGolang での生の SQL と ORM による SQL インジェクションの防止の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。