Gotestwaf
An open-source project in Golang to asess different API Security tools and WAF for detection logic and bypasses
Install / Use
/learn @wallarm/GotestwafREADME
GoTestWAF 
GoTestWAF is a tool for API and OWASP attack simulation that supports a wide range of API protocols including REST, GraphQL, gRPC, SOAP, XMLRPC, and others.
It was designed to evaluate web application security solutions, such as API security proxies, Web Application Firewalls, IPS, API gateways, and others.
- How it works
- Requirements
- Quick start with Docker
- Checking evaluation results
- Demos
- Other options to run GoTestWAF
- Configuration options
- Running with OWASP Core Rule Set regression testing suite
How it works
GoTestWAF generates malicious requests using encoded payloads placed in different parts of HTTP requests: its body, headers, URL parameters, etc. Generated requests are sent to the application security solution URL specified during GoTestWAF launch. The results of the security solution evaluation are recorded in the report file created on your machine.
Default conditions for request generation are defined in the testcases folder in the YAML files of the following format:
payload:
- '"union select -7431.1, name, @aaa from u_base--w-'
- "'or 123.22=123.22"
- "' waitfor delay '00:00:10'--"
- "')) or pg_sleep(5)--"
encoder:
- Base64Flat
- URL
placeholder:
- UrlPath
- UrlParam
- JSUnicode
- Header
type: SQL Injection
-
payloadis a malicious attack sample (e.g XSS payload like<script>alert(111)</script>or something more sophisticated). Since the format of the YAML string is required for payloads, they must be encoded as binary data. -
encoderis an encoder to be applied to the payload before placing it to the HTTP request. Possible encoders are:- Base64
- Base64Flat
- JSUnicode
- URL
- Plain (to keep the payload string as-is)
- XML Entity
-
placeholderis a place inside HTTP request where encoded payload should be. Possible placeholders are:- gRPC
- Header
- UserAgent
- RequestBody
- JSONRequest
- JSONBody
- HTMLForm
- HTMLMultipartForm
- SOAPBody
- XMLBody
- URLParam
- URLPath
- RawRequest
The
RawRequestplaceholder will allow you to do an arbitrary HTTP request. The payload is substituted by replacing the string{{payload}}in the URL path, Headers or body. Fields ofRawRequestplaceholder:methodpathheadersbody
Required fields for
RawRequestplaceholder:methodfield
Example:
payload: - test encoder: - Plain placeholder: - RawRequest: method: "POST" path: "/" headers: Content-Type: "multipart/form-data; boundary=boundary" body: | --boundary Content-disposition: form-data; name="field1" Test --boundary Content-disposition: form-data; name="field2" Content-Type: text/plain; charset=utf-7 Knock knock. {{payload}} --boundary-- type: RawRequest test -
typeis a name of entire group of the payloads in file. It can be arbitrary, but should reflect the type of attacks in the file.
Request generation is a three-step process involving the multiplication of payload amount by encoder and placeholder amounts. Let's say you defined 2 payloads, 3 encoders (Base64, JSUnicode, and URL) and 1 placeholder (URLParameter - HTTP GET parameter). In this case, GoTestWAF will send 2x3x1 = 6 requests in a test case.
During GoTestWAF launch, you can also choose test cases between two embedded: OWASP Top-10, OWASP-API,
or your own (by using the configuration option testCasePath).
Requirements
- GoTestwaf supports all the popular operating systems (Linux, Windows, macOS), and can be built natively if Go is installed in the system. If you want to run GoTestWaf natively, make sure you have the Chrome web browser to be able to generate PDF reports. In case you don't have Chrome, you can create a report in HTML format.
- If running GoTestWAF as the Docker container, please ensure you have installed and configured Docker, and GoTestWAF and evaluated application security solution are connected to the same Docker network.
- For GoTestWAF to be successfully started, please ensure the IP address of the machine running GoTestWAF is whitelisted on the machine running the application security solution.
Quick start with Docker
The steps below walk through downloading and starting GoTestWAF with minimal configuration on Docker.
-
Pull the GoTestWAF image from Docker Hub:
docker pull wallarm/gotestwaf -
Start the GoTestWAF image:
docker run --rm --network="host" -it -v ${PWD}/reports:/app/reports \ wallarm/gotestwaf --url=<EVALUATED_SECURITY_SOLUTION_URL>If required, you can replace
${PWD}/reportswith the path to another folder used to place the evaluation report.If you don't want to optionally email the report, just press Enter after the email request message appears, or you can use --noEmailReport to skip the message:
docker run --rm --network="host" -v ${PWD}/reports:/app/reports \ wallarm/gotestwaf --url=<EVALUATED_SECURITY_SOLUTION_URL> --noEmailReportIf the evaluated security tool is available externally, you can skip the option
--network="host". This option enables interaction of Docker containers running on 127.0.0.1.To perform the gRPC tests you must have a working endpoint and use the --grpcPort <port> cli option.
docker run --rm --network="host" -it -v ${PWD}/reports:/app/reports \ wallarm/gotestwaf --grpcPort 9000 --url=http://my.grpc.endpoint -
Check your email for the report.
You have successfully evaluated your application security solution by using GoTestWAF with minimal configuration. To learn advanced configuration options, please use this link.
Checking the evaluation results
Check the evaluation results logged using the STDOUT and STDERR services. For example:
INFO[0000] GoTestWAF started version=v0.5.6-7-g48e6959
INFO[0000] Test cases loading started
INFO[0000] Test cases loading finished
INFO[0000] Test cases fingerprint fp=c6d14d6138601d19d215bb97806bcda3
INFO[0000] Try to identify WAF solution
INFO[0000] WAF was not identified
INFO[0000] gohttp is used as an HTTP client to make requests http_client=gohttp
INFO[0000] WAF pre-check url="http://host.docker.internal:8080"
INFO[0000] WAF pre-check blocked=true code=403 status=done
INFO[0000] gRPC pre-check status=started
INFO[0000] gRPC pre-check connection="not available" status=done
INFO[0000] GraphQL pre-check status=started
INFO[0000] GraphQL pre-check connection="not available" status=done
INFO[0000] Scanning started url="http://host.docker.internal:8080"
INFO[0005] Scanning finished duration=5.422700876s
True-Positive Tests:
┌────────────┬───────────────────────────┬──────────────────────┬─────────────────────┬──────────────────────┬────────────────────┬─────────────┬─────────────────┐
│ TEST SET │ TEST CASE │ PERCENTAGE , % │ BLOCKED │ BYPASSED │ UNRESOLVED │ SENT │ FAILED │
├────────────┼───────────────────────────┼──────────────────────┼─────────────────────┼──────────────────────┼────────────────────┼─────────────┼─────────────────┤
│ community │ community-128kb-rce │ 0.00 │ 0 │ 0 │ 1 │ 1 │ 0 │
│ community │ community-128kb-sqli │ 0.00 │ 0 │ 0 │ 1 │ 1 │ 0 │
│ community │ community-128kb-xss │ 0.00 │ 0 │ 0 │ 1 │ 1 │ 0 │
│ community │ community-16kb-rce │ 100.00 │ 1 │ 0 │ 0 │ 1 │ 0 │
│ community │ community-16kb-sqli │ 100.00 │ 1 │ 0 │ 0 │ 1 │ 0 │
│ community │ community-16kb-xss │ 100.00 │ 1 │ 0 │ 0 │ 1 │ 0 │
│ community │ community-32kb-rce │ 100.00 │ 1 │ 0 │ 0 │ 1 │ 0 │
│ community │ community-32kb-sqli │ 100.00 │ 1 │ 0 │ 0 │ 1 │ 0 │
│ community │ community-32kb-xss │ 100.00
