ラボ演習 regex1

これはセキュアなソフトウェア開発に関するラボ演習です。 ラボの詳細については、概要をご覧ください。

ゴール

入力検証のためのシンプルな正規表現の書き方を学びます。

背景

正規表現(regular expressions: regexes)はテキストのパターンを表現するために広く利用されている表記方法です。 正規表現は入力の検証に使うことができます。正しく使用することで、多くの攻撃への対策となります。

正規表現の表記方法は言語により若干異なりますが、大枠では共通しています。以下が正規表現を表記するための基本的なルールです。

  1. 最も単純なルールは、文字や数字はそれ自身にマッチするということです。つまり、"d" という正規表現は "d" という文字にマッチします。多くの実装 ではデフォルトで大文字・小文字を区別してマッチし、それは通常望まれる動作です。
  2. もうひとつのルールは、いくつかの文字のうちどれかを指定するために大カッコで囲むというものです。もし大カッコが単なる英数字を囲っていた場合は、それらは囲まれた英数字のどれかにマッチします。つまり [brt] は単一の文字である "b", "r", "t" のどれかにマッチします。 大カッコの中ではダッシュ("-")で文字の範囲を示すことができます。つまり [A-D] はその範囲の一文字、すなわち一文字の A、一文字の B、一文字の C、一文字の D のどれかにマッチします。 大カッコの中には複数の範囲を書くことができます。 例えば [A-Za-z] は、大文字のアルファベット一文字または小文字のアルファ ベット一文字にマッチします。 (このラボでは EBCDIC のような使われなくなって久しい文字システムを使用していないと仮定しています)
  3. パターンに続けて "*" が書かれた場合、それは"0回以上"を意味します。 ほとんど全ての正規表現の実装では(ただし POSIX BRE を除く)、パターンに続けて "+" が書かれた場合は"1回以上"を意味します。 つまり [A-D]* は、A, B, C, D のどれかが0文字以上続く場合にマッチします 。
  4. 選択肢、つまり指定したどれかにマッチするためには、"|" を使うことができます。 "|" は優先度が低いので、入力の検証に用いる場合は正しい選択肢を小カッコで囲む必要があります。つまり、例えば "yes" または "no" にマッチさせる方法は "(yes|no)" です。

タスクの詳細

正規表現を使って入力の検証を行いたいとします。 それはつまり、入力は正規表現のパターンに完全に一致するということです。 正規表現では、シンボルを前置したり後置したりして、(マルチラインモードではなく)デフォルトモードでそれを行うことができます。 残念ながら、異なるプラットフォームでは入力に完全一致させるために異なる正規表現のシンボルを使用します。 以下の表は様々なプラットフォーム(で使用されるデフォルトの正規表現システム)において、どんな前置や後置が必要かを簡単に示したものです。

プラットフォーム 前置 後置
POSIX BRE, POSIX ERE, and ECMAScript (JavaScript) “^” “$”
Java, .NET, PHP, Perl, and PCRE “^” or “\A” “\z”
Golang, Rust crate regex, and RE2 “^” or “\A” “$” or “\z”
Python “^” or “\A” “\Z” (not “\z”)
Ruby “\A” “\z”

例えば ECMAScript (JavaScript) で入力を "ab" または "de" としたい場合に使用する正規表現は "^(ab|de)$" になります。 同じことを Python で行う場合は "^(ab|de)\Z" または "\A(ab|de)\Z" となります。(正規表現のパターンが少し違うことに注意してください)

より詳しい情報は OpenSSF ガイド Correctly Using Regular Expressions for Secure Input Validation にあります。

演習 ()

以下の要求を満たす正規表現(regex)のパターンを作成してください。

必要に応じて「ヒント」や「諦める」のボタンを押してください。

Part 1

ECMAScript (JavaScript) で使うことを想定して、文字 "Y" または "N" のみにマッチする正規表現を作成してください。


Part 2

ECMAScript (JavaScript) で使うことを想定して、1文字以上の大文字のアルファベット(A から Z)にのみにマッチする正規表現を作成してください。


Part 3

ECMAScript (JavaScript) で使うことを想定して、単語 "true" または "false" のみにマッチする正規表現を作成してください。


Part 4

1文字以上の大文字のアルファベット(A から Z)にのみにマッチする正規表現を作成してください。 ただし今回は、(JavaScript ではなく)Python で使うことを想定してください。


Part 5

1文字の大文字のアルファベット(A から Z)に続けてダッシュ ("-")、さらに続けて1文字以上の数字にのみにマッチする正規表現を作成してください。 今回は、(JavaScript ではなく)Ruby で使うことを想定してください。




このラボは、Linux FoundationのDavid A. Wheelerによって開発されました。