34
再再再 再再再再 JSON Validator 再再再再再 再再再再再再 再再 再再 <[email protected]>

再帰的 正規表現JSON Validator

Embed Size (px)

DESCRIPTION

PCREの記法(?R)(?0)(?1)を使うテクニック

Citation preview

Page 1: 再帰的 正規表現JSON Validator

再帰的 正規表現JSON Validator再帰的 正規表現JSON Validator

サイボウズ・ラボ株式会社竹迫 良範

<[email protected]>

Page 3: 再帰的 正規表現JSON Validator

(?R)

Page 4: 再帰的 正規表現JSON Validator

再帰的正規表現で JSON Validator を作ってみた再帰的正規表現で JSON Validator を作ってみた

PCRE の記法 (?R)(?0)(?1) を使うテクニック$json =~ /\A (

\s* (?: "(?:[^"\\]*|\\["\\bfnrt\/]|\\u[0-9A-Fa-f]{4})*" | -? (?= [1-9]|0(?!\d) ) \d+ (?:\.\d+)? (?:[eE] [+-]? \d+)? | true | false | null | \[ (?: (?1) (?: , (?1) )* )? \s* \] | \{ (?: \s*"(?:[^"\\]*|\\["\\bfnrt\/]|\\u[0-9A-Fa-f]{4})*"\s*:(?1) (?:,\s*"(?:[^"\\]*|\\["\\bfnrt\/]|\\u[0-9A-Fa-f]{4})*"\s*:(?1)

)*)? \s* \} ) \s*)\Z/sx;

Page 5: 再帰的 正規表現JSON Validator

JSON とは

Page 6: 再帰的 正規表現JSON Validator

JSON とはJSON とは

JavaScript Object NotationJavaScript の記法を元にしたデータ記述用言語

元々は JavaScript のサブセットとして考案var obj = eval( "(" + json_text + ")" );

JSON 文字列を eval すると JavaScript object になる

[ { "id" : 1001 , "name" : "foo" }, { "id" : 1002 , "name" : "bar" }]

Page 7: 再帰的 正規表現JSON Validator

JavaScript で受け取った JSON を eval すると… JavaScript で受け取った JSON を eval すると…

そのまま eval するのは大変危険「山田太郎(正常系)」

{ "name" : " 山田太郎 => (正常系 " }「山田 ” }),alert(24)//XSS 」

{ "name" : " 山田 "}),alert(24)// 太郎 " }

