Skip to content

Commit e65b0fc

Browse files
authored
Merge pull request #400 from owasp-noir/add-set-pvalue-x
Add set-value-*
2 parents 57c3dd0 + 3d8a18b commit e65b0fc

File tree

14 files changed

+228
-75
lines changed

14 files changed

+228
-75
lines changed

docs/_advanced/configuration.md

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ layout: page
2222

2323
```yaml
2424
---
25+
---
2526
# Noir configuration file
2627
# This file is used to store the configuration options for Noir.
2728
# You can edit this file to change the configuration options.
29+
30+
# Config values are defaults; CLI options take precedence.
2831
# **************************************************************
2932

3033
# Base directory for the application
3134
base: ""
3235

3336
# Whether to use color in the output
34-
color: true
37+
color: "true"
3538

3639
# The configuration file to use
3740
config_file: ""
@@ -40,7 +43,7 @@ config_file: ""
4043
concurrency: "100"
4144

4245
# Whether to enable debug mode
43-
debug: false
46+
debug: "false"
4447

4548
# Technologies to exclude
4649
exclude_techs: ""
@@ -49,49 +52,56 @@ exclude_techs: ""
4952
format: "plain"
5053

5154
# Whether to include the path in the output
52-
include_path: false
55+
include_path: "false"
5356

5457
# Whether to disable logging
55-
nolog: false
58+
nolog: "false"
5659

5760
# The output file to write to
5861
output: ""
5962

6063
# The Elasticsearch server to send data to
64+
# e.g http://localhost:9200
6165
send_es: ""
6266

6367
# The proxy server to use
68+
# e.g http://localhost:8080
6469
send_proxy: ""
6570

6671
# Whether to send a request
67-
send_req: false
72+
send_req: "false"
6873

69-
# Whether to send headers with the request
70-
send_with_headers:
71-
- "Authorization: ABCD1234"
72-
- "X-API-Key: ABCD1234"
74+
# Whether to send headers with the request (Array of strings)
75+
# e.g "Authorization: Bearer token"
76+
send_with_headers:
7377

74-
# The value to set for pvalue
75-
set_pvalue: ""
78+
# The value to set for pvalue (Array of strings)
79+
set_pvalue:
80+
set_pvalue_header:
81+
set_pvalue_cookie:
82+
set_pvalue_query:
83+
set_pvalue_form:
84+
set_pvalue_json:
85+
set_pvalue_path:
7686

7787
# The technologies to use
7888
techs: ""
7989

8090
# The URL to use
8191
url: ""
8292

83-
# Whether to use filters
84-
use_filters:
85-
- "/admin"
93+
# Whether to use filters (Array of strings)
94+
use_filters:
8695

87-
# Whether to use matchers
88-
use_matchers:
89-
- "/user"
96+
# Whether to use matchers (Array of strings)
97+
use_matchers:
9098

9199
# Whether to use all taggers
92-
all_taggers: false
100+
all_taggers: "false"
93101

94102
# The taggers to use
103+
# e.g "tagger1,tagger2"
104+
# To see the list of all taggers, please use the noir command with --list-taggers
95105
use_taggers: ""
96106

97107
# The diff file to use

spec/unit_test/models/noir_spec.cr

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,38 @@ describe "Methods" do
3131
runner.endpoints[1].url.should eq("https://www.hahwul.com/abcd")
3232
end
3333
end
34+
35+
describe "set-pvalue" do
36+
config_init = ConfigInitializer.new
37+
options = config_init.default_options
38+
options["base"] = YAML::Any.new("noir")
39+
options["set_pvalue_query"] = YAML::Any.new([YAML::Any.new("FUZZ")])
40+
options["set_pvalue_header"] = YAML::Any.new([YAML::Any.new("name=FUZZ")])
41+
options["set_pvalue_cookie"] = YAML::Any.new([YAML::Any.new("name:FUZZ")])
42+
options["set_pvalue_json"] = YAML::Any.new([YAML::Any.new("name:FUZZ=FUZZ")])
43+
runner = NoirRunner.new(options)
44+
45+
it "applies pvalue to query parameter" do
46+
runner.apply_pvalue("query", "name", "value").should eq("FUZZ")
47+
end
48+
49+
it "applies pvalue to header parameter with '=' delimiter" do
50+
runner.apply_pvalue("header", "name", "value").should eq("FUZZ")
51+
end
52+
53+
it "does not apply pvalue to header parameter when name does not match" do
54+
runner.apply_pvalue("header", "name2", "value").should eq("value")
55+
end
56+
57+
it "applies pvalue to cookie parameter with ':' delimiter" do
58+
runner.apply_pvalue("cookie", "name", "value").should eq("FUZZ")
59+
end
60+
61+
it "does not apply pvalue to cookie parameter when name does not match" do
62+
runner.apply_pvalue("cookie", "name2", "value").should eq("value")
63+
end
64+
65+
it "includes '=' in the pvalue for JSON parameter" do
66+
runner.apply_pvalue("json", "name", "value").should eq("FUZZ=FUZZ")
67+
end
68+
end

spec/unit_test/utils/utils_spec.cr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ describe "get_symbol" do
5353
end
5454
end
5555

56-
describe "str_to_bool" do
56+
describe "any_to_bool" do
5757
it true do
58-
str_to_bool(true).should eq(true)
58+
any_to_bool(true).should eq(true)
5959
end
6060
it false do
61-
str_to_bool(false).should eq(false)
61+
any_to_bool(false).should eq(false)
6262
end
6363
it "any string" do
64-
str_to_bool("hahwul").should eq(false)
64+
any_to_bool("hahwul").should eq(false)
6565
end
6666
end
6767

src/config_initializer.cr

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class ConfigInitializer
4545
begin
4646
parsed_yaml = YAML.parse(File.read(@config_file)).as_h
4747
symbolized_hash = parsed_yaml.transform_keys(&.to_s)
48-
# stringlized_hash = symbolized_hash.transform_values(&.to_s)
4948

5049
# Transform specific keys from "yes"/"no" to true/false for old version noir config
5150
["color", "debug", "include_path", "nolog", "send_req", "all_taggers"].each do |key|
@@ -56,16 +55,28 @@ class ConfigInitializer
5655
end
5756
end
5857

59-
# Transform specific keys from "" to [""] or ["value"] for old version noir config
60-
["send_with_headers", "use_filters", "use_matchers"].each do |key|
61-
if symbolized_hash[key] == ""
58+
# Transform specific keys for array and string config values
59+
[
60+
"send_with_headers", "use_filters", "use_matchers",
61+
"set_pvalue", "set_pvalue_header", "set_pvalue_cookie",
62+
"set_pvalue_query", "set_pvalue_form", "set_pvalue_json", "set_pvalue_path",
63+
].each do |key|
64+
if symbolized_hash[key].to_s == ""
65+
# If the value is an empty string, initialize it as an empty array of YAML::Any
6266
symbolized_hash[key] = YAML::Any.new([] of YAML::Any)
63-
elsif symbolized_hash[key].is_a?(String)
64-
symbolized_hash[key] = YAML::Any.new([YAML::Any.new(symbolized_hash[key].to_s)])
67+
else
68+
begin
69+
# If the value is already an array, ensure it is treated as an array of YAML::Any
70+
symbolized_hash[key].as_a
71+
rescue
72+
# If the value is a string, wrap it in an array of YAML::Any
73+
symbolized_hash[key] = YAML::Any.new([YAML::Any.new(symbolized_hash[key].to_s)])
74+
end
6575
end
6676
end
6777

68-
symbolized_hash
78+
final_options = default_options.merge(symbolized_hash) { |_, _, new_val| new_val }
79+
final_options
6980
rescue e : Exception
7081
puts "Failed to read config file: #{e.message}"
7182
puts "Using default config."
@@ -90,7 +101,13 @@ class ConfigInitializer
90101
"send_proxy" => YAML::Any.new(""),
91102
"send_req" => YAML::Any.new(false),
92103
"send_with_headers" => YAML::Any.new([] of YAML::Any),
93-
"set_pvalue" => YAML::Any.new(""),
104+
"set_pvalue" => YAML::Any.new([] of YAML::Any),
105+
"set_pvalue_header" => YAML::Any.new([] of YAML::Any),
106+
"set_pvalue_cookie" => YAML::Any.new([] of YAML::Any),
107+
"set_pvalue_query" => YAML::Any.new([] of YAML::Any),
108+
"set_pvalue_form" => YAML::Any.new([] of YAML::Any),
109+
"set_pvalue_json" => YAML::Any.new([] of YAML::Any),
110+
"set_pvalue_path" => YAML::Any.new([] of YAML::Any),
94111
"techs" => YAML::Any.new(""),
95112
"url" => YAML::Any.new(""),
96113
"use_filters" => YAML::Any.new([] of YAML::Any),
@@ -118,7 +135,7 @@ class ConfigInitializer
118135
base: "#{options["base"]}"
119136
120137
# Whether to use color in the output
121-
color: "#{options["color"]}"
138+
color: #{options["color"]}
122139
123140
# The configuration file to use
124141
config_file: "#{options["config_file"]}"
@@ -127,7 +144,7 @@ class ConfigInitializer
127144
concurrency: "#{options["concurrency"]}"
128145
129146
# Whether to enable debug mode
130-
debug: "#{options["debug"]}"
147+
debug: #{options["debug"]}
131148
132149
# Technologies to exclude
133150
exclude_techs: "#{options["exclude_techs"]}"
@@ -136,10 +153,10 @@ class ConfigInitializer
136153
format: "#{options["format"]}"
137154
138155
# Whether to include the path in the output
139-
include_path: "#{options["include_path"]}"
156+
include_path: #{options["include_path"]}
140157
141158
# Whether to disable logging
142-
nolog: "#{options["nolog"]}"
159+
nolog: #{options["nolog"]}
143160
144161
# The output file to write to
145162
output: "#{options["output"]}"
@@ -153,14 +170,20 @@ class ConfigInitializer
153170
send_proxy: "#{options["send_proxy"]}"
154171
155172
# Whether to send a request
156-
send_req: "#{options["send_req"]}"
173+
send_req: #{options["send_req"]}
157174
158175
# Whether to send headers with the request (Array of strings)
159176
# e.g "Authorization: Bearer token"
160177
send_with_headers:
161178
162-
# The value to set for pvalue
163-
set_pvalue: "#{options["set_pvalue"]}"
179+
# The value to set for pvalue (Array of strings)
180+
set_pvalue:
181+
set_pvalue_header:
182+
set_pvalue_cookie:
183+
set_pvalue_query:
184+
set_pvalue_form:
185+
set_pvalue_json:
186+
set_pvalue_path:
164187
165188
# The technologies to use
166189
techs: "#{options["techs"]}"
@@ -175,7 +198,7 @@ class ConfigInitializer
175198
use_matchers:
176199
177200
# Whether to use all taggers
178-
all_taggers: "#{options["all_taggers"]}"
201+
all_taggers: #{options["all_taggers"]}
179202
180203
# The taggers to use
181204
# e.g "tagger1,tagger2"

src/models/analyzer.cr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ class Analyzer
1717
@url = options["url"].to_s
1818
@result = [] of Endpoint
1919
@endpoint_references = [] of EndpointReference
20-
@is_debug = str_to_bool(options["debug"])
21-
@is_color = str_to_bool(options["color"])
22-
@is_log = str_to_bool(options["nolog"])
20+
@is_debug = any_to_bool(options["debug"])
21+
@is_color = any_to_bool(options["color"])
22+
@is_log = any_to_bool(options["nolog"])
2323
@options = options
2424

2525
@logger = NoirLogger.new @is_debug, @is_color, @is_log

src/models/code_locator.cr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ class CodeLocator
1010

1111
def initialize
1212
options = {"debug" => "true", "color" => "true", "nolog" => "false"}
13-
@is_debug = str_to_bool(options["debug"])
14-
@is_color = str_to_bool(options["color"])
15-
@is_log = str_to_bool(options["nolog"])
13+
@is_debug = any_to_bool(options["debug"])
14+
@is_color = any_to_bool(options["color"])
15+
@is_log = any_to_bool(options["nolog"])
1616
@logger = NoirLogger.new(@is_debug, @is_color, @is_log)
1717

1818
@s_map = Hash(String, String).new

src/models/deliver.cr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ class Deliver
1313

1414
def initialize(options : Hash(String, YAML::Any))
1515
@options = options
16-
@is_debug = str_to_bool(options["debug"])
17-
@is_color = str_to_bool(options["color"])
18-
@is_log = str_to_bool(options["nolog"])
16+
@is_debug = any_to_bool(options["debug"])
17+
@is_color = any_to_bool(options["color"])
18+
@is_log = any_to_bool(options["nolog"])
1919
@proxy = options["send_proxy"].to_s
2020
@logger = NoirLogger.new @is_debug, @is_color, @is_log
2121

src/models/detector.cr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ class Detector
1010
@base_path : String
1111

1212
def initialize(options : Hash(String, YAML::Any))
13-
@is_debug = str_to_bool(options["debug"])
14-
@is_color = str_to_bool(options["color"])
15-
@is_log = str_to_bool(options["nolog"])
13+
@is_debug = any_to_bool(options["debug"])
14+
@is_color = any_to_bool(options["color"])
15+
@is_log = any_to_bool(options["nolog"])
1616
@name = ""
1717
@base_path = options["base"].to_s
1818

0 commit comments

Comments
 (0)