2
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?

More than 1 year has passed since last update.

【Python・MySQL】SQL文中でテーブル名やカラム名を変数にする方法とその脆弱性について【初心者向け】

Last updated at Posted at 2022-11-09

(22/11/09追記)
コメントにて@retaさんにご指摘いただきました通り、今回の解法は外部から受け取った値をそのままSQL文に挿入すると、SQLインジェクションの脆弱性を引き起こす原因となります。

この記事は、テーブル名やカラム名を変数として使用できること以上に、それらを変数として扱った場合に脆弱性を生むことについての知見をもたらす記事として読んでいただければ幸いです。

また、実際に当記事で紹介する方法を使用する場合においては、外部から受け取った値ではなく、内部的に決定される値が変数に設定されることが保証される環境でのみお使いいただき、特にDjangoで作成したWeb入力欄やそれに類する方法で取得した値を受け渡す場面での使用を控える、もしくは十分な専門知識を持った上で安全を確認してからの使用をお願いします。

この記事を読んで発生したいかなる事由においても私は責任を負うことができませんが、内部でのみ使用したい方にとっての便益も考え、注釈を残したうえで記事を残そうと考えています。
ここまでご理解いただけた場合に、以下ご参考にいただけましたら幸いです。

----------------------------------

初投稿です、よろしくお願いします。

PythonでMySQLを実行する際に、SQL文中でプレースホルダ(%s)を用いる場合に値を変数にすることはできますが、SQL文中のテーブル名やカラム名をプレースホルダにすることはできずに不便だったので、テーブル名やカラム名であっても変数で動的に変更する方法の解説になります。

やっていること自体は単純ですが、「PythonでのMySQL解説」というジャンル内では言語化された記事を見かけなかったので、言語化しておこうと思いました。

format関数を使う方法です。

py
import mysql.connect

# MySQLへの接続処理は中略

sql = ('''SELECT *
          FROM {}    # テーブルに{}を代入
          WHERE {} = %s   # カラムに{}を代入
'''.format(tbl, clm)) 

param = ("hoge", )

cursor.execute(sql, param)

以上の場合、テーブルが変数tbl、カラムが変数clm、カラムの検索対象が"hoge"になります。

フォーマット関数とプレースホルダを同時に使えるのはとても便利だなと思いました。

もし訂正や、より良い方法があれば、コメントいただけると嬉しいです。

2
0
2

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
2
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?