SQLite3::escapeStringの使用法とは?

このQ&Aのポイント
  • SQLite3クラスのメソッドescapeStringを使って、SQL文の中に挿入する文字列の浄化(SQLインジェクション対策)をする方法について教えてください。
  • 具体的には、指定した文字列をエスケープして安全に使用するために、SQLite3データベースをオープンし、escapeStringメソッドを呼び出すことが一般的です。
  • ただし、文字列の浄化だけを行いたい場合には、必ずしもデータベースをオープンする必要はありません。その場合は、:memory:を指定することで一時的なデータベースを作成します。
回答を見る
  • ベストアンサー

SQLite3:: escapeString使用法

SQLite3クラスのメソッドescapeStringを使って、 SQL文の中に挿入する文字列の 浄化(SQLインジェクション対策)をする場合の、 一般的な作法について教えて下さい。 例えば、 //----------------------- //エスケープしたい文字列 $var= "Let's"; //オープンするデータベース $db= ":memory:" $obj = new SQLite3($db); $tmp = $obj->escapeString($var); $db->close(); //----------------------- こんな感じで使おうとしていますが、 「オープンするデータベース」の所が、 ちょっと理解できていません。 とりあえず文字列の浄化だけを行いたい場合には、 必ずしも、DBをオープンする必要はないと思いますので、 オープンするDBなんて、ないですよ! ということで、 :memory: を指定していたりしますが、 この辺りの正しい作法について、どなたか教えて下さい。

  • march4
  • お礼率83% (628/754)
  • PHP
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • agunuz
  • ベストアンサー率65% (288/438)
回答No.1

>とりあえず文字列の浄化だけを行いたい場合 この意味がわかりません。データベース固有のエスケープは文字列をデータベースに格納する直前に行うべき処理です。「とりあえず」やる必然性がありません。 htmlspecialcharsをブラウザに返す直前に通すのと同じです。htmlspecialcharsした状態で保持する意味なんてありませんよね。逆に『2回通して』しまって壊してしまう可能性が増えるだけです。

march4
質問者

お礼

回答をありがとうございます。 やはり、つっこまれてしまいましたね。(笑) えっと、私は以前から、 プリペアドステートメント(PDO::prepare)を使って、 SQL文を作成していたのですが、 それでも、そのSQL文の作成時には、 エスケープ処理は必要なのだと、 これまで誤解しており、 そのため、今回、この、PDO::prepareを使った処理の間に、 SQLite3:: escapeString を使ったエスケープ処理を、 挟み込もうとしていました。 つまり、この方法ですと、 浄化をする時には既に、PDO経由で、 使用するDBはオープンされているわけなので、 改めて、 new SQLite3($db); でもって、 DBをオープンすることはないだろ、 と、私は考えたわけです。 しかし、今回、皆さんから、 上記のプリペアドステートメントでSQL文を作成していれば、 「その時点で、エスケープ処理の問題は既に解決済みだよ!」(←間違ってたら教えて下さい。照) ということを教わりましたので、 今後も、引き続き、 SQLite3クラスの「escapeString」ではなく、PDO::prepareを使って、 セキュアーに「SQLite3のDB」を使用していけたらと考えています。 以上、また何か変なことを言っていましたら(笑)、 また、よろしければ、教えてください。

