Skip to content

Commit

Permalink
feat(test): Allow overwriting the original value in function testing
Browse files Browse the repository at this point in the history
  • Loading branch information
bararchy committed Jul 3, 2024
1 parent 990dc88 commit c7ac164
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,31 @@ tester.run_check(scan_name: "UnitTestingScan - XSS - function only", tests: ["xs
end
```

> **Note**
>
> You also have an optional "param_overwrite" parameter that allows you to overwrite the parameters in the request.
> This is useful when your function is expecting a specific data object like JSON or JWT etc..

You can use the `param_overwrite` to overwrite the value to be attacked like:

```crystal
jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
tester.run_check(scan_name: "jwt-testing", tests: ["jwt"], param_overwrite: jwt) do |payload, response|
spawn do
while payload_data = payload.receive?
# This is where we send the payload to the function and send back a response
# In this example we just want to send back the payload
# as we are testing reflection
# my_function is a demo function that returns the payload
response_data = my_JWT_verification(payload_data)
# we end up sending the response back to the channel
response.send(response_data)
end
end
end
```

There is also a variant of this interface that accepts target and yields back the whole HTTP::Server::Context.
This is useful if you want to do something with the response body or headers.

Expand Down
20 changes: 20 additions & 0 deletions spec/sec_tester_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,26 @@ describe SecTester::Test do
end
end

it "starts a function oriented test for XSS including param_overwrite" do
tester = SecTester::Test.new
expect_raises(SecTester::IssueFound) do
tester.run_check(scan_name: "xss", tests: ["xss"], param_overwrite: "abcdefu") do |payload, response|
spawn do
while payload_data = payload.receive?
# This is where we send the payload to the function and send back a response
# In this example we just want to send back the payload
# as we are testing reflection
# my_function is a demo function that returns the payload
response_data = my_function(payload_data)

# we end up sending the response back to the channel
response.send(response_data)
end
end
end
end
end

it "starts a request/response oriented test for XSS" do
tester = SecTester::Test.new
target = SecTester::Target.new(
Expand Down
4 changes: 2 additions & 2 deletions src/sec_tester/test.cr
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ module SecTester
server.try &.close
end

def run_check(scan_name : String, tests : String | Array(String)?, severity_threshold : Severity = :low, options : Options = Options.new, on_issue : Bool = true, &)
def run_check(scan_name : String, tests : String | Array(String)?, severity_threshold : Severity = :low, options : Options = Options.new, on_issue : Bool = true, param_overwrite : String? = nil, &)
# Start a server for the user, in this form we can test specific functions.
payload = Channel(String).new
response = Channel(String).new
Expand All @@ -95,7 +95,7 @@ module SecTester
end

target = Target.new(
url: "http://#{addr}?artificial=dummydata",
url: "http://#{addr}?artificial=#{param_overwrite || "dummydata"}",
)

yield payload, response
Expand Down

0 comments on commit c7ac164

Please sign in to comment.