Skip to content

Commit

Permalink
Merge pull request #170 from noir-cr/hahwul-dev
Browse files Browse the repository at this point in the history
Add cookie type of param, Improve logger and baker
  • Loading branch information
ksg97031 authored Nov 20, 2023
2 parents ef3b921 + 15dfb97 commit 1323a9c
Show file tree
Hide file tree
Showing 16 changed files with 64 additions and 47 deletions.
2 changes: 2 additions & 0 deletions spec/functional_test/fixtures/crystal_kemal/src/testapp.cr
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
require "kemal"

get "/" do
env.request.headers["x-api-key"].as(String)
"Hello World!"
end

post "/query" do
env.request.cookies["my_auth"].as(String)
env.params.body["query"].as(String)
end

Expand Down
11 changes: 9 additions & 2 deletions spec/functional_test/fixtures/python_flask/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

@app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
db_session.remove()

@app.route('/sign', methods=['GET', 'POST'])
def sign_sample():
Expand All @@ -28,6 +28,13 @@ def sign_sample():

return render_template('sign.html')

@app.route('/cookie', methods=['GET'])
def cookie_test():
if request.cookies.get('test') == "y":
return "exist cookie"

return "no cookie"

@app.route('/login', methods=['POST'])
def login_sample():
if request.method == 'POST':
Expand All @@ -40,7 +47,7 @@ def login_sample():
else:
return "Fail"

return render_template('login.html')
return render_template('login.html')

@app.route('/create_record', methods=['PUT'])
def create_record():
Expand Down
7 changes: 5 additions & 2 deletions spec/functional_test/testers/crystal_kemal_spec.cr
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
require "../func_spec.cr"

extected_endpoints = [
Endpoint.new("/", "GET"),
Endpoint.new("/", "GET", [Param.new("x-api-key", "", "header")]),
Endpoint.new("/socket", "GET"),
Endpoint.new("/query", "POST", [Param.new("query", "", "form")]),
Endpoint.new("/query", "POST", [
Param.new("query", "", "form"),
Param.new("my_auth", "", "cookie"),
]),
]