関連するQ&A

  • SQLiteのデータベースについて

    PHP初心者です。以下のSQLiteより作成するデータベースについて教えてください。 $DB = sqlite_open('db1.db'); $sql="create table tables(id integer ,name,texts)"; $result=sqlite_query($db,$SQL); 上記、プログラムにより、同ディレクトリに、db1.dbが作成されますが、このデータベース情報はどのようにして、閲覧するのでしょうか(MS-ACCESS、SQLのように簡単に閲覧できないのか)。主キーやテーブルの名前またはフィールドの名前の変更、データ一覧閲覧などどのようにするのでしょうか。 環境は、Windows環境で、PHP4を使用しております。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • SQlite

    SQLiteを使って メールを保存するデータベースを作っています。 以下のようになっています。  さらに、 アドレス帳を作りたいのですが 新たにデータベースを開くのか 同じデータベースで別のテーブルを開けばよいのかわかりません。 ご存知の方よろしくお願いします。 また、 C++からSQLiteを扱う上での参考書などもありましたら 教えてください。 rc = sqlite3_open(".\\mailbox\\SQMail.db", &db); if( rc ){ AfxMessageBox("Can't open database:", MB_OK); sqlite3_close(db); return; } rc = sqlite3_exec(db, "create table MailTbl (id INTEGER PRIMARY KEY, attach varchar(20), subject varchar(120),addressfrom varchar(80),addressto varchar(80),date varchar(80),size integer,priority integer, read integer, state integer, alldata blob);", callback, 0, &zErrMsg); if( rc!=SQLITE_OK ){ // AfxMessageBox("SQL error:", MB_OK); sqlite3_free(zErrMsg); }

  • Sqliteで使えない文字。

    Sqlite3にて 列名やデータ内で使えない文字列(記号等の文字コード)を教えてください。 調べてみた情報では 改行や区切り文字などの基本的なことしか見つかりませんでしが 実際に使っていると、半角スペース等が混入している場合 全てではありませんが、データベース内で明らかに存在するのに検索できないなどの場合 があるようです。 一つずつ調べてエスケープ処理をすることは現実的に不可能なので 独自にエスケープ処理等を書かれている方に どのような文字列をエスケープしていますでしょうか?

  • SQLインジェクション対策(クオーテーション関連

    PHP Version 5.4.7の環境にて。 SQLite3::escapeStringを使って、 SQLインジェクション対策をしようと考えています。 HTMLの<form>からPOSTで値を受け取り、 その値をSQL文に入れ込み、 そのクエリ(※ちなみに、INSERTのみです。)をSQLite3のDBに対して行う、 なんてことをする際の、 SQLインジェクション対策として、お考え下さい。 POSTで受け取る値に入っていたら危険なものとして、 「シングルクオーテーション」が、まず、挙げられるかと思います。 「'」 ←これです。 さて、「"」 ←こちらはダブルクオーテーションですが、 こちらのダブルの方はエスケープする必要は無いのでしょうか? (例)※wikipediaより SELECT * FROM users WHERE name = '(入力値)'; SELECT * FROM users WHERE name = 't' OR 't' = 't'; → このSQL文では条件が常に真となるため、 nameカラムの値にかかわらず、全レコードが選択される。 → ということで、入力値に、 エスケープされていない「シングルクオーテーション」をそのまま使うのはNG。 ここまではOKです。 では、次に、ダブルクオーテーション版で、 SELECT * FROM users WHERE name = "(入力値)"; SELECT * FROM users WHERE name = "t" OR "t" = "t"; こちらはどうなのでしょうか? (シングルをダブルに変えただけですが。) ---------- ちなみに、 SQLite3::escapeString にて、 (1) $var = "Let's"; //←シングルクオーテーション $db = new SQLite3(':memory:'); $escaped_var = $db->escapeString($var); echo $escaped_var; //Let''s と表示される (「 ' 」が1つ追加される。) (2) $var = 'Let"s'; //←ダブルクオーテーション $db = new SQLite3(':memory:'); $escaped_var = $db->escapeString($var); echo $escaped_var; //Let"s と表示される (何も追加されず。) というように、 シングルクオーテーションはエスケープされるが、 ダブルクオーテーションの方ではエスケープされませんでした。 これは、つまり、 ダブルクオーテーションの方は危険視されていない、 ということだと思いますが、 でも、本当にダブルクオーテーションをエスケープせずに、 そのまま、SQL文につっこんでも大丈夫なのでしょうか?

    • ベストアンサー
    • PHP
  • sqlite_escape_stringのアンエスケープ方法

    sqliteのエスケープ方法としてPHPマニュアルでは sqlite_escape_string() を利用することが望ましいと 記述されています。 実際にsqlite_escape_string() を使用してDBに格納するのは 問題ないのですが、データを取り出したときに エスケープされたままで出てきます。 アンエスケープする方法はどのようなものでしょうか? str_replace("'","''",取り出した文字列); とかではないですよね・・・。

    • ベストアンサー
    • PHP
  • BCBでSQLite

    下記のサイトを参考にさせて頂き、BCB5を使用してSQLite3を操作しようと格闘中です。 自分のレベル的には初心者を脱しようかといったところだと思います。 http://members.jcom.home.ne.jp/komina/wiki/4243422F53514C69746533A4F2BBEEA4B9.html TEdit1一つに郵便番号7桁を入力して、Button1クリックで該当する住所を検索してMemo1に表示するものですが、コンパイルエラーになってしまい対処法がわかりません。 ちなみにそこで紹介されている、ライブラリをリンクするのが上手くいきませんで sqlite3.cをプロジェクトに追加してメイクしました。 また、文字コードをUTF-8に変換するというのが別サイトにも書かれていました エラー内容は、 E2034 'int(*(_closure))(void *,int,char**,char**))(void*,int char**,char**)'型は'int(*)(void*,int,char**,char**)'型に変換できない。 E2342 パラメータ'callback'はint(*)(void*,int,char**,char**)型として定義されているのでvoidは渡せない 以下、ソース抜粋です。宜しくご教授お願いいたします。 int TFmMain::callback(void* arg,int argc,char** argv,char** column){ AnsiString addr1=argv[0]; AnsiString addr2=argv[1]; AnsiString addr3=argv[2]; add_message(addr1+addr2+addr3); return SQLITE_OK; } void __fastcall TFmMain::Button1Click(TObject *Sender) { sqlite3* db; if(sqlite3_open("DBTEST1.db",&db)==SQLITE_OK){ add_message("DB open"); int rtn; char* sql; sql=sqlite3_mprintf("SELECT ADDR1,ADDR2,ADDR3 FROM ZIP WHERE ZIP=%d" ,StrToInt(Edit1->Text)); add_message(sql); rtn=sqlite3_exec(db,sql,callback,NULL,NULL); <<< ここでエラー発生!! if(rtn!=SQLITE_OK){ add_message("COMMAND err"); } sqlite3_free(sql); sqlite3_close(db); add_message("DB close"); }else{ add_message("DB open err"); } }

  • PHP5でSQLiteが接続エラーを出します

    PHPには初心者です(データベースには多少知識有るはず)。 PHPからSQLに商品データを登録するシステムを作っていますが、データベースに接続することができません。 繋げるためにはどこを直したらよいでしょうか。 データベース名はshop、テーブル名はitemです。 SQLite:バージョン 2.8.17 PHP:バージョン 5.1.6 WindowsXPのプロフェッショナル、eclipse3.2、参考にした本は『eclipseではじめるPHP(http://item.rakuten.co.jp/book/4296315/)』と『基礎PHP(http://item.rakuten.co.jp/book/1711777/)』です。 エラーが出る行 if(!$db = sqlite_open('/../SQLiteManager/shop')){ die("データベース接続エラー.<br/>"); } エラー文 Warning: sqlite_open() [function.sqlite-open]: unable to open database: C:\SQLiteManager\shop in C:\Eclipse\workspace\shop\touroku.php on line 23 データベース接続エラー. PHPのフォルダ内にある 『PHP.iniextension=php_pdo_sqlite.dll』 『extension=php_sqlite.dll』 のコロンは外しました。 SQLiteManagerはworkspaceの中です。 設定が悪いのかファイルを置く場所が悪いのか、それともプログラムが悪いのかもわかりません。 宜しくお願いいたします。

    • 締切済み
    • PHP
  • yahooウィジェットのSQLiteに関して

    どうしてもわからず、質問させてください。 INSERTの所で 1 near "[i]" :syntax error と出てしまいます。 配列にはちゃんとデータが入っていることを確認しました。 どこがおかしいのかお分かりになる方すいませんが、お願いします。 またyahooウィジェットのSQLiteはトランザクションは使えるのか知っている方いましたら合わせてお願いいたします。 ▼ソースは以下のようなものです var db = new SQLite(); //オープン db.open( "オーブンファイル名" ); //テーブル存在確認 var result = db.query( "SELECT * FROM sqlite_master WHERE type='table' AND name='テーブル名'" ); if ( result.getRow() == null ) { result.dispose(); db.exec( "CREATE TABLE テーブル名(id int(10),name varchar(255))" ); FileRead( "ファイル読み込み" ); for (var i in lineArray) { alert(lineArray[i]); db.exec( "INSERT INTO テーブル名(id, name) VALUES(i, lineArray[i])" ); } } db.close;

  • BCBでSQLite操作

    下記のサイトを参考にさせて頂き、BCB5からSQLite3を操作しようと格闘中です。 http://members.jcom.home.ne.jp/komina/wiki/4243422F53514C69746533A4F2BBEEA4B9.html TEdit1に郵便番号7桁を入力して、Button1クリックでMemo1に該当住所等を表示するものですが コンパイルエラーが発生して対処法がわかりません。ご教授お願いいたします。 ちなみに、そこで紹介されているライブラリのリンクが上手くいかないので sqlite3.cをプロジェクトに追加してメイクしております。 また、別のサイトではUTF-8を使わないといけない様なことも書いてありました。 エラー内容は、 E2034 'int(*(_closure)(void*,int char**,char**))(void*,int,char**,char**)'型は'int(*)void*,int,char**,char**)'型に変換できない E2342 パラメータ'callback'はint(*)(void*,int,char**,char**)型として定義されているのでvoidは渡せない 以下、ソース抜粋です。 int TFmMain::callback(void* arg,int argc,char** argv,char** column){ AnsiString addr1=argv[0]; AnsiString addr2=argv[1]; AnsiString addr3=argv[2]; add_message(addr1+addr2+addr3); return SQLITE_OK; } void __fastcall TFmMain::Button1Click(TObject *Sender) { sqlite3* db; if(sqlite3_open("DBTEST1.db",&db)==SQLITE_OK){ add_message("DB open"); int rtn; char* sql; sql=sqlite3_mprintf("SELECT ADDR1,ADDR2,ADDR3 FROM ZIP WHERE ZIP=%d" ,StrToInt(Edit1->Text)); add_message(sql); rtn=sqlite3_exec(db,sql,callback,NULL,NULL); <<< ここでエラー発生します!! if(rtn!=SQLITE_OK){ add_message("COMMAND err"); } sqlite3_free(sql); sqlite3_close(db); add_message("DB close"); }else{ add_message("DB open err"); } }

  • PHP+ACCESSのデータベース接続について

    こんにちわ。PHP+ACCESSを使って、データベース接続を試みようとしておりますが、最初のところでつまづております。 <?php //データベースに接続する $DB = sqlite_open('db.mdb'); $SQL = "create table db (id integer ,name,time) $result = sqlite_query($DB, $SQL); ?> 上記のPHPで、ACCESSファイルを作成しましたが、作成したファイルを開くと、"データベース形式が認識できません"と表示し、データベースを閲覧することができません。 また、ACCESSから手動で作成したファイルをsqlite_openで接続しようとすると、sqlite_open(): file is encrypted or is not a database inエラーが表示接続することができません。 PHPとACCESSの相性の問題なのでしょうか。この原因がわかる方がいらっしゃいましたら、教えていただけないでしょうか。 宜しくお願い致します。 【php4.3.10 SQLite Library2.8.14 ACCESS2000】

    • ベストアンサー
    • PHP

専門家に質問してみよう