クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

入力値の検証(バリデーション)

このレッスンのあとで: 値を使う前に、型と長さと範囲を許可リストで確かめるコードを書ける。

55分のレッスンコマンド3件SQL インジェクションのラボ:弱い検索を攻撃し、クエリを直して確かめる

入力値の検証とは何か

入力値の検証(バリデーション)とは、プログラムが受け取った値を、使う前に決まりと照らして確かめることです。検証を飛ばすと、想定外の値が計算や保存の中へ入り、不具合や攻撃につながります。

大学の履修登録フォームを考えます。学籍番号の欄に全角の数字を打つ人も、1万字を貼りつける人も、必ずいます。

このレッスンのゴール

メモ

値を使う前に、型と長さと範囲を許可リストで確かめるコードを書ける。

今日のキーワード

ことばいみれい
検証値が決まりに合うかを、使う前に確かめることです。
許可リスト通してよい文字や語を並べた一覧です。
型値の種類です。数、文字、真偽などがあります。
範囲値が取ってよい、最小から最大までの幅です。18 から 120
正規化同じ意味の値を、1つの決まった形にそろえることです。

学生が入力するセルは、このプレビューでは空白です。

たった1つのルール

注意

試してよいのは、自分専用のラボのコピーだけです。このラボは、わざと弱く作った店で、インターネットにはつながっていません。許可のない他人のシステムに同じことをするのは、不正アクセス禁止法に触れる犯罪です。

許可リストで確かめる

検証の基本は、通してよいものを先に決めることです。学籍番号が数字8桁なら、「数字」と「8文字」だけを通します。

「怪しい文字を探して止める」やり方は、探し忘れた文字が通ります。許可リストなら、リストにない文字は全部止まります。

数字8桁だけを通す

コード: python
GOOD = "0123456789"

def is_student_no(text):
    if len(text) != 8:
        return False
    for ch in text:
        if ch not in GOOD:
            return False
    return True

# 文字を変えて、実行します。全角の数字は通りますか。
print(is_student_no("20250123"))
print(is_student_no("20250123"))
print(is_student_no("2025 123"))

型と長さと範囲を確かめる

値は3つの面から確かめます。型は、数か文字かなどの種類です。長さは、文字の数です。範囲は、数の最小と最大です。

3つとも守る値だけを通します。どれか1つでも外れたら、理由を短く伝えて、その値は使いません。

例: 履修登録フォームの決まり

欄型長さ・範囲外れた値の例
名前文字1から20字空の欄、1万字の貼りつけ
年齢数字だけ18から12017、300、abc
郵便番号数字7桁ハイフンは除く123-45、1234567
学籍番号数字だけちょうど8字2025 123

学生が入力するセルは、このプレビューでは空白です。

全角の数字は数字なのか

Python の isdigit() は、全角の「123」も数字と答えます。int() も、全角を数に直します。見た目が違っても、プログラムは数字と考えるのです。

表の文字と見た目が違うと、比べる処理や保存でずれが出ます。だから、通す文字は、"0123456789" のように自分で書いて決めます。

全角の数字を調べる

コード: python
# 全角の数字は、半角と同じ文字ではありません。
print("20".isdigit())
print(int("20"))
print("20" == "20")
print("2" in "0123456789")
print("2" in "0123456789")

ラボの店に、変わった入力を送る

ラボの店に、変わった入力を3つ送りましょう。どれも見るだけです。1つ目は空の検索ことば、2つ目は60文字のことばです。

店は、どちらも断りません。3つ目はラボの店ではなく、店のコンテナに入っている Python で、全角の数字を調べます。

空の検索ことば

コマンド
curl -s -G --data-urlencode "q=" http://app:8000/search

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

60文字のことば

コマンド
curl -s -o /dev/null -w "%{http_code}\n" -G --data-urlencode "q=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" http://app:8000/search

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

全角の数字を調べる

コマンド
docker exec app python -c 'print("\uff11\uff12\uff13".isdigit(), int("\uff11\uff12\uff13"))'

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

3つの答えを読む

1つ目は、公開の5つの商品を全部表示します。空の欄を、店は断らず、「何にでも合う」と読みます。2つ目は 200 を表示します。長いことばも、そのまま受け取りました。

3つ目は True 123 を表示します。全角の数字は、数字で、しかも 123 という数です。店は、この3つの面を何も確かめていません。

よくある間違い

注意

「画面の JavaScript で確かめたから、サーバーでは確かめなくてよい」と考える人がいます。それは違います。画面の確認は、利用者への親切です。攻撃する人は画面を通りません。守るのは、サーバー側の確認です。

このラボとソースについて: SQL インジェクションのラボ:弱い検索を攻撃し、クエリを直して確かめる

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。