項 1 / 13
目的と使う場面を知る
何ができるようになるか、何のために学ぶかを確認します。
今回できるようになること
入力した名前をSQLの命令へ混ぜず、指定した人の書類だけを取り出せるようにする。
この節で学ぶ理由と、前後の節とのつながり
このセクションの位置づけ
なぜ、今これを学ぶのか
サーバーが利用者を確認しても、保存したデータの探し方を間違えると、他人の書類が混ざることがあります。検索の命令と、入力した名前などの扱いを学びます。
ここまでの知識をどう使うか
前の節で学んだ、会社や持ち主で書類を絞る検索を使います。今回は、検索する文字に記号が含まれていても、別の命令として扱われない書き方を学びます。
この後、何につながるか
必要な書類だけを探せたら、次はアプリに与える操作の許可を見直します。読む仕事に削除の許可まで必要かを考えます。
この実習で確かめること
名前に記号があっても検索でき、別の会社の書類を返さない
実務では、どんな場面?
架空の書類表reportsには、持ち主ownerがaliceの本文Aと、bobの本文Bがあります。検索する値はvalueへ入ります。通常のaliceだけでなく、引用符を含む文字列でも検索し、値がSQLの命令に変わる不具合を直します。データベースは実行のたびにメモリー内へ作り直すSQLiteです。
読み始める前に:この節の前提と言葉
は、ここでは書類を表として保存するものと考えます。はその表へ検索などを依頼する言葉。まず表の行と列を見て、次に行を選ぶ条件を書きます。の===や&&と、の=やを混同しないようにします。
- 表・行・列
- 表は同じ項目を持つデータの集まりです。今回のreportsにはowner(名前)とbody(本文)があります。行は一件の記録です。返す列と返してよい行を別に考えます。
- ・
- はこの実習で使うの仕組み、は問い合わせを書く言語です。実習では架空の表に対する制限付きの読取りだけを行います。
- ・・
- は返す列、は表、は行の条件を表します。の条件に合う行から、で指定した列を返します。
- 値・文字列・引用符
- O'Reillyのような名前はデータの値です。中の文字列は通常単一引用符で囲みます。入力にある引用符までへ連結すると、値と命令の境界が変わります。
- ・
- は値を別に渡す位置です。今回はの?に対し、Pythonの別引数で(value,)を渡します。値が一つでも末尾のカンマを残します。名前付きの:labelを使う方式もありますが、今回は?です。
- 完全一致・該当なし
- 完全一致は値が同じ行だけを選ぶこと。該当する行がなければ0件も正常な結果です。のエラーとは区別します。今回はによる部分一致は扱いません。
- ドライバー
- アプリからを利用するための接続部品です。使える命令や値の渡し方はや部品ごとに違うため、実務へ移すときはその仕様を確認します。
は表へ検索などを頼む言葉です。今回のreportsという表には、持ち主ownerと本文bodyがあります。 body reports owner = ?は、?へ別に渡す値とownerが合う行の本文を返す枠です。
は両方、は少なくとも一方の条件が必要なことを表します。がより先に結び付きます。会社・公開状態などの条件も実サービスでは別に必要ですが、今回の表の列と混同しないようにします。
- 検索する名前を入力
- 表から探す
- 返った本文を確認
では'で囲んだ部分を文字列として扱います。外側のは条件を結ぶ命令、--はその行の残りを命令として読ませないための記号です。文字列の内側なら、同じ記号も値の一部です。
利用者が入れた文字を、の引用符の間へそのままつなげるとどうなるでしょうか。入力中の'が文字列の終わりと読まれ、その後ろが命令になることがあります。検索したい名前と、処理の指示を分ける必要があります。
並んだ項目を見比べ、違う点と同じ点を読み取ります。
- 文字列の内側:記号も検索値の一部
- 文字列の外側:ORなどが命令になる
利用者の文字を引用符の間へ直接つなぐと、引用符を閉じられて命令に混ざる恐れがあります。
今回の最初のコードは、入力した値をの文字列へつなげます。引用符とを含む値を渡すと、名前の一致を調べるはずの条件が変わり、別の名前の本文まで返ります。これがです。
削除や複数命令を実行できなくても、読むだけで情報は漏れます。会社や本人を確認する規則があるサービスでは、その条件も入力によって崩れないかを調べます。今回のreportsは架空の名前と本文だけの小さな表です。
- 値をSQLの文字列へ連結
- 入力の記号が命令になる
- 検索対象以外の本文も返る
今回のPythonではconnection.executeの最初の引数に、二つ目に値を渡します。?は値を置く位置で、引用符で囲みません。(value,)は値が一つ入った組を表し、末尾のカンマが必要です。
別に渡した名前は命令として読み直されません。引用符を含む名前もそのまま扱います。他のでは:labelのような名前付きの印を使う場合がありますが、この課題の印は?です。
- 命令の枠に?を書く
- 値を別に渡す
- 値をSQL命令として連結しない
値を別に渡しても、その利用者が誰の書類を読んでよいかという条件がなければ、他人の書類を探せる場合があります。命令と値の分離は、の代わりにはなりません。
この実習は固定の架空入力を使って検索値の扱いを直します。本物のログインや会社の境界の確認は行いません。別の独力確認を追加するのでなく、同じ課題の正常な名前と記号入りの値を比べます。
- 入力を値として扱う
- 読む許可も確認
- 両方を満たすデータだけ返す
初期コードへ引用符入りの入力を渡したときと、普通の名前を渡したときの結果を比べます。入力をそのまま命令へ連結すると、値の引用符が命令の構造を変える恐れがあります。
修正後は通常の名前で必要な本文が返り、命令を含むように見える文字列でも条件が変わらないかを確かめます。名前に引用符がある場合に文字を勝手に削って別の名前へ変えないことも大切です。
- 普通の名前と記号入りの名前
- 同じ検索関数
- 必要な結果を維持し混入を防ぐ
exercise.pyのlookupにあるexecuteを修正します。は body reports owner = ?という枠、検索値は(value,)という別の引数です。返された行の本文を結果へまとめる部分はそのまま使います。
は値のための仕組みです。利用者に表名や列名を自由に書かせるためには使えません。その場合はアプリが用意した候補から選ぶなど別の設計が必要です。
- Pythonのexecute
- SQLと値を別の引数へ
- SQLiteが値を扱う
で削除や更新を禁止すると、被害を抑える助けになります。しかし、だけでも、他人の行を読めてしまう問題は残ります。返った行をアプリが本人の情報と思い込むと、ログインの確認をすり抜ける原因になることもあります。
に与える権限を小さくする対策と、値を命令とは別に渡す対策は、どちらも必要です。この実習は検索を扱います。ログイン、パスワードの確認、の発行は別の課題です。
並んだ項目を見比べ、違う点と同じ点を読み取ります。
- DBは読取りだけ:削除や更新の被害を抑える
- 値と命令を分ける:読める行の条件を変えさせない
SELECTだけの権限でも、他人の行が読めれば情報は漏れます。
実行ごとに作る架空のの表を検索し、result.jsonへ結果を出します。最新の結果と修正したexercise.pyを提出します。サーバーで学習者のコードを実行する方式ではありません。
エラーで結果が出ない場合は、エラー文と修正した行を先に確認します。エラーがないのに他人の本文が混ざる場合は、の枠と値を本当に別々に渡したかを見直します。
- 修正前の検索結果
- 修正後の同じ入力
- 本文の違いと理由を提出
依頼が変わったら、どの書類を検索結果に残すか考え直す
検索語などの値を命令とは別に渡す方法は続けたまま、返す書類の条件を今回の依頼から決め直します。自分の資料を探す場合と、同じ部署で共有した資料を探す場合では、WHEREに書く条件が異なります。持ち主の条件が不要になっても残したままだと、他の人が共有した必要な資料まで消えてしまいます。
並んだ項目を見比べ、違う点と同じ点を読み取ります。
- 値を命令と分ける::labelなどへ検索語を渡す
- 返す行を絞る:会社・持ち主・公開状態など
値を別に渡しても、読む許可の条件は自動では付きません。必要な行と不要な行を今回のルールで分け、WHEREの条件と実際のIDを比べます。
- 今回返す行と返さない行を小さな表で分ける。
- 検索語を入れる場所には :label などを書き、値は別に渡します。どの行を返すかはWHEREの条件を直します。
- 通常値と引用符入りの値の両方で、余分な行と欠落を調べる。
ここでは実務で条件が増えた場合の考え方も紹介しました。今回の実習で操作する範囲は、次の「自分のパソコンで確かめる」で確認します。追加の別課題を提出する必要はありません。
検索する値をSQLの命令へ混ぜずに渡す
本文の知識を、この実習でどう使うか
の命令と検索する名前を別々に渡すと、名前に引用符が入っても命令として読み直されません。?は値を置く位置です。
- の枠と検索値
- 別々にへ渡す
- 通常の名前と引用符入りを比較
結果が違ったときに考えること:引用符を削る修正では正しい名前も変わります。値一つを渡す(value,)のカンマと、?を引用符で囲んでいないことを確認します。
入力した名前をSQLの命令へ混ぜず、指定した人の書類だけを取り出せるようにする。
WindowsまたはMacの操作手順、準備に失敗したときの確認方法、実行コマンドは実習画面に用意しています。ページ下部の「準備から実習を始める」から進んでください。
この実習の架空データで確認した結果です。実際の利用者や本番システムの安全性を保証しません。