var json_text = ( { "name" : " 山田 "}, alert(24);//XSS " });var obj = eval("(" + json_text + ")");

Page 8: 再帰的 正規表現JSON Validator

CVE-2007-3227 : JSON における XSS 脆弱性CVE-2007-3227 : JSON における XSS 脆弱性

#to_json の HTML エスケープ漏れで XSSが発生

http://dev.rubyonrails.org/ticket/8371

Page 9: 再帰的 正規表現JSON Validator

JSON の規格(データ交換フォーマット)JSON の規格(データ交換フォーマット)

RFC4627 による定義The application/json Media Type for

JavaScript Object Notation (JSON)ECMA-262 による定義

ECMA-262 ECMAScript 言語仕様 5th edition15.12 The JSON object [PDF]

ISO/IEC 16262:2011他のプログラミング言語の JSON parser

PHP, Python, Java, Perl, C/C++...http://json.org/

Page 10: 再帰的 正規表現JSON Validator

JSON の構成要素JSON の構成要素

JSON stringJSON numberJSON arrayJSON objectJSON value特別な値3つ

truefalsenull

Page 11: 再帰的 正規表現JSON Validator

JSON string の定義JSON string の定義

例: "abc", "\t\n", " あ ", "\u3042"A string is a collection of zero or more

Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string.

Page 12: 再帰的 正規表現JSON Validator

JSON number の定義JSON number の定義

例: 0, 1, -2, 3.14, 9e3, 9000A number is very much like a C or Java

number, except that the octal and hexadecimal formats are not used.

Page 13: 再帰的 正規表現JSON Validator

JSON array の定義JSON array の定義

例: ["a", "b", "c"]An array is an ordered collection of values.

An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

Page 14: 再帰的 正規表現JSON Validator

JSON object の定義JSON object の定義

例: {"string": value, "key": value}An object is an unordered set of name/value

pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

Page 15: 再帰的 正規表現JSON Validator

JSON value の定義JSON value の定義

例: "abc", 123, {}, [], true, false, nullA value can be a string in double quotes, or

a number, or true or false or null, or an object or an array. These structures can be nested.[ [], [1, 2], ["a", "b"], {}, {"x": {"y": "z"}} ]

Page 16: 再帰的 正規表現JSON Validator

演習問題

Page 17: 再帰的 正規表現JSON Validator

Q. 以下の JSON は正しいフォーマットか?Q. 以下の JSON は正しいフォーマットか?

(1) JSON object のキーは "string"

{ apple: 1, beer: 2 }

{ "apple": 1, "beer": 2 }

Page 18: 再帰的 正規表現JSON Validator

Q. 以下の JSON は正しいフォーマットか?Q. 以下の JSON は正しいフォーマットか?

(2) 複数 value のカンマ区切り(最後){ "name" : "TAKESAKO, Yoshinori", "E-mail" : "[email protected]",}

{ "name" : "TAKESAKO, Yoshinori", "E-mail" : "[email protected]"}

Page 19: 再帰的 正規表現JSON Validator

Q. 以下の JSON は正しいフォーマットか?Q. 以下の JSON は正しいフォーマットか?

(3) JSON string の引用符は "" のみ

[ 0, 1, 2, 'abc', 'string' ]

[ 0, 1, 2, "abc", "string" ]

Page 20: 再帰的 正規表現JSON Validator

Q. 以下の JSON は正しいフォーマットか?Q. 以下の JSON は正しいフォーマットか?

(4) JSON number の符号に + はない

[ -3, 3.14, 1.23e2, +123.456 ]

[ -3, 3.14, 1.23e2, 123.456 ]

Page 21: 再帰的 正規表現JSON Validator

Q. 以下の JSON は正しいフォーマットか?Q. 以下の JSON は正しいフォーマットか?

(5) JavaScript comment は使用できない

[{ /* Bookmark */ "url": "http://cybozu.co.jp/", "memo": "Cybozu HP" // title}]

[{ "url": "http://cybozu.co.jp/", "memo": "Cybozu HP"}]

Page 22: 再帰的 正規表現JSON Validator

Q. 以下の JSON は正しいフォーマットか?Q. 以下の JSON は正しいフォーマットか?

(6) JSON number は 10 進数のみ

[ { "file": "a.out", "chmod": 0775 }, { "file": "a.cpp", "chmod": 0644 }]

[ { "file": "a.out", "chmod": 509 }, { "file": "a.cpp", "chmod": 420 }]

Page 23: 再帰的 正規表現JSON Validator

Q. 以下の JSON は正しいフォーマットか?Q. 以下の JSON は正しいフォーマットか?

(7) string number 以外の JSON value

[ "Boolean", True, False, Null ]

[ "Boolean", true, false, null ]

Page 24: 再帰的 正規表現JSON Validator

Q. 以下の JSON は正しいフォーマットか?Q. 以下の JSON は正しいフォーマットか?

(8) Unicode 文字の扱い

{ "a": "a あ A", "i": "i\u3044I" }

{ "a":"a\u3042A", "i":"i\u3044I" }

Page 25: 再帰的 正規表現JSON Validator

Q. 以下の JSON は正しいフォーマットか?Q. 以下の JSON は正しいフォーマットか?

(9) / のエスケープ

"<script src='/jquery.js'></script>"

"<script src='/jquery.js'><\/script>"

Page 26: 再帰的 正規表現JSON Validator
Page 27: 再帰的 正規表現JSON Validator

正規表現でチェックできる?

Page 28: 再帰的 正規表現JSON Validator

Perl で PCRE 拡張の記法を使うPerl で PCRE 拡張の記法を使う

(?(DEFINE) (?<foo> regexp1)(?<bar> regexp2) … )

(?&foo) (?&bar)$json =~ / (?(DEFINE) (?<string> (?:[^"\\]* | \\ ["\\bfnrt\/] | \\u[0-9A-Fa-f]{4} )* " ) (?<number> -? (?=[1-9]|0(?!\d))\d+(?:\.\d+)? (?:[eE] [+-]? \d+)? ) (?<boolean> true | false | null ) (?<array> \[ (?: (?&json) (?: , (?&json) )* )? \s* \] ) (?<pair> \s* (?&string) \s* : (?&json) ) (?<object> \{ (?: (?&pair) (?: , (?&pair) )* )? \s* \} ) (?<json> \s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) \s* ) ) \A (?&json) \Z/sx;

Page 29: 再帰的 正規表現JSON Validator

これはわかりやすい

Page 30: 再帰的 正規表現JSON Validator

自分自身の正規表現にマッチ (?R)自分自身の正規表現にマッチ (?R)

PCRE の記法 (?R) が Perl でも使える!

“{{{}}}” にマッチ“xxxx{{{}}}}}}}zzzzzz” にもマッチ

以下の正規表現だとネストしてくれない…

/\{(?R)*\}/

/^ \{(?R)*\} $/

Page 31: 再帰的 正規表現JSON Validator

(?R)(?0)(?1)(?2) ・・・が使える!(?R)(?0)(?1)(?2) ・・・が使える!

任意のキャプチャ部分の再帰ができる

/\{(?R)*\}/

/^(\{(?1)*\})$/

/\{(?0)*\}/

/(\{(?1)*\})/

Page 32: 再帰的 正規表現JSON Validator

JSON Validator を作ってみるJSON Validator を作ってみる

PCRE の記法 (?1) を使うテクニック$json =~ /\A ( \s* (?: "(?:[^"\\]*|\\["\\bfnrt\/]|\\u[0-9A-Fa-f]{4})*" | -? (?= [1-9]|0(?!\d) ) \d+ (?:\.\d+)? (?:[eE] [+-]? \d+)? | true | false | null | \[ (?: (?1) (?: , (?1) )* )? \s* \] | \{(?: \s*"(?:[^"\\]*|\\["\\bfnrt\/]|\\u[0-9A-Fa-f]{4})*"\s*:(?1) (?:,\s*"(?:[^"\\]*|\\["\\bfnrt\/]|\\u[0-9A-Fa-f]{4})*"\s*:(?1)

)* )? \s* \} ) \s*)\Z/sx;

Page 33: 再帰的 正規表現JSON Validator

再帰的正規表現便利也

Page 34: 再帰的 正規表現JSON Validator