アプリ版:「スタンプのみでお礼する」機能のリリースについて

HTML+CSS+PHP+MySQLで「SQL実習サイト」を作っています。
SQLを入力し、その結果を確認するという学習用のサイトです。
現在はXAMPP上で動かしているだけですが、上手くできたらWeb上に上げる予定です。
質問は、そのサイトでのSQLインジェクション対策についてです。

作成している「SQL実習サイト」では、フォームにSQL文を直接入力してもらい、そのままその
SQL文をPHPで実行するようにしています。
具体的には、POSTで自分自身(index.php)にSQLを送信し、それをクエリとして実行しています。

<h2>SQL入力</h2>
<form action="index.php" method="post">
    <textarea name="input_sql" cols=38 rows=3></textarea>
    <input id="sql" type="submit" value="SQL実行">
</form>
(~略~)
$_SESSION['jikkou_sql'] = $_POST['input_sql'];
(~略~)
$sql = $_SESSION['jikkou_sql'];
$query = mysql_query($sql, $conn);

IPAの「安全なSQLの呼び出し方」等から調べると、SQLインジェクション対策としては
プレースホルダ(プリペアド・ステートメント)が有効だとありますが、
作成しているケースだとSQLを直接実行するのでプレースホルダが使えない気がします。

「SQL実習サイト」ではSELECT文のみ実行できるようにしたいと考えています。
入力してもらったSQLの中で「SELECT」を探すようにして自作のSQLインジェクション対策を
行えばよろしいのでしょうか?(DELETEやUPDATEがあれば無効化したり・・・)
それとも、そもそもこのような使い方ではSQLインジェクション対策はできないのでしょうか?

ご教授よろしくお願いします。

A 回答 (4件)

サブクエリなどもあるので、先頭がSELECTかどうかだけを判定するだけではさすがに不十分すぎます。

オススメの方法としては、MySQLを捨ててSQLiteを使うことです。SQLiteであればユーザーごとにファイルを生成することができ、個別のデータベース空間を与えることが出来ます。この状態であれば何されても特に問題はありません。(重いSQL実行によるサーバー負荷とかは注意)


PHPでデータベースに接続するときのまとめ
http://qiita.com/mpyw/items/b00b72c5c95aac573b71

・mysql_query関数は問答無用でやめましょう…
・ユーザーが実行不能なSQLを投げてくることも想定し、「PDO::ERRMODE_EXCEPTION」を有効にしておき、例外を捕まえられるようにしましょう。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
古い書籍を参考にしているので現状ではmysql関数でした…
実際に上げるときはPDOにしようと思います。
また、想定しているレンタルサーバがMySQLのみ対応です。
まだレンタルしていませんのでSQLiteも視野に入れて考えてみようと思います。
SQLiteでユーザーごとにファイルを生成する、ということに対しての理解は
私自身は不十分ですので調べてみます。ありがとうございます。

お礼日時:2014/07/09 19:57

>> また、想定しているレンタルサーバがMySQLのみ対応です。



SQLiteってただの "1つの" ファイルだけでデータベースのように扱えるものなんですよね。レンタルサーバーがもし「MySQLしか対応していない」という表記でも、SQLiteは使えるというケースがあります。レンタル前にサーバー管理者に「PDO_SQLITEは使えますか?」と聞いてみるのもいいと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
SQLiteを使う方向で考えて見ます。
また、No5さんが回答してくださったように想定しているレンタルサーバでも
SQLiteは使えるようです。

お礼日時:2014/07/10 07:27

所詮プレースホルダは「値を安全に渡せる」というだけのことですから


SQLをそのまま走らせるような処理は無理ですね

ただ考えてみれば、インジェクション対策の意義は
(1)データ挿入・更新・削除など勝手にされないようにする
(2)アクセスできるdbやtableを制限する
(2)表示させるカラムやレコードを制限する

という趣旨ですから、実行ユーザーの権限をうまく抑制すれば理論上問題は
極小化できます。むしろ、とかく手抜きでDSNにrootユーザーを設定しがちですが、
検索だけが目的なら本来どんなSQLの発行も権限を抑えられたユーザーにすべきです。

あとはたぶん汚いSQLが大量に流れてくるでしょうから、エラー処理など適切に
設定する必要はあるでしょう。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
PHPで対策をすることしか考えていませんでしたので、DBの権限のことは
どのように実現できるかわかりませんので調べてみます。
また、エラー処理は現状では、
if(!$query) → エラーメッセージ
と、クエリがおかしい場合のみのエラーメッセージ表示のみです。

お礼日時:2014/07/09 20:02

DBの接続ユーザーを新規に作成して、特権情報でselectのみを許可する。


root権限のない、レンタルサーバーじゃ無理だろうけど…。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
想定しているレンタルサーバはさくらインターネットです。
調べたところroot権限があるような感じはしなかったです…。
もう少し調べてみます。

お礼日時:2014/07/09 19:53

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!