1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】SQLインジェクション

Posted at

はじめに

こんにちは。アメリカに住みながら、独学でエンジニアを目指している Taira です。
現在セキュリティについて、徳丸本を使用しながら学習中ですが、そこで出てきた SQL インジェクションについてまとめてみようと思います。

SQL インジェクションとは?

SQL インジェクション(SQL Injection)は、ユーザーからの入力値がアプリケーションによって適切に検証・エスケープされずにそのまま SQL クエリとしてデータベースに渡されることで、悪意のある SQL 文が実行されてしまう脆弱性です。

攻撃者の目的

  • ログインをバイパスする
  • 本来見られない機密データを抽出する
  • データの改ざん・削除を行う
  • データベースサーバーに対して DoS 攻撃を仕掛ける

仕組みの概要

通常、アプリケーションでは以下のようにユーザーの入力をもとに SQL 文を生成して、データベースへ問い合わせを行います。

User.where("name = '#{params[:name]}'")

このとき、params[:name]"' OR '1'='1" というような値を与えると、次のような SQL 文が生成されてしまいます:

SELECT * FROM users WHERE name = '' OR '1'='1'

このクエリは常に真となる条件を持つため、すべてのユーザー情報を取得してしまう危険性があります。これが SQL インジェクションの基本的な攻撃原理です。

このような攻撃は、データの漏洩、改ざん、アカウントのなりすまし、さらにはアプリケーション全体の制御権の奪取にまでつながる可能性があります。

安全な書き方(推奨)

Rails では、**バインドパラメータ(プレースホルダ)**を使用することで、SQL インジェクションを防ぐことができます。

User.where("name = ?", params[:name])

このように書くことで、params[:name] の値は SQL 文に直接埋め込まれず、適切にエスケープ処理された上でクエリに渡されます。その結果、不正な入力が SQL 文の構造を壊すことができなくなり、安全に値を扱うことができます。

Active Record では他にも以下のような安全な記述が可能です:

User.find_by(name: params[:name])

これらの記法は内部でプレースホルダを使用しており、安全性が保たれています。

User.where("name = ?", params[:name])

まとめ

SQL インジェクションは、ユーザー入力を適切に扱わないことで発生する重大な脆弱性です。特に Web アプリケーションでは、入力値をそのまま SQL 文に組み込むのは非常に危険です。

  • 危険な例:where("name = '#{params[:name]}'")
  • 安全な例:where("name = ?", params[:name])

Rails のようなフレームワークを使う場合でも、常に「プレースホルダ」や「安全なメソッド」を使うことで、SQL インジェクションを防ぐことができます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?