FunctionalTester.new("fixtures/crystal_kemal/", {
Expand Down
2 changes: 1 addition & 1 deletion spec/functional_test/testers/python_django_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extected_endpoints = [
Endpoint.new("/links.html", "GET"),
Endpoint.new("/upload", "GET", [Param.new("sign", "", "query"), Param.new("sign", "", "query"), Param.new("X_FORWARDED_FOR", "", "header"), Param.new("X_REAL_IP", "", "header")]),
Endpoint.new("/upload", "POST", [Param.new("sign", "", "query"), Param.new("X_FORWARDED_FOR", "", "header"), Param.new("X_REAL_IP", "", "header")]),
Endpoint.new("/not_found", "GET", [Param.new("Cookie['app_type']", "", "header")]),
Endpoint.new("/not_found", "GET", [Param.new("app_type", "", "cookie")]),
Endpoint.new("/test", "GET", [Param.new("test_param", "", "form")]),
Endpoint.new("/test", "POST", [Param.new("test_param", "", "form")]),
Endpoint.new("/test", "PUT", [Param.new("test_param", "", "form")]),
Expand Down
2 changes: 1 addition & 1 deletion spec/functional_test/testers/python_fastapi_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ extected_endpoints = [
Endpoint.new("/query/param-required/int", "GET", [Param.new("query", "", "query")]),
Endpoint.new("/items/{item_id}", "PUT", [Param.new("name", "", "form"), Param.new("size", "", "form")]),
Endpoint.new("/hidden_header", "GET", [Param.new("hidden_header", "", "header")]),
Endpoint.new("/cookie_examples/", "GET", [Param.new("Cookie['data']", "", "header")]),
Endpoint.new("/cookie_examples/", "GET", [Param.new("data", "", "cookie")]),
Endpoint.new("/dummypath", "POST", [Param.new("dummy", "", "json")]),
Endpoint.new("/main", "GET"),
]
Expand Down
3 changes: 2 additions & 1 deletion spec/functional_test/testers/python_flask_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ require "../func_spec.cr"
extected_endpoints = [
Endpoint.new("/sign", "GET"),
Endpoint.new("/sign", "POST", [Param.new("username", "", "form"), Param.new("password", "", "form")]),
Endpoint.new("/cookie", "GET", [Param.new("test", "", "cookie")]),
Endpoint.new("/login", "POST", [Param.new("username", "", "form"), Param.new("password", "", "form")]),
Endpoint.new("/create_record", "PUT"),
Endpoint.new("/delete_record", "DELETE", [Param.new("name", "", "json")]),
Expand All @@ -12,5 +13,5 @@ extected_endpoints = [

FunctionalTester.new("fixtures/python_flask/", {
:techs => 1,
:endpoints => 7,
:endpoints => 8,
}, extected_endpoints).test_all
2 changes: 1 addition & 1 deletion spec/unit_test/analyzer/analyzer_kemal_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe "mapping_to_path" do
end

it "line_to_param - env.response.headers[]" do
line = "env.response.headers[\"x-token\"]"
line = "env.request.headers[\"x-token\"]"
instance.line_to_param(line).name.should eq("x-token")
end
end
9 changes: 7 additions & 2 deletions src/analyzer/analyzers/analyzer_crystal_kemal.cr
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,16 @@ class AnalyzerCrystalKemal < Analyzer
return Param.new(param, "", "form")
end

if content.includes? "env.response.headers["
param = content.split("env.response.headers[")[1].split("]")[0].gsub("\"", "").gsub("'", "")
if content.includes? "env.request.headers["
param = content.split("env.request.headers[")[1].split("]")[0].gsub("\"", "").gsub("'", "")
return Param.new(param, "", "header")
end

if content.includes? "env.request.cookies["
param = content.split("env.request.cookies[")[1].split("]")[0].gsub("\"", "").gsub("'", "")
return Param.new(param, "", "cookie")
end

Param.new("", "", "")
end

Expand Down
6 changes: 1 addition & 5 deletions src/analyzer/analyzers/analyzer_django.cr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class AnalyzerDjango < AnalyzerPython
REQUEST_PARAM_FIELD_MAP = {
"GET" => {["GET"], "query"},
"POST" => {["POST"], "form"},
"COOKIES" => {nil, "header"},
"COOKIES" => {nil, "cookie"},
"META" => {nil, "header"},
"data" => {["POST", "PUT", "PATCH"], "form"},
}
Expand Down Expand Up @@ -293,10 +293,6 @@ class AnalyzerDjango < AnalyzerPython
if param_name.starts_with? "HTTP_"
param_name = param_name[5..]
end
elsif noir_param_type == "header"
if field_name == "COOKIES"
param_name = "Cookie['#{param_name}']"
end
end

# If it receives a specific parameter, it is considered to allow the method.
Expand Down
4 changes: 0 additions & 4 deletions src/analyzer/analyzers/analyzer_fastapi.cr
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,6 @@ class AnalyzerFastAPI < AnalyzerPython
# Get param type by default value first
if param.default.size != 0
param_type = infer_parameter_type(param.default)
if param_type == "cookie"
param_type = "header"
param.name = "Cookie['#{param.name}']"
end
end

# Get param type by type if not found
Expand Down
7 changes: 1 addition & 6 deletions src/analyzer/analyzers/analyzer_flask.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class AnalyzerFlask < AnalyzerPython
"files" => {["POST", "PUT", "PATCH", "DELETE"], "form"},
"values" => {["GET", "POST", "PUT", "PATCH", "DELETE"], "query"},
"json" => {["POST", "PUT", "PATCH", "DELETE"], "json"},
"cookie" => {nil, "header"},
"cookie" => {nil, "cookie"},
"headers" => {nil, "header"},
}

Expand Down Expand Up @@ -200,11 +200,6 @@ class AnalyzerFlask < AnalyzerPython
matches.each do |parameter_match|
next if parameter_match.size != 2
param_name = parameter_match[1]
if noir_param_type == "header"
if field_name == "cookie"
param_name = "Cookie['#{param_name}']"
end
end

suspicious_params << Param.new(param_name, "", noir_param_type)
end
Expand Down
19 changes: 3 additions & 16 deletions src/models/endpoint.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,14 @@ require "yaml"
struct Endpoint
include JSON::Serializable
include YAML::Serializable
property url, method, params, headers, protocol
property url, method, params, protocol

def initialize(@url : String, @method : String)
@params = [] of Param
@headers = [] of Header
@protocol = "http"
end

def initialize(@url : String, @method : String, @params : Array(Param))
@headers = [] of Header
@protocol = "http"
end

def initialize(@url : String, @method : String, @params : Array(Param), @headers : Array(Header))
@protocol = "http"
end

Expand Down Expand Up @@ -48,16 +42,9 @@ struct Param
include YAML::Serializable
property name, value, param_type

def initialize(@name : String, @value : String, @param_type : String)
end
end

struct Header
include JSON::Serializable
include YAML::Serializable
property name, value
# param_type can be "query", "json", "form", "header", "cookie"

def initialize(@name : String, @value : String)
def initialize(@name : String, @value : String, @param_type : String)
end
end

Expand Down
6 changes: 6 additions & 0 deletions src/models/output_builder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class OutputBuilder
final_url = url
final_body = ""
final_headers = [] of String
final_cookies = [] of String
is_json = false
first_query = true
first_form = true
Expand Down Expand Up @@ -69,6 +70,10 @@ class OutputBuilder
final_headers << "#{param.name}: #{param.value}"
end

if param.param_type == "cookie"
final_cookies << "#{param.name}=#{param.value}"
end

if param.param_type == "json"
is_json = true
end
Expand All @@ -95,6 +100,7 @@ class OutputBuilder
url: final_url,
body: final_body,
header: final_headers,
cookie: final_cookies,
body_type: is_json ? "json" : "form",
}
end
Expand Down
21 changes: 16 additions & 5 deletions src/output_builder/common.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,29 @@ class OutputBuilderCommon < OutputBuilder
r_method = endpoint.method.colorize(:light_blue).toggle(@is_color)
r_url = baked[:url].colorize(:light_yellow).toggle(@is_color)
r_headers = baked[:header].join(" ").colorize(:light_green).toggle(@is_color)

r_cookies = baked[:cookie].join(";").colorize(:light_green).toggle(@is_color)
r_ws = ""
r_buffer = "#{r_method} #{r_url}"

if endpoint.protocol == "ws"
r_ws = "[WEBSOCKET]".colorize(:light_red).toggle(@is_color)
r_ws = "[websocket]".colorize(:light_red).toggle(@is_color)
r_buffer += " #{r_ws}"
end

if baked[:header].size > 0
r_buffer += "\n ○ headers: #{r_headers}"
end

if baked[:cookie].size > 0
r_buffer += "\n ○ cookies: #{r_cookies}"
end

if baked[:body] != ""
r_body = baked[:body].colorize(:cyan).toggle(@is_color)
ob_puts "#{r_method} #{r_url} #{r_body} #{r_headers} #{r_ws}"
else
ob_puts "#{r_method} #{r_url} #{r_headers} #{r_ws}"
r_buffer += "\n ○ body: #{r_body}"
end

ob_puts r_buffer
end
end
end
4 changes: 4 additions & 0 deletions src/output_builder/curl.cr
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class OutputBuilderCurl < OutputBuilder
baked[:header].each do |header|
cmd += " -H \"#{header}\""
end

baked[:cookie].each do |cookie|
cmd += " --cookie \"#{cookie}\""
end
end

ob_puts cmd
Expand Down
6 changes: 5 additions & 1 deletion src/output_builder/httpie.cr.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ class OutputBuilderHttpie < OutputBuilder

cmd = "http #{endpoint.method} #{baked[:url]}"
if baked[:body] != ""
cmd += " #{baked[:body]}"
cmd += " \"#{baked[:body]}\""
if baked[:body_type] == "json"
cmd += " \"Content-Type:application/json\""
end
baked[:header].each do |header|
cmd += " \"#{header}\""
end

baked[:cookie].each do |cookie|
cmd += " \"Cookie: #{cookie}\""
end
end

ob_puts cmd
Expand Down

0 comments on commit 1323a9c

Please sign in to comment.