@@ -8,45 +8,77 @@ module Unisec
88 module CLI
99 module Commands
1010 # CLI sub-commands `unisec normalize xxx` for the class {Unisec::Normalization} from the lib.
11- #
12- # Command `unisec normalize "example"`
13- #
14- # Example:
15- #
16- # ```plaintext
17- # ➜ unisec normalize ẛ̣
18- # Original: ẛ̣
19- # U+1E9B U+0323
20- # NFC: ẛ̣
21- # U+1E9B U+0323
22- # NFKC: ṩ
23- # U+1E69
24- # NFD: ẛ̣
25- # U+017F U+0323 U+0307
26- # NFKD: ṩ
27- # U+0073 U+0323 U+0307
28- #
29- # ➜ unisec normalize ẛ̣ --form nfkd
30- # ṩ
31- # ```
32- class Normalize < Dry ::CLI ::Command
33- desc 'Normalize in all forms'
34-
35- argument :input , required : true ,
36- desc : 'String input. Read from STDIN if equal to -.'
37-
38- option :form , default : nil , values : %w[ nfc nfkc nfd nfkd ] ,
39- desc : 'Output only in the specified normalization form.'
40-
41- # Normalize in all forms
42- # @param input [String] Input string to normalize
43- def call ( input : nil , **options )
44- input = $stdin. read . chomp if input == '-'
45- if options [ :form ] . nil?
46- puts Unisec ::Normalization . new ( input ) . display
47- else
48- # using send() is safe here thanks to the value whitelist
49- puts Unisec ::Normalization . send ( options [ :form ] , input )
11+ module Normalize
12+ # Command `unisec normalize all "example"`
13+ #
14+ # Example:
15+ #
16+ # ```plaintext
17+ # ➜ unisec normalize all ẛ̣
18+ # Original: ẛ̣
19+ # U+1E9B U+0323
20+ # NFC: ẛ̣
21+ # U+1E9B U+0323
22+ # NFKC: ṩ
23+ # U+1E69
24+ # NFD: ẛ̣
25+ # U+017F U+0323 U+0307
26+ # NFKD: ṩ
27+ # U+0073 U+0323 U+0307
28+ #
29+ # ➜ unisec normalize all ẛ̣ --form nfkd
30+ # ṩ
31+ # ```
32+ class All < Dry ::CLI ::Command
33+ desc 'Normalize in all forms'
34+
35+ argument :input , required : true ,
36+ desc : 'String input. Read from STDIN if equal to -.'
37+
38+ option :form , default : nil , values : %w[ nfc nfkc nfd nfkd ] ,
39+ desc : 'Output only in the specified normalization form.'
40+
41+ # Normalize in all forms
42+ # @param input [String] Input string to normalize
43+ def call ( input : nil , **options )
44+ input = $stdin. read . chomp if input == '-'
45+ if options [ :form ] . nil?
46+ puts Unisec ::Normalization . new ( input ) . display
47+ else
48+ # using send() is safe here thanks to the value whitelist
49+ puts Unisec ::Normalization . send ( options [ :form ] , input )
50+ end
51+ end
52+ end
53+
54+ # Command `unisec normalize replace "example"`
55+ #
56+ # Example:
57+ #
58+ # ```plaintext
59+ # ➜ unisec normalize replace "<svg onload=\"alert('XSS')\">"
60+ # Original: <svg onload="alert('XSS')">
61+ # U+003C U+0073 U+0076 U+0067 U+0020 U+006F U+006E U+006C U+006F U+0061 U+0064 U+003D U+0022 U+0061 U+006C U+0065 U+0072 U+0074 U+0028 U+0027 U+0058 U+0053 U+0053 U+0027 U+0029 U+0022 U+003E
62+ # Bypass payload: ﹤svg onload="alert('XSS')"﹥
63+ # U+FE64 U+0073 U+0076 U+0067 U+0020 U+006F U+006E U+006C U+006F U+0061 U+0064 U+003D U+FF02 U+0061 U+006C U+0065 U+0072 U+0074 U+0028 U+FF07 U+0058 U+0053 U+0053 U+FF07 U+0029 U+FF02 U+FE65
64+ # NFKC: <svg onload="alert('XSS')">
65+ # U+003C U+0073 U+0076 U+0067 U+0020 U+006F U+006E U+006C U+006F U+0061 U+0064 U+003D U+0022 U+0061 U+006C U+0065 U+0072 U+0074 U+0028 U+0027 U+0058 U+0053 U+0053 U+0027 U+0029 U+0022 U+003E
66+ # NFKD: <svg onload="alert('XSS')">
67+ # U+003C U+0073 U+0076 U+0067 U+0020 U+006F U+006E U+006C U+006F U+0061 U+0064 U+003D U+0022 U+0061 U+006C U+0065 U+0072 U+0074 U+0028 U+0027 U+0058 U+0053 U+0053 U+0027 U+0029 U+0022 U+003E
68+ #
69+ # ➜ echo -n "<svg onload=\"alert('XSS')\">" | unisec normalize replace -
70+ # ```
71+ class Replace < Dry ::CLI ::Command
72+ desc 'Prepare a XSS payload for HTML escape bypass (HTML escape followed by NFKC / NFKD normalization)'
73+
74+ argument :input , required : true ,
75+ desc : 'String input. Read from STDIN if equal to -.'
76+
77+ # Prepare a XSS payload for HTML escape bypass (HTML escape followed by NFKC / NFKD normalization)
78+ # @param input [String] Input string to normalize
79+ def call ( input : nil , **_options )
80+ input = $stdin. read . chomp if input == '-'
81+ puts Unisec ::Normalization . new ( input ) . display_replace
5082 end
5183 end
5284 end
0 commit comments