😽

ActiveRecordのプレイスホルダーの使い方

2023/09/22に公開

概要

ActiveRecordのプレイスホルダーの使い方について記載します。プレイスホルダーを使うと不正なデータ取得を防ぐことが出来ます。

やってみる

まず、不正なデータ取得をやってみます。

# frozen_string_literal: true

require 'bundler/inline'

gemfile(true) do
  source 'https://rubygems.org'

  gem 'activerecord', '7.0.7.2'
  gem 'sqlite3'
end

require 'active_record'
require 'minitest/autorun'
require 'logger'

ActiveRecord::Base.establish_connection(adapter: :sqlite3, database: ':memory:')
ActiveRecord::Base.logger = Logger.new($stdout)

ActiveRecord::Schema.define do
  create_table :books, force: true do |t|
    t.string :title
    t.string :author
  end
end

class Book < ActiveRecord::Base; end

class Yakou < Minitest::Test
  def test_usagi
    book1 = Book.create!(title: '夜行', author: '森見登美彦')
    book2 = Book.create!(title: 'ホワイトラビット', author: '伊坂幸太郎')
    book3 = Book.create!(title: 'らせん階段', author: 'エセル・リナ・ホワイト')
    book4 = Book.create!(title: '四畳半神話大系', author: '森見登美彦')

    title = "'夜行' OR 1 = 1"
    assert_equal Book.where("title = #{title}"), [book1, book2, book3, book4]
  end
end

夜行の後ろにOR 1 = 1をつけると意図せずに全てのBookを取得出来ます。一方、プレイスホルダーを使うと取得出来なくなります。

title = "夜行 OR 1 = 1"
assert_equal Book.where("title = ?", title), []

以上です。

Discussion