Giter Site home page Giter Site logo

endava / cats Goto Github PK

View Code? Open in Web Editor NEW
1.1K 14.0 73.0 17.08 MB

CATS is a REST API Fuzzer and negative testing tool for OpenAPI endpoints. CATS automatically generates, runs and reports tests with minimum configuration and no coding effort. Tests are self-healing and do not require maintenance.

License: Apache License 2.0

Java 96.40% JavaScript 0.33% CSS 0.80% Mustache 0.65% Shell 1.83%
java openapi testing api swagger fuzzer rest-api rest-fuzzer

cats's People

Contributors

akullpp avatar binaryarrow avatar cailyoung avatar dependabot[bot] avatar en-ewoods avatar en-milie avatar ganeshnikam18 avatar jc5 avatar mhanci92 avatar shuaixiaoqiang avatar victor-li avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cats's Issues

SocketException: Broken pipe

hello, I'm trying to run tests using this command:
cats --contract=<my-yaml>.yaml --server=http://<my-server> --blackbox
and after generating some amount of tests it fails with an error
Exception while processing!: com.endava.cats.io.CatsIOException: java.net.SocketException: Broken pipe

`[Test 2627*][VLUSIFF] ✖ error Exception while processing!: com.endava.cats.io.CatsIOException: java.net.SocketException: Broken pipe
at com.endava.cats.io.ServiceCaller.call(ServiceCaller.java:225)
at com.endava.cats.io.ServiceCaller_Subclass.call$$superforward1(Unknown Source)
at com.endava.cats.io.ServiceCaller_Subclass$$function$$1.apply(Unknown Source)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:53)
at com.endava.cats.aop.DryRunAspect.intercept(DryRunAspect.java:116)
at com.endava.cats.aop.DryRunAspect_Bean.intercept(Unknown Source)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:40)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
at com.endava.cats.io.ServiceCaller_Subclass.call(Unknown Source)
at com.endava.cats.io.ServiceCaller_ClientProxy.call(Unknown Source)
at com.endava.cats.fuzzer.fields.base.BaseFieldsFuzzer.process(BaseFieldsFuzzer.java:86)
at com.endava.cats.fuzzer.fields.base.BaseFieldsFuzzer.lambda$fuzz$0(BaseFieldsFuzzer.java:65)
at com.endava.cats.report.TestCaseListener.createAndExecuteTest(TestCaseListener.java:110)
at com.endava.cats.report.TestCaseListener_Subclass.createAndExecuteTest$$superforward1(Unknown Source)
at com.endava.cats.report.TestCaseListener_Subclass$$function$$27.apply(Unknown Source)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:53)
at com.endava.cats.aop.DryRunAspect.intercept(DryRunAspect.java:116)
at com.endava.cats.aop.DryRunAspect_Bean.intercept(Unknown Source)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:40)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
at com.endava.cats.report.TestCaseListener_Subclass.createAndExecuteTest(Unknown Source)
at com.endava.cats.report.TestCaseListener_ClientProxy.createAndExecuteTest(Unknown Source)
at com.endava.cats.fuzzer.fields.base.BaseFieldsFuzzer.fuzz(BaseFieldsFuzzer.java:65)
at com.endava.cats.command.CatsCommand.lambda$fuzzPath$6(CatsCommand.java:232)
at java.util.ArrayList.forEach(ArrayList.java:1511)
at com.endava.cats.command.CatsCommand.fuzzPath(CatsCommand.java:229)
at com.endava.cats.command.CatsCommand.startFuzzing(CatsCommand.java:142)
at com.endava.cats.command.CatsCommand.doLogic(CatsCommand.java:126)
at com.endava.cats.command.CatsCommand.run(CatsCommand.java:112)
at picocli.CommandLine.executeUserObject(CommandLine.java:1939)
at picocli.CommandLine.access$1300(CommandLine.java:145)
at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2352)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2314)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
at picocli.CommandLine$RunLast.execute(CommandLine.java:2316)
at picocli.CommandLine.execute(CommandLine.java:2078)
at com.endava.cats.CatsMain.run(CatsMain.java:33)
at com.endava.cats.CatsMain_ClientProxy.run(Unknown Source)
at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:131)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:67)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:41)
at io.quarkus.runner.GeneratedMain.main(Unknown Source)
Caused by: java.net.SocketException: Broken pipe
at sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:420)
at sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:440)
at sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:826)
at java.net.Socket$SocketOutputStream.write(Socket.java:1035)
at sun.security.ssl.SSLSocketOutputRecord.deliver(SSLSocketOutputRecord.java:345)
at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1303)
at okio.OutputStreamSink.write(JvmOkio.kt:57)
at okio.AsyncTimeout$sink$1.write(AsyncTimeout.kt:99)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.kt:255)
at okio.RealBufferedSink.write(RealBufferedSink.kt:146)
at okhttp3.internal.http2.Http2Writer.writeContinuationFrames(Http2Writer.kt:285)
at okhttp3.internal.http2.Http2Writer.headers(Http2Writer.kt:310)
at okhttp3.internal.http2.Http2Connection.newStream(Http2Connection.kt:259)
at okhttp3.internal.http2.Http2Connection.newStream(Http2Connection.kt:225)
at okhttp3.internal.http2.Http2ExchangeCodec.writeRequestHeaders(Http2ExchangeCodec.kt:76)
at okhttp3.internal.connection.Exchange.writeRequestHeaders(Exchange.kt:59)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:36)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
at com.endava.cats.io.ServiceCaller.callService(ServiceCaller.java:373)
at com.endava.cats.io.ServiceCaller.call(ServiceCaller.java:212)
... 44 more

Fatal error: Util_sun_misc_Signal.SignalState.await(): CSunMiscSignal.await() failed.`

java.lang.NullPointerException

I am using version cats-linux 7.0.1
launch string: cats --contract=../swagger.json --server=https://api-site/
Why does not it work? cats.jar starts without problems

Powered by Quarkus 2.5.1.Final
[][] ▶ start Starting CATS, version 7.0.1, build-time 2021-12-18T19:44:03Z UTC
[
][] ● note Processing configuration...
[][] ℹ info No security custom Fuzzer file. SecurityFuzzer will be skipped!
[
][] ℹ info No custom Fuzzer file. CustomFuzzer will be skipped!
[][] ℹ info No reference data file was supplied! Payloads supplied by Fuzzers will remain unchanged!
[
][] ℹ info No URL parameters supplied!
[][] ℹ info No headers file was supplied! No additional header will be added!
[
][] ☑ complete Finished parsing the contract in 1 ms
[][] ▶ start Start cleaning up cats-report folder ...
[
][] ☑ complete Cleanup complete!
java.lang.NullPointerException
at com.endava.cats.util.OpenApiUtils.getSchemas(OpenApiUtils.java:49)
at com.endava.cats.command.CatsCommand.initGlobalData(CatsCommand.java:127)
at com.endava.cats.command.CatsCommand.doLogic(CatsCommand.java:121)
at com.endava.cats.command.CatsCommand.run(CatsCommand.java:109)
at picocli.CommandLine.executeUserObject(CommandLine.java:1939)
at picocli.CommandLine.access$1300(CommandLine.java:145)
at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2352)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2314)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
at picocli.CommandLine$RunLast.execute(CommandLine.java:2316)
at picocli.CommandLine.execute(CommandLine.java:2078)
at com.endava.cats.CatsMain.run(CatsMain.java:27)
at com.endava.cats.CatsMain_ClientProxy.run(Unknown Source)
at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:125)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:67)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:41)
at io.quarkus.runner.GeneratedMain.main(Unknown Source)

--securityFuzzerFile Argument not showing any results

I was curious to use the security fuzzer offered by CATS but when ran,does not give the right result.Is this the right way to use it,I am using the command below (attached in screenshot)? If not please provide some additional info and how it outputs will look like?
Screenshot 2022-04-17 at 7 14 13 PM
Screenshot 2022-04-17 at 7 22 08 PM

cats appears to incorrectly (?) provide a value for a read only field for an unrelated fuzzer

Hi, I've started playing around with cats and noticed something odd. I see a fuzz test report for the RemoveFieldsFuzzer that ran a post request to create a record. Based on the request payload shown in the report, a particular field was actually removed, so that part looks good.

However, another field was included in the request payload that my OpenAPI spec defines as read only (the "id" field in this case). Here's a snippet from the spec, just for context (OpenAPI 3.0.0):

      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  type: object
                  properties:
                    id:
                      type: integer
                      description: ID
                      readOnly: true

The request payload was otherwise structured as I'd expect with various dummy/fuzzed values. My expectation in this case is that this fuzzer would isolate the request payload such that fields marked as read only won't be included, so as to isolate the logic and only validate the behavior when some other fields is intentionally excluded.

I'm not sure if this is a cats bug, or a misunderstanding on my part, or something that can be configured. Thoughts?

How to add mine dictionaries?

In CustomFuzzer there are examples of how to specify the path and fields, but what if I need the fuzzer to go through all the paths and fields in swagger file. Can you give an example? Or how to add your own payloads dictionary for substitution in the fields? For example, on all lines or numbers?

HTTP method not supported yet!

OS: Windows
Action: Fuzz endpoint with POST method
Swagger: 2.0
CATS version: 7.0.5

Hi,

we tried to launch test for fuzzing endpoint with POST method. We used "swagger":"2.0" and after run command below we have got error: HTTP method not supported yet!
We executed this command twice on "openapi":"3.0.3 and it worked well.

java -jar cats.jar --contract=swaggerdoc.yaml --server=https://example.com --paths=/api/v1/xyz --headers=header.yaml --refData=refdata.yaml --httpMethods=POST

Powered by Quarkus 2.6.2.Final
[][] ? start Starting CATS, version 7.0.5, build-time 2022-02-03T19:03:37Z UTC
[
][] ? note Processing configuration...
[][] ? info No security custom Fuzzer file. SecurityFuzzer will be skipped!
[
][] ? info No custom Fuzzer file. FunctionalFuzzer will be skipped!
[][] ? info Reference data file loaded successfully: {/api/v1/xyz={type=PERSON}}
[
][] ? info No URL parameters supplied!
[][] ? complete Finished parsing the contract in 842 ms
[
][] ? start Start cleaning up cats-report folder ...
[][] ? complete Cleanup complete!
[
][] ? info
[][] ? start Start fuzzing path /api/v1/xyz
[
][] ? warning Skipping path /api/v1/xyz. HTTP method not supported yet!
[][] ? skipping Skip printing time execution statistics. You can use --printExecutionStatistics to enable this feature!
[
][] ? complete CATS finished in 82 ms. Total (excluding skipped) requests 0. ? Passed 0, ? warnings: 0, ? errors: 0, ? skipped: 0. You can open the report here:

Pls can you check it.

Thanks

NullPointerException for getSchema()

version: v6.0.5
running environments: Windows 10(64bit)

openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

command: cats --contract=ghes-2.22.yaml --server=https://api.github.com --paths="/user/repos" --headers=header_github.yml
where cats is just java -jar (path)\cats.jar %*
error message:

�[32m
             _____   ___ _____ _____
            /  __ \ / _ \_   _/  ___|
            | /  \// /_\ \| | \ `--.
            | |    |  _  || |  `--. \
            | \__/\| | | || | /\__/ /
             \____/\_| |_/\_/ \____/
           .. ...    -.-. --- --- .-..
�[39m
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m �[1mnote�[m     Proxy configuration to be used: DIRECT
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[32m�[1m �[1mstart�[m    Starting �[32mCATS, version �[32m6.0.5, build-time �[32m2021-08-30T05:50:13.55�[m UTC
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m �[1mnote�[m     �[32mProcessing configuration...�[m
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     No security custom Fuzzer file. SecurityFuzzer will be skipped!
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     No custom Fuzzer file. CustomFuzzer will be skipped!
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     No reference data file was supplied! Payloads supplied by Fuzzers will remain unchanged!
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     No URL parameters supplied!
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[32m�[1m �[1mstart�[m    skipXXXForPath supplied arguments: []. Matching with registered fuzzers...
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[32m�[1m? �[1mcomplete�[m skipXXXForPath list after matching with registered fuzzers: []
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     Supplied arguments
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     contract: ghes-2.22.yaml
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     server: https://api.github.com
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     maxRequestsPerMinute: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     fuzzers: all
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     paths: /user/repos
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     skipPaths: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     excludedFuzzers: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     skipXXXForPath: []
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     skipFields: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     httpMethods: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     checkHeaders: false
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     checkFields: false
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     checkHttp: false
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     checkContract: false
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     fieldsFuzzingStrategy: ONEBYONE
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     maxFieldsToRemove: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     edgeSpacesStrategy: trimAndValidate
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     sanitizationStrategy: sanitizeAndValidate
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     useExamples: true
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     reportingLevel: info
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     log: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     printExecutionStatistics: false
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     timestampReports: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     reportFormat: htmlJs
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     urlParams: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     headers: header_github.yml
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     refData: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     customFuzzerFile: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     securityFuzzerFile: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     proxyPort: 0
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     proxyHost: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     sslKeystore: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     sslKeystorePwd: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     sslKeyPwd: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m? �[1minfo�[m     basicauth: empty
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[32m�[1m? �[1mcomplete�[m �[32mFinished parsing the contract in 1074 ms�[m
[
(...)
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m �[1mskipping�[m Skipping path /user/projects
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[34m�[1m �[1mskipping�[m Skipping path /user/public_emails
[�[36m********* �[0;39m][�[36m*****�[0;39m] �[31m�[1m? �[1merror�[m    Something went wrong while running CATS!
java.lang.NullPointerException: null
        at com.endava.cats.CatsMain.addToSchemas(CatsMain.java:131)
        at com.endava.cats.CatsMain.lambda$getSchemas$1(CatsMain.java:115)
        at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
        at com.endava.cats.CatsMain.getSchemas(CatsMain.java:115)
        at com.endava.cats.CatsMain.fuzzPath(CatsMain.java:360)
        at com.endava.cats.CatsMain.startFuzzing(CatsMain.java:180)
        at com.endava.cats.CatsMain.doLogic(CatsMain.java:171)
        at com.endava.cats.CatsMain.run(CatsMain.java:149)
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:791)
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:775)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:345)
        at com.endava.cats.CatsMain.main(CatsMain.java:102)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:467)

spec file:https://github.com/github/rest-api-description/blob/main/descriptions/ghes-2.22/ghes-2.22.yaml
header file:

all:
  Authorization: token (personal token)

I've tried with --paths="/user/repo", then it runs successfuly with all skipped.

High maxLength throws IllegalArgumentException

Stacktrace when attempting to generate a string when schema says maxLength: 2147483647. (Including this value is the default behavior of springdoc if minLength is specified). Ideally a warning instead. I can update my API doc to be a more reasonable number, but opening so can be handled more gracefully and/or others can know how to fix.

java.lang.IllegalArgumentException: bound must be positive
        at java.base/java.util.Random.nextInt(Random.java:388)
        at com.github.curiousoddman.rgxgen.visitors.GenerationVisitor.visit(GenerationVisitor.java:67)
        at com.github.curiousoddman.rgxgen.nodes.Repeat.visit(Repeat.java:43)
        at com.github.curiousoddman.rgxgen.RgxGen.generate(RgxGen.java:161)
        at com.github.curiousoddman.rgxgen.RgxGen.generate(RgxGen.java:146)
        at com.endava.cats.generator.simple.StringGenerator.generateRightBoundString(StringGenerator.java:59)
        at com.endava.cats.fuzzer.fields.StringFieldsRightBoundaryFuzzer.getBoundaryValue(StringFieldsRightBoundaryFuzzer.java:37)
        at com.endava.cats.fuzzer.fields.base.BaseBoundaryFieldFuzzer.fuzzerGeneratedBoundaryValue(BaseBoundaryFieldFuzzer.java:57)
        at com.endava.cats.fuzzer.fields.base.BaseBoundaryFieldFuzzer.getFieldFuzzingStrategy(BaseBoundaryFieldFuzzer.java:40)
        at com.endava.cats.fuzzer.fields.base.BaseFieldsFuzzer.fuzz(BaseFieldsFuzzer.java:57)
        at com.endava.cats.fuzzer.fields.base.BaseFieldsFuzzer$$FastClassBySpringCGLIB$$3055f71f.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
        at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)
        at com.endava.cats.aop.FuzzerLogAspect.logExecutionTime(FuzzerLogAspect.java:31)
        at jdk.internal.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)
        at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
        at com.endava.cats.fuzzer.fields.StringFieldsRightBoundaryFuzzer$$EnhancerBySpringCGLIB$$d847ce3b.fuzz(<generated>)
        at com.endava.cats.CatsMain.lambda$fuzzPath$14(CatsMain.java:385)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at com.endava.cats.CatsMain.fuzzPath(CatsMain.java:383)
        at com.endava.cats.CatsMain.startFuzzing(CatsMain.java:174)
        at com.endava.cats.CatsMain.doLogic(CatsMain.java:165)
        at com.endava.cats.CatsMain.run(CatsMain.java:143)
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:819)
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:803)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:346)
        at com.endava.cats.CatsMain.main(CatsMain.java:102)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:467)

Fuzzing won't be executed on POST method without request body

OS: Windows
Action: Fuzz endpoint with POST method without request body
Swagger: 2.0
CATS version: 7.0.6
Server: https://petstore.swagger.io/
API doc: https://petstore.swagger.io/v2/swagger.json

Hi,

we tried to launch test for fuzzing endpoint with POST method without request body. We used "swagger":"2.0" and after run command below we have got error: The following HTTP methods won't be executed for path /pet/{petId}: [GET, DELETE]

Command:
java -jar cats-uber.jar --contract=https://petstore.swagger.io/v2/swagger.json --server=https://petstore.swagger.io --paths=/pet/{petId} --urlParams=petId:PET-123 --httpMethods=POST

Log from CMD:
Powered by Quarkus 2.7.1.Final
[][] ? start Starting CATS, version 7.0.6, build-time 2022-03-14T06:40:15Z UTC
[
][] ? note Processing configuration...
[][] ? info No security custom Fuzzer file. SecurityFuzzer will be skipped!
[
][] ? info No custom Fuzzer file. FunctionalFuzzer will be skipped!
[][] ? info No reference data file was supplied! Payloads supplied by Fuzzers will remain unchanged!
[
][] ? info URL parameters: [petId:PET-123]
[][] ? info No headers file was supplied! No additional header will be added!
[
][] ? complete Finished parsing the contract in 1865 ms
[][] ? start Start cleaning up cats-report folder ...
[
][] ? complete Cleanup complete!
[][] ? skipping Skipping path /pet
[
][] ? skipping Skipping path /pet/findByStatus
[][] ? skipping Skipping path /pet/findByTags
[
][] ? info
[][] ? start Start fuzzing path /pet/{petId}
[
][] ? info The following HTTP methods won't be executed for path /pet/{petId}: [GET, DELETE]
[][] ? info 61 configured fuzzers out of 88 total fuzzers: [TrailingSpacesInHeadersFuzzer, VeryLargeValuesInFieldsFuzzer, RemoveFieldsFuzzer, StringFormatTotallyWrongValuesFuzzer, NamingsContractInfoFuzzer, AbugidasCharsInHeadersFuzzer, DummyContentTypeHeadersFuzzer, NewFieldsFuzzer, PathTagsContractInfoFuzzer, NullValuesInFieldsFuzzer, UnsupportedAcceptHeadersFuzzer, HappyFuzzer, StringFormatAlmostValidValuesFuzzer, SecurityFuzzer, OnlySpacesInHeadersFuzzer, LeadingSpacesInHeadersFuzzer, StringsInNumericFieldsFuzzer, MinimumExactValuesInNumericFieldsFuzzer, ExtremeNegativeValueIntegerFieldsFuzzer, MaximumExactValuesInNumericFieldsFuzzer, MinLengthExactValuesInStringFieldsFuzzer, DecimalValuesInIntegerFieldsFuzzer, NonRestHttpMethodsFuzzer, RecommendedHttpCodesContractInfoFuzzer, ExtremeNegativeValueDecimalFieldsFuzzer, DuplicateHeaderFuzzer, RecommendedHeadersContractInfoFuzzer, FunctionalFuzzer, ExtraHeaderFuzzer, SecuritySchemesContractInfoFuzzer, StringFieldsLeftBoundaryFuzzer, BypassAuthenticationFuzzer, TopLevelElementsContractInfoFuzzer, ExtremePositiveValueDecimalFieldsFuzzer, MaxLengthExactValuesInStringFieldsFuzzer, VersionsContractInfoFuzzer, VeryLargeUnicodeValuesInHeadersFuzzer, ZalgoTextInStringFieldsSanitizeValidateFuzzer, RemoveHeadersFuzzer, DummyRequestFuzzer, ZalgoTextInHeadersFuzzer, VeryLargeUnicodeValuesInFieldsFuzzer, DecimalFieldsLeftBoundaryFuzzer, HttpMethodsFuzzer, MalformedJsonFuzzer, VeryLargeValuesInHeadersFuzzer, DecimalFieldsRightBoundaryFuzzer, InvalidValuesInEnumsFieldsFuzzer, EmptyStringValuesInHeadersFuzzer, BooleanFieldsFuzzer, CheckSecurityHeadersFuzzer, EmptyStringValuesInFieldsFuzzer, DummyAcceptHeadersFuzzer, IntegerFieldsRightBoundaryFuzzer, HttpStatusCodeInValidRangeContractInfoFuzzer, AbugidasCharsInStringFieldsSanitizeValidateFuzzer, StringFieldsRightBoundaryFuzzer, ExtremePositiveValueInIntegerFieldsFuzzer, IntegerFieldsLeftBoundaryFuzzer, UnsupportedContentTypesHeadersFuzzer, XmlContentTypeContractInfoFuzzer]
[
][] ? skipping Skipping path /pet/{petId}/uploadImage
[][] ? skipping Skipping path /store/inventory
[
][] ? skipping Skipping path /store/order
[][] ? skipping Skipping path /store/order/{orderId}
[
][] ? skipping Skipping path /user
[][] ? skipping Skipping path /user/createWithArray
[
][] ? skipping Skipping path /user/createWithList
[][] ? skipping Skipping path /user/login
[
][] ? skipping Skipping path /user/logout
[][] ? skipping Skipping path /user/{username}
[
][] ? skipping Skip printing time execution statistics. You can use --printExecutionStatistics to enable this feature!
[***][] ? complete CATS finished in 171 ms. Total (excluding skipped) requests 0. ? Passed 0, ? warnings: 0, ? errors: 0, ? skipped: 0. You can open the report here: file:///C:/Users/user1/Documents/TOOLS/CATS/cats-report/index.html

java.lang.NullPointerException when trying to parse a swagger v2.0 with custom extentions

cats --server=https://my_server --contract=swagger.json --headers=my_headers.yaml --paths=/v1/objects/hint/create --blackbox --debug

[][] 👣 trace Getting fields for prefix:
[
][] 👣 trace Getting fields for prefix: clientid
java.lang.NullPointerException
at com.endava.cats.model.FuzzingData.getFields(FuzzingData.java:94)
at com.endava.cats.model.FuzzingData.getFields(FuzzingData.java:105)
at com.endava.cats.model.FuzzingData.getAllFieldsAsCatsFields(FuzzingData.java:147)
at com.endava.cats.model.FuzzingData.getAllReadOnlyFields(FuzzingData.java:126)
at com.endava.cats.model.FuzzingData.removeReadWrite(FuzzingData.java:71)
at com.endava.cats.model.FuzzingData.getPayload(FuzzingData.java:63)
at com.endava.cats.command.CatsCommand.lambda$fuzzPath$6(CatsCommand.java:225)
at java.util.ArrayList.forEach(ArrayList.java:1541)
at com.endava.cats.command.CatsCommand.fuzzPath(CatsCommand.java:224)
at com.endava.cats.command.CatsCommand.startFuzzing(CatsCommand.java:137)
at com.endava.cats.command.CatsCommand.doLogic(CatsCommand.java:121)
at com.endava.cats.command.CatsCommand.run(CatsCommand.java:108)
at picocli.CommandLine.executeUserObject(CommandLine.java:1939)
at picocli.CommandLine.access$1300(CommandLine.java:145)
at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2352)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2314)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
at picocli.CommandLine$RunLast.execute(CommandLine.java:2316)
at picocli.CommandLine.execute(CommandLine.java:2078)
at com.endava.cats.CatsMain.run(CatsMain.java:27)
at com.endava.cats.CatsMain_ClientProxy.run(Unknown Source)
at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:124)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:67)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:41)
at io.quarkus.runner.GeneratedMain.main(Unknown Source)

Presumably, CATS does not know how to work with ^x- custom extensions, could you please check this case?

Client side rate limitting or throttling

Hi team. first of all thanks for the awesome library you built. The whole process was a breeze.
Just wonder whether it support any type of Rate limit setup or have a plan for having something similar in the future.
I'm asking this because I came across multiple 503 from the API server while running it, the more Fuzzer CATS have, the more it act like a performance testing. :)

Names for reports

Is it possible to make it possible to give names to directories with reports? When several assemblies are launched in cd\ci, problems begin. As far as I see the option is to include a timestamp and parse the fuzzer's response to find out which timestamp. It would be very convenient if you could specify the option where the report will be saved and what name it will have. For exmaple:
cats ... -o /path/to/dir/myreportname/...
so you can operate on variables and paths in cd\ci

malformed JSON scenarios send a correct JSON format payload

The "Send a malformed JSON" scenario doesn't work as expected: the "bla" string that needed to be appended to the payload isn't.

Expected: send a payload + "bla" string at final and receive a 4XX response code
Actual: sends a correct payload and receives a 200 response code

MalformedJSON

Add support for response code ranges

I noticed something else about this particular report... it looks like cats doesn't support http status code "ranges" syntax in I have in the OpenAPI spec file (eg, 4xx as defined here: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#patterned-fields-1).

The expected result in the report says "Should return [4XX] response code as required fields [were] removed", and the response code is actually 400. The result details says:

Response does NOT match expected result. Response code is from a list of expected codes for this FUZZER, but it is undocumented: expected [400, 413, 414, 422], actual [400], documented response codes: [200, 4XX, 5XX]".

CATS fails for HTTP PUT, does not replace the path parameter

I'm not entirely sure if this is because of the tool not working well with that particular case or if there is something in documentation I missed about configuration options. But what is the expected behavior for HTTP PUT for paths that have a required path parameter in them?

Here is the error I'm receiving when trying to run these tests against my API (full URL path is redacted):

[ERROR] [Test 36] [DuplicateHeaderFuzzer] - Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:787)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:768)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at com.endava.cats.CatsMain.main(CatsMain.java:95)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:597)
Caused by: java.lang.IllegalArgumentException: Illegal character in path at index 70: http://localhost:8000/***********************************************/{id}
at java.base/java.net.URI.create(URI.java:883)
at org.apache.http.client.methods.HttpPut.(HttpPut.java:65)
at com.endava.cats.io.ServiceCaller.put(ServiceCaller.java:185)
at com.endava.cats.io.ServiceCaller.call(ServiceCaller.java:154)
at com.endava.cats.fuzzer.headers.DuplicateHeaderFuzzer.process(DuplicateHeaderFuzzer.java:61)
at com.endava.cats.fuzzer.headers.DuplicateHeaderFuzzer.lambda$fuzz$0(DuplicateHeaderFuzzer.java:42)
at com.endava.cats.report.TestCaseListener.createAndExecuteTest(TestCaseListener.java:62)
at com.endava.cats.fuzzer.headers.DuplicateHeaderFuzzer.fuzz(DuplicateHeaderFuzzer.java:41)
at com.endava.cats.fuzzer.headers.DuplicateHeaderFuzzer$$FastClassBySpringCGLIB$$f2dd043b.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
at com.endava.cats.aop.FuzzerLogAspect.logExecutionTime(FuzzerLogAspect.java:19)
at jdk.internal.reflect.GeneratedMethodAccessor22.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at com.endava.cats.fuzzer.headers.DuplicateHeaderFuzzer$$EnhancerBySpringCGLIB$$8ced12e9.fuzz()
at com.endava.cats.CatsMain.lambda$fuzzPath$7(CatsMain.java:309)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at com.endava.cats.CatsMain.fuzzPath(CatsMain.java:307)
at com.endava.cats.CatsMain.startFuzzing(CatsMain.java:152)
at com.endava.cats.CatsMain.doLogic(CatsMain.java:146)
at com.endava.cats.CatsMain.run(CatsMain.java:125)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:784)
... 11 common frames omitted
Caused by: java.net.URISyntaxException: Illegal character in path at index 70: http://localhost:8000/***********************************************/{id}
at java.base/java.net.URI$Parser.fail(URI.java:2913)
at java.base/java.net.URI$Parser.checkChars(URI.java:3084)
at java.base/java.net.URI$Parser.parseHierarchical(URI.java:3166)
at java.base/java.net.URI$Parser.parse(URI.java:3114)
at java.base/java.net.URI.(URI.java:600)
at java.base/java.net.URI.create(URI.java:881)
... 45 common frames omitted

Any way to apply all fuzzers regardsless of field types?

As title, some fuzzers are skipped due to not matching with field types even though I've tried to define field types as below:

properties: mobileNumber: type: oneOf: - type: string - type: number - type: integer - type: boolean - type: array items: {} - type: object

For example below String fuzzer is skipped although I want to it to be applied
[*Test 88**][VLSIFF*] ℹ info Send [very large string values] in request fields: field [xxxxx], value [REPLACE with fuzzfuzzfuzzfuzzfuzzfuzzfuzzfu...], is required [TRUE] [*Test 88**][VLSIFF*] ℹ info Test will be skipped! [*Test 88**][VLSIFF*] ≫ skip Skipped due to: Field could not be fuzzed. Possible reasons: field is not a primitive, is a discriminator or is not matching the Fuzzer schemas [*Test 88**][VLSIFF*] ★ star Test 88, Path ####, HttpMethod ####, Result skipped

So do you know any way to enforce it or do I need to correct my openAPI spec?

Have we thought about integrating CATS into maven plugins?

for example.
If I add maven plugin CATS into pom.xml.

<build>
    <plugins>
        <plugin>
            <groupId>xxxxxxxx</groupId>
            <artifactId>cats</artifactId>
        </plugin>
    </plugins>
</build>

when I run mvn test,
then CATS will automatically run test based on openapi.yaml and local environment.

Positive test with CAT

I understand that CATS is a tool for negative testing.
Can I do a positive test using CATS?

CATS fails on HTTP GET with query parameters

CATS will replace url path parameters. However, query parameters are not set or replaced. For example:
http://localhost/api/{id}?sortBy={sortProperty}

Query parameter "sortBy" is not set in the Full Request Path.

OpenAPI swagger fully supports query parameters:

     parameters:
        - in: query
          name: sortBy
          schema:
            type: string

UnsupportedContentTypesHeadersFuzzer missing "boundary" when sending "multipart" as content type

When sending "multipart" as the content type, an additional "boundary" value is required. This affects the scenarios where UnsupportedContentTypesHeadersFuzzer is used for checking if "multipart" is not accepted, as expected and a 415 response code is returned. The server instead returns Http Code 500 and the test is marked as an error.

actual:
{ "name": "Content-Type", "value": "multipart/form-data" }

expected:
{ "name": "Content-Type", "value": "multipart/form-data; boundary=<value>" }

Ignoring results for a specific HTTP Response code

It is necessary to discard the 4xx codes. So that it doesn’t even get into the results and doesn’t create files on them.
There is an option in the settings to ignoreResponseCodes, but it does not do exactly what we would like - it also creates files and moves the results to the success.
Now results are additionally processed by an external script to get rid of unnecessary HTTP response codes. Is it possible to add similar functionality to the fuzzer?

Question: path parameters?

I love this project, by the way. Heard about you from TLDR newsletter, giving it a try on some of my APIs. (We have some internal tools, and yours is waaay easier to get to work with authentication, props to you :) )

I'm building APIs with Spring, so my springdoc-generated OAS specs can often have path parameters expressed like /articles/{id}, which I'm not sure how to pass in a valid ID for. Especially if these tests call my DELETE method too early, I might get lots of 404s giving false failures on later tests. Any advice?

Translating CATS

Have you ever considered linking CATS' documentation to a freelance translating site? So that non-English speakers who want to contribute to the project can understand the documentation.

Adding a GUI to CATS?

Have you considered adding a GUI to CATS anytime soon?
It could make the program more intuitive and easy to use for new users as they will interact directly with the GUI marking checkboxes with the different arguments they want to use. Basically implementing all current business logic of CATS to a GUI.

better parsing errors

When trying to run cats on our project specification, i get a plain old

[**********][*****] ‼ fatal Error parsing OPEN API contract <filename>

anyway could get a reasoning with whats wrong in the error message ?

we are using relative file paths to reference and reuse schema definitions.

ive added cats.jar to my path so i can run it directly on the project level

When multiple values are required for one parameter

Hello, I have a question using CATS.

I am testing the REST API.
While testing the parameters, the 1:1 matching parameters go well in CATS.
1:N, i.e., when multiple values are required for one parameter, CATS does not seem to recognize it.
Do you know the solution to this problem?
Is it not recognized when multiple values are required for one parameter in CATS?

Thank you.

NullPointerException for MediaType.getSchema()

I'm facing a NullPointerException issue.

The command that I ran was:
./cats.jar --contract=openapi.yaml --server=https://subdomain.domain-name --paths=/v1/endpoint --headers=headers.yaml

Result Info

[********* ][*****] ● note     Proxy configuration to be used: DIRECT
[********* ][*****] ▶ start    Starting CATS, version 6.0.4, build-time 2021-07-23T06:05:54.116 UTC
[********* ][*****] ● note     Processing configuration...
[********* ][*****] ℹ info     No security custom Fuzzer file. SecurityFuzzer will be skipped!
[********* ][*****] ℹ info     No custom Fuzzer file. CustomFuzzer will be skipped!
[********* ][*****] ℹ info     No reference data file was supplied! Payloads supplied by Fuzzers will remain unchanged!
[********* ][*****] ▶ start    skipXXXForPath supplied arguments: []. Matching with registered fuzzers...
[********* ][*****] ☑ complete skipXXXForPath list after matching with registered fuzzers: []
[********* ][*****] ✖ error    Something went wrong while running CATS!
java.lang.NullPointerException: Cannot invoke "io.swagger.v3.oas.models.media.MediaType.getSchema()" because the return value of "io.swagger.v3.oas.models.media.Content.get(Object)" is null
	at com.endava.cats.CatsMain.addToSchemas(CatsMain.java:123)
	at com.endava.cats.CatsMain.lambda$getSchemas$0(CatsMain.java:111)
	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:723)
	at com.endava.cats.CatsMain.getSchemas(CatsMain.java:111)
	at com.endava.cats.CatsMain.fuzzPath(CatsMain.java:355)
	at com.endava.cats.CatsMain.startFuzzing(CatsMain.java:175)
	at com.endava.cats.CatsMain.doLogic(CatsMain.java:166)
	at com.endava.cats.CatsMain.run(CatsMain.java:144)
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:791)
	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:775)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:345)
	at com.endava.cats.CatsMain.main(CatsMain.java:102)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
	at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
	at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
	at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
	at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:467)

How can I fix this issue?

HTTP method not supported yet!

Hi! Works great in cats.jar, but cats-linux doesn't work as it should.

./cats-linux --contract=swagger.json --server=https://api/docs

Powered by Quarkus 2.6.2.Final
[][] ▶ start Starting CATS, version 7.0.3, build-time 2022-01-18T18:54:52Z UTC
[
][] ● note Processing configuration...
[][] ℹ info No security custom Fuzzer file. SecurityFuzzer will be skipped!
[
][] ℹ info No custom Fuzzer file. CustomFuzzer will be skipped!
[][] ℹ info No reference data file was supplied! Payloads supplied by Fuzzers will remain unchanged!
[
][] ℹ info No URL parameters supplied!
[][] ℹ info No headers file was supplied! No additional header will be added!
[
][] ☑ complete Finished parsing the contract in 21 ms
[][] ℹ info
[
][] ▶ start Start fuzzing path /canUserSignDocument
[][] ⚠ warning Skipping path /canUserSignDocument. HTTP method not supported yet!
[
][] ℹ info
[][] ▶ start Start fuzzing path /signDocument
[
][] ⚠ warning Skipping path /signDocument. HTTP method not supported yet!
[][] ≫ skipping Skip printing time execution statistics. You can use --printExecutionStatistics to enable this feature!
[
][] ☑ complete CATS finished in 2 ms. Total (excluding skipped) requests 0. ✔ Passed 0, ⚠ warnings: 0, ‼ errors: 0, ❯ skipped: 0. You can open the report here: file:///..../cats_fuzz/cats-report/index.html

swagger file https://pastebin.com/dRkjCFbZ

How disable colorization in non terminal system?

Is it possible to disable colorization in the output? When it is displayed in the terminal, everything is fine, but when it is displayed on a page, for example, jenkins, then a lot of unnecessary things are visible, which makes it difficult to navigate.

Example:
�[39m�[38;5;188m[�[39m�[38;5;85m*�[35;1mTest 376�[m*�[39m�[38;5;188m][�[39m�[38;5;85m�[35;1mVLVIFF�[m*�[39m�[38;5;188m] �[39m�[38;5;231m�[34m�[1m● �[1mnote�[m Path /signDocument has the following headers: null�[39m�[38;5;188m �[39m�[38;5;227m �[39m�[38;5;188m[�[39m�[38;5;85m*�[35;1mTest 376�[m*�[39m�[38;5;188m][�[39m�[38;5;85m�[35;1mVLVIFF�[m*�[39m�[38;5;188m] �[39m�[38;5;231m�[34m�[1m● �[1mnote�[m Headers that should be added to all paths: null�[39m�[38;5;188m �[39m�[38;5;227m �[39m�[38;5;188m[�[39m�[38;5;85m*�[35;1mTest 376�[m*�[39m�[38;5;188m][�[39m�[38;5;85m�[35;1mVLVIFF�[m*�[39m�[38;5;188m] �[39m�[38;5;231m�[34m�[1m● �[1mnote�[m Path reference data replacement: path /signDocument has the following reference data: {}�[39m�[38;5;188m �[39m�[38;5;227m �[39m�[38;5;188m[�[39m�[38;5;85m*�[35;1mTest 376�[m*�[39m�[38;5;188m][�[39m�[38;5;85m�[35;1mVLVIFF�[m*�[39m�[38;5;188m] �[39m�[38;5;231m�[34m�[1m● �[1mnote�[m Final list of request headers: [CatsRequest.Header(name=Accept, value=application/json), CatsRequest.Header(name=Content-Type, value=application/json)]�[39m�[38;5;188m �[39m�[38;5;227m �[39m�[38;5;188m[�[39m�[38;5;85m*�[35;1mTest 376�[m*�[39m�[38;5;188m][�[39m�[38;5;85m�[35;1mVLVIFF�[m*�[39m�[38;5;188m] �[39m�[38;5;231m�[34m�[1m● �[1mnote�[m Final payload:

Test inputs based on examples for path/query params

For request body, if we add examples in schema, generated inputs take the example for generating meaningful inputs. Is there similar way to generate inputs for path/query parameters?
I tried adding examples for them but CATS doesn’t generate any test cases using examples values.

NullPointerException in PayloadGenerator.parseFromInnerSchema

(swagger.json in the attached zip file)

./cats --debug --paths=/api/groopits/create --contract=swagger.json --dryRun --server=http://example.com

java.lang.NullPointerException at com.endava.cats.model.generator.PayloadGenerator.parseFromInnerSchema(PayloadGenerator.java:360) at com.endava.cats.model.generator.PayloadGenerator.processSchemaProperties(PayloadGenerator.java:342) at com.endava.cats.model.generator.PayloadGenerator.resolveModelToExample(PayloadGenerator.java:318) at com.endava.cats.model.generator.PayloadGenerator.getExampleFromArraySchema(PayloadGenerator.java:274) at com.endava.cats.model.generator.PayloadGenerator.resolvePropertyToExample(PayloadGenerator.java:137) at com.endava.cats.model.generator.PayloadGenerator.parseFromInnerSchema(PayloadGenerator.java:364) at com.endava.cats.model.generator.PayloadGenerator.processSchemaProperties(PayloadGenerator.java:342) at com.endava.cats.model.generator.PayloadGenerator.resolveModelToExample(PayloadGenerator.java:318) at com.endava.cats.model.generator.PayloadGenerator.generate(PayloadGenerator.java:115) at com.endava.cats.factory.FuzzingDataFactory.generateSample(FuzzingDataFactory.java:307) at com.endava.cats.factory.FuzzingDataFactory.getResponsePayloads(FuzzingDataFactory.java:472) at com.endava.cats.factory.FuzzingDataFactory.getFuzzDataForHttpMethod(FuzzingDataFactory.java:187) at com.endava.cats.factory.FuzzingDataFactory.getFuzzDataForPost(FuzzingDataFactory.java:145) at com.endava.cats.factory.FuzzingDataFactory.fromPathItem(FuzzingDataFactory.java:76) at com.endava.cats.factory.FuzzingDataFactory_ClientProxy.fromPathItem(Unknown Source) at com.endava.cats.command.CatsCommand.fuzzPath(CatsCommand.java:198) at com.endava.cats.command.CatsCommand.startFuzzing(CatsCommand.java:137) at com.endava.cats.command.CatsCommand.doLogic(CatsCommand.java:121) at com.endava.cats.command.CatsCommand.run(CatsCommand.java:108) at picocli.CommandLine.executeUserObject(CommandLine.java:1939) at picocli.CommandLine.access$1300(CommandLine.java:145) at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358) at picocli.CommandLine$RunLast.handle(CommandLine.java:2352) at picocli.CommandLine$RunLast.handle(CommandLine.java:2314) at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179) at picocli.CommandLine$RunLast.execute(CommandLine.java:2316) at picocli.CommandLine.execute(CommandLine.java:2078) at com.endava.cats.CatsMain.run(CatsMain.java:27) at com.endava.cats.CatsMain_ClientProxy.run(Unknown Source) at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:124) at io.quarkus.runtime.Quarkus.run(Quarkus.java:67) at io.quarkus.runtime.Quarkus.run(Quarkus.java:41) at io.quarkus.runner.GeneratedMain.main(Unknown Source)

swagger.zip

apiKey after paths

Hello, I got a question while working on this project.
I'm performing REST API fuzzing with this project, and the apiKey value should be added after the paths, do you know how to solve this?

I'll show you an example.

I used this command on linux(kali-linux-2021.4-installer-amd64.iso / VirtualBox)
cats --contract=swagger.json --server=https://[Server IP:Port]/mc2/rest --paths=/logs --headers=headers.yml --refData=refData.yml

This is the result I want
[Full Request Path]
https://[Server IP:Port]/mc2/rest/logs?apiKey={apiKey} ...

but that command running, results in this.
[Full Request Path]
https://[Server IP:Port]/mc2/rest/logs?qsearch=my6cCmm&logfilterid=h7vYiDGvbU4sdtS&pageSize=-9223372036854775808&description=e3RFzlUje4KNA&sensorname=0dWQSwwXK3Ym&auditlogTypes=node%2Cnode&startdate=gansB1kZyUD&radiuspolicy=vzItvvzItvvvz&userid=ycTo3opZ&ssid=Z3DDL&mac=oOCVg&extrainfo=dD0aAmFjdT2fj&nasporttype=zxRbJeIKlWnL&nasport=xNplD0X3&logschema=auditlog&ip=10.10.10.20&sort=ihMdoII&nasmac=slC1yFsn&deptname=hLVhCXLHp&periodType=custom&enddate=sw0Ci14IWkE&loglevel=v336r2pRsee&logid=Ur0ILlieO&page=1&nasip=10.10.10.20&username=oc7YxAy2Pz

Cats endlessly looping on cyclic references

Cats keeps looping endlessly through creating payloads when there are cyclical references in the swagger.

An example that stalls fuzzing:

basePath: /v1
consumes:
- application/json
- application/vnd.api+json
definitions:
  CatFoodReturn:
    properties:
      attributes:
        properties:
          charges_amount:
            $ref: '#/definitions/CatFoodReturn'
            x-omitempty: true
            x-parent: data.attributes
          clearing_id:
            description: Unique identifier for organisations collecting payments
            example: '123456'
            type: string
            x-parent: data.attributes
          compensation_amount:
            $ref: '#/definitions/CatFoodReturn'
            x-omitempty: true
            x-parent: data.attributes
          processing_date:
            description: 'Date on which the operation is to be debited from the debtor
              account. Formatted according to ISO 8601 format: YYYY-MM-DD.'
            example: '2015-02-12'
            format: date
            type: string
            x-nullable: true
            x-parent: data.attributes
          return_amount:
            $ref: '#/definitions/CatFoodReturn'
            x-omitempty: true
            x-parent: data.attributes
          return_code:
            type: string
            x-parent: data.attributes
          return_initiator:
            enum:
            - FOODBANK
            - CUSTOMER
            type: string
            x-parent: data.attributes
          scheme_processing_date:
            description: 'Date on which the operation is processed by the scheme.
              Formatted according to ISO 8601 format: YYYY-MM-DD. Only used if different
              from `processing_date`.'
            example: '2015-02-12'
            format: date
            type: string
            x-nullable: true
            x-parent: data.attributes
          scheme_transaction_id:
            type: string
            x-parent: data.attributes
        type: object
        x-parent: data
      created_on:
        format: date-time
        type: string
        x-nullable: true
      id:
        format: uuid
        type: string
      modified_on:
        format: date-time
        type: string
        x-nullable: true
      organisation_id:
        format: uuid
        type: string
      relationships:
        properties:
          direct_debit:
            properties:
              data:
                type: array
            type: object
          direct_debit_return_admission:
            properties:
              data:
                type: array
            type: object
          direct_debit_return_reversal:
            properties:
              data:
                type: array
            type: object
          direct_debit_return_submission:
            properties:
              data:
                items:
                  $ref: '#/definitions/CatFoodReturnSubmission'
                type: array
            type: object
        type: object
      type:
        pattern: ^[A-Za-z_]*$
        type: string
      version:
        minimum: 0
        type: integer
    required:
    - id
    - organisation_id
    - attributes
    type: object
    x-access:
    - Public
  CatFoodReturnSubmission:
    properties:
      attributes:
        properties:
          scheme_status_code:
            type: string
            x-parent: data.attributes
          scheme_status_code_description:
            type: string
            x-parent: data.attributes
          status_reason:
            type: string
            x-parent: data.attributes
          submission_datetime:
            format: date-time
            readOnly: true
            type: string
            x-parent: data.attributes
          transaction_start_datetime:
            format: date-time
            readOnly: true
            type: string
            x-parent: data.attributes
        type: object
        x-parent: data
      created_on:
        format: date-time
        type: string
        x-nullable: true
      id:
        format: uuid
        type: string
      modified_on:
        format: date-time
        type: string
        x-nullable: true
      organisation_id:
        format: uuid
        type: string
      relationships:
        properties:
          direct_debit:
            properties:
              data:
                type: array
            type: object
          direct_debit_return:
            properties:
              data:
                items:
                  $ref: '#/definitions/CatFoodReturn'
                type: array
            type: object
        type: object
      type:
        pattern: ^[A-Za-z_]*$
        type: string
      version:
        minimum: 0
        type: integer
    required:
    - id
    - organisation_id
    type: object
    x-access:
    - Public
host: api.foodCorp.tech
info:
  title: FoodCorp Public API
  version: '1'
parameters:
  admissionIdParam:
    description: Cat Food Admission Id
    format: uuid
    in: path
    name: admissionId
    required: true
    type: string
  decisionIdParam:
    description: Cat Food decision id
    format: uuid
    in: path
    name: decisionId
    required: true
    type: string
  catFoodIdParam:
    description: Cat Food Id
    format: uuid
    in: path
    name: id
    required: true
    type: string
  recallIdParam:
    description: Recall Id
    format: uuid
    in: path
    name: recallId
    required: true
    type: string
  returnIdParam:
    description: Return Id
    format: uuid
    in: path
    name: returnId
    required: true
    type: string
  reversalIdParam:
    description: Reversal Id
    format: uuid
    in: path
    name: reversalId
    required: true
    type: string
  submissionIdParam:
    description: Cat Food decision submission id
    format: uuid
    in: path
    name: submissionId
    required: true
    type: string
paths:
  /transaction/catfoods/{id}/returns:
    post:
      consumes:
      - application/vnd.api+json
      - application/json
      parameters:
      - $ref: '#/parameters/catFoodIdParam'
      - in: body
        name: Return creation request
        schema:
          $ref: '#/definitions/CatFoodReturn'
      responses:
        201:
          description: Return creation response
          schema:
            $ref: '#/definitions/CatFoodReturn'
        400:
          description: Return creation error
          schema:
            $ref: '#/definitions/CatFoodReturn'
      summary: Create direct debit return
      tags:
      - CatFoods
      x-access:
      - Public
  /transaction/catfoods/{id}/returns/{returnId}:
    get:
      parameters:
      - $ref: '#/parameters/catFoodIdParam'
      - $ref: '#/parameters/returnIdParam'
      responses:
        200:
          description: Return details
          schema:
            $ref: '#/definitions/CatFoodReturn'
      summary: Fetch direct debit return
      tags:
      - CatFoods
      x-access:
      - Public
  /transaction/catfoods/{id}/returns/{returnId}/submissions:
    post:
      consumes:
      - application/vnd.api+json
      - application/json
      parameters:
      - $ref: '#/parameters/catFoodIdParam'
      - $ref: '#/parameters/returnIdParam'
      - in: body
        name: Return submission creation request
        schema:
          $ref: '#/definitions/CatFoodReturn'
      responses:
        201:
          description: Return submission creation response
          schema:
            $ref: '#/definitions/CatFoodReturn'
        400:
          description: Return submission creation error
          schema:
            $ref: '#/definitions/CatFoodReturn'
      summary: create direct debit return submission
      tags:
      - CatFoods
      x-access:
      - Public
  /transaction/catfoods/{id}/returns/{returnId}/submissions/{submissionId}:
    get:
      parameters:
      - $ref: '#/parameters/catFoodIdParam'
      - $ref: '#/parameters/returnIdParam'
      - $ref: '#/parameters/submissionIdParam'
      responses:
        200:
          description: Return submission details
          schema:
            $ref: '#/definitions/CatFoodReturn'
      summary: Fetch return submission
      tags:
      - CatFoods
      x-access:
      - Public
produces:
- application/vnd.api+json
- application/json
responses:
  BadGateway:
    description: Bad Gateway
  BadRequest:
    description: Bad Request
  Conflict:
    description: Conflict
  Forbidden:
    description: Action Forbidden
  NotFound:
    description: Not Found
  UnexpectedError:
    description: Unexpected Error
schemes:
- https
security:
- OAuth2: []
securityDefinitions:
  Basic:
    type: basic
  OAuth2:
    description: OAuth 2.0 with Client Credentials Grant type
    flow: application
    tokenUrl: /oauth2/token
    type: oauth2
swagger: '2.0'
cats --contract=bad.yaml --server=https://api.foodcorp.co -D

Output:

[**********][*******] 👣 trace     Resolving model 'charges_amount' to example
[**********][*******] 👣 trace     Schema properties not null charges_amount: [attributes, created_on, id, modified_on, organisation_id, relationships, type, version]
[**********][*******] 👣 trace     Creating example from model values charges_amount
[**********][*******] 👣 trace     Resolving model 'attributes' to example
[**********][*******] 👣 trace     Schema properties not null attributes: [charges_amount, clearing_id, compensation_amount, processing_date, return_amount, return_code, return_initiator, scheme_processing_date, scheme_transaction_id]
[**********][*******] 👣 trace     Creating example from model values attributes
[**********][*******] 👣 trace     Resolving model 'charges_amount' to example
[**********][*******] 👣 trace     Schema properties not null charges_amount: [attributes, created_on, id, modified_on, organisation_id, relationships, type, version]
[**********][*******] 👣 trace     Creating example from model values charges_amount
[**********][*******] 👣 trace     Resolving model 'attributes' to example
[**********][*******] 👣 trace     Schema properties not null attributes: [charges_amount, clearing_id, compensation_amount, processing_date, return_amount, return_code, return_initiator, scheme_processing_date, scheme_transaction_id]
[**********][*******] 👣 trace     Creating example from model values attributes
[**********][*******] 👣 trace     Resolving model 'charges_amount' to example
[**********][*******] 👣 trace     Schema properties not null charges_amount: [attributes, created_on, id, modified_on, organisation_id, relationships, type, version]
[**********][*******] 👣 trace     Creating example from model values charges_amount
[**********][*******] 👣 trace     Resolving model 'attributes' to example

Hacky python script to detect cyclical references:

import networkx as nx
import sys

#python3 display.py swagger.yaml

gr = nx.DiGraph()

file = open(sys.argv[1],'r')

dot = ""
defs = False

for x in file.readlines():
    if "definitions:" in x:
        defs = True
        continue
    if defs and x.startswith("  ") and x[2] != ' ':
        dot = x.strip()[:-1]
    if defs and "$ref" in x:
        other = x.split('/')[2].strip()[:-1]
        gr.add_edges_from([(dot, other)])
    if defs and x[0] != ' ':
        defs = False
        break

print(nx.is_directed_acyclic_graph(gr))
for x in list(nx.simple_cycles(gr)):
    print(x)
% python3 display.py bad.yaml
False
['CatFoodReturn']
['CatFoodReturnSubmission', 'CatFoodReturn']

Fuzzing path with method DELETE containing request body

OS: Windows
Action: Fuzzing path with method DELETE containing request body
Swagger: 2.0
CATS version: 7.0.6
API doc: petstore.zip

Hi,

we tried to launch test for fuzzing endpoint with DELETE method containing request body. We used "swagger":"2.0" and after run command below fuzz test was successfully launched. When we checked cats-report we expected that request body will be fuzzed with all field fuzzers but in report there is only payload "catsFuzzyField": "catsFuzzyField". When we run same command for POST method more than one field fuzzer was launched for request body.

Command:
java -jar cats-uber.jar --contract=petstore.yaml --server=https://petstore.swagger.io --paths=/pet/{petId} --urlParams=petId:PET-123 --checkFields --httpMethods=DELETE

Cats-report:
cats-report

X-Frame-Options vs Content-Security-Policy in CheckSecurityHeaders

Hello,

First, let me tell you that cats is a really great piece of software, congrats!

Issue

The fuzzer CheckSecurityHeaders checks if X-Frame-Options is present in the response, but as can be seen on MDN:

2022-12-02-173413_789x112_scrot

My app doesn't have a X-Frame-Options header, but has a CSP with frame-ancestors 'none'.

I suggest that the fuzzer validates the test if this string is present in the CSP header.

Best,
~Nico

NamingsContractInfoFuzzer does not allow operations in path names because they are in singular form

Since not all actions are logically linked to CRUD operations, you should be allowed to have endpoints which end with an operation name rather than a resource, in case the action is isolated.
https://www.finextra.com/blogposting/16402/nouns-and-verbs-in-the-world-of-apis
https://plonerestapi.readthedocs.io/en/latest/conventions.html

e.g.
/devices/{id}/alerts/{id}/resend

CATS does not accomodate this approach, since it checks if the path ends with a plural noun, even if the beginning includes one which identifies a resource, in the case above, "alerts"

Getting ResponseCode 999 and log shows Fuzzer [VeryLargeUnicodeValuesInFieldsFuzzer] failed due to [java.net.ProtocolException: Unexpected status line:

I was running CATS with 1 Api and got this error response code shows 999.What does that mean?Log shows :
Exception while processing!: com.endava.cats.io.CatsIOException: java.net.ProtocolException: Unexpected status line: 62\uDCD4?\uD848\uDC6F????\uD855]...[\uDD52?\uD84A\uDE5E?\uD801\uDE64\uD808\uDEDC\uD87E\uDD85\uD81A\uDF26??\uD85D\uDF9C?\uD81F\uDC4F\uD804\uDEB5\uD865\uDF0A??\uD854\uDFC7???\uD86E\uDE22\uD84D\uDC51\uD840\uDF2B\uD862\uDC16??\uD86D\uDF89\uD835\uDFC8??\uD804\uDDAB?????\uD844\uDCEE\uD844\uDC83???\uD85C\uDDA7\uD842\uDF9B??\uD855\uDDCC?\\uD850\uDFAA\uD85B\uDE6F??\uD864\uDCF7?????\uD82C\uDE49\uD876\uDEF7\uD811\uDD6B\uD808\uDD16?\uD850\uDD65\uD800\uDF51????\uD81F\uDC62?????\uD86F\uDC16\uD872\uDEFF\uD83D\uDD85?\uD85A\uDF50\uD863\uDF05\uD85C\uDCBF\uD857\uDEF8?\uD842\uDCBE?\uD85C\uDFF7\uD86A\uDEB5??\uD848\uDFB8ts\": only \"true\" or \"false\" recognized\n at [Source: (ByteArrayInputStream); line: 1, column: 636] (through reference chain: Animal[\"land\"]->AnimalLand[\"reptiles\"]->AnimalReptiles[\"lizard\"])"}HTTP/1.1 400 Bad Request at com.endava.cats.io.ServiceCaller.call(ServiceCaller.java:214) at com.endava.cats.io.ServiceCaller_Subclass.call$$superforward1(Unknown Source) at com.endava.cats.io.ServiceCaller_Subclass$$function$$1.apply(Unknown Source) at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54) at com.endava.cats.aop.DryRunAspect.intercept(DryRunAspect.java:95) at com.endava.cats.aop.DryRunAspect_Bean.intercept(Unknown Source) at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41) at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41) at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32) at com.endava.cats.io.ServiceCaller_Subclass.call(Unknown Source) at com.endava.cats.io.ServiceCaller_ClientProxy.call(Unknown Source) at com.endava.cats.fuzzer.fields.base.BaseFieldsFuzzer.process(BaseFieldsFuzzer.java:86) at com.endava.cats.fuzzer.fields.base.BaseFieldsFuzzer.lambda$fuzz$0(BaseFieldsFuzzer.java:65) at com.endava.cats.report.TestCaseListener.createAndExecuteTest(TestCaseListener.java:109) at com.endava.cats.report.TestCaseListener_Subclass.createAndExecuteTest$$superforward1(Unknown Source) at com.endava.cats.report.TestCaseListener_Subclass$$function$$27.apply(Unknown Source) at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54) at com.endava.cats.aop.DryRunAspect.intercept(DryRunAspect.java:95) at com.endava.cats.aop.DryRunAspect_Bean.intercept(Unknown Source) at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41) at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41) at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32) at com.endava.cats.report.TestCaseListener_Subclass.createAndExecuteTest(Unknown Source) at com.endava.cats.report.TestCaseListener_ClientProxy.createAndExecuteTest(Unknown Source) at com.endava.cats.fuzzer.fields.base.BaseFieldsFuzzer.fuzz(BaseFieldsFuzzer.java:65) at com.endava.cats.command.CatsCommand.lambda$fuzzPath$6(CatsCommand.java:227) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at com.endava.cats.command.CatsCommand.fuzzPath(CatsCommand.java:224) at com.endava.cats.command.CatsCommand.startFuzzing(CatsCommand.java:137) at com.endava.cats.command.CatsCommand.doLogic(CatsCommand.java:121) at com.endava.cats.command.CatsCommand.run(CatsCommand.java:108) at picocli.CommandLine.executeUserObject(CommandLine.java:1939) at picocli.CommandLine.access$1300(CommandLine.java:145) at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358) at picocli.CommandLine$RunLast.handle(CommandLine.java:2352) at picocli.CommandLine$RunLast.handle(CommandLine.java:2314) at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179) at picocli.CommandLine$RunLast.execute(CommandLine.java:2316) at picocli.CommandLine.execute(CommandLine.java:2078) at com.endava.cats.CatsMain.run(CatsMain.java:27) at com.endava.cats.CatsMain_ClientProxy.run(Unknown Source) at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:124) at io.quarkus.runtime.Quarkus.run(Quarkus.java:67) at io.quarkus.runtime.Quarkus.run(Quarkus.java:41) at io.quarkus.runner.GeneratedMain.main(Unknown Source) Caused by: java.net.ProtocolException: Unexpected status line: 62\uDCD4?\uD848\uDC6F????\uD855]...[\uDD52?\uD84A\uDE5E?\uD801\uDE64\uD808\uDEDC\uD87E\uDD85\uD81A\uDF26??\uD85D\uDF9C?\uD81F\uDC4F\uD804\uDEB5\uD865\uDF0A??\uD854\uDFC7???\uD86F\uDC16\uD872\uDEFF\uD83D\uDD85?\uD85A\uDF50\uD863\uDF05\uD85C\uDCBF\uD857\uDEF8?\uD842\uDCBE?\uD85C\uDFF7\uD86A\uDEB5??\uD848\uDFB8ts\": only \"true\" or \"false\" recognized\n at [Source: (ByteArrayInputStream); line: 1, column: 636] (through reference chain: Animal[\"land\"]->AnimalLand[\"reptiles\"]->AnimalReptiles[\"lizard\"])"}HTTP/1.1 400 Bad Request at okhttp3.internal.http.StatusLine$Companion.parse(StatusLine.kt:80) at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.kt:178) at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:106) at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:79) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201) at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154) at com.endava.cats.io.ServiceCaller.callService(ServiceCaller.java:349) at com.endava.cats.io.ServiceCaller.call(ServiceCaller.java:208) ... 44 more
Please provide some info on it and how to resolve this.Open Api spec attached

Question about Report

First of all, I'm using this project really well. Thank you.
But, there was a problem performing the REST API Fuzzing test with this project.
Please tell me the solution to this problem.
I worked on the project by writing kali linux(kali-linux-2021.4-installer-amd64.iso) on Virtual Box.
The REST API uses swagger 2.0.

  1. The characters are broken.
    ex)
    Scenario
    Send [values containing abugidas chars] in request fields: field [logfilterid], value [REPLACE with iజ్ఞ\u200cాP], is required [FALSE]

  2. The jsonbody of the response part is strange.
    ex)
    Response
    {
    "responseCode": 200,
    "httpMethod": "GET",
    "jsonBody": {
    "notAJson": "\n\n<html xmlns="http://www.w3.org/1999/xhtml\"><head id="j_idt2"><link type="text/css" rel="stylesheet" href="/mc2/faces/javax.faces.resource/theme.css?ln=primefaces-dain" /><link type="text/css" rel="stylesheet" href="/mc2/faces/javax.faces.resource/font-awesome/5.13.0/css/all.min-jsf.css?ln=webjars" /><link type="text/css" rel="stylesheet" href="/mc2/faces/javax.faces.resource/font-awesome/5.13.0/css/v4-shims.min-jsf.css?ln=webjars" /><link t"
    },
    "responseTimeInMs": "3",
    "numberOfWordsInResponse": "53",
    "numberOfLinesInResponse": "9",
    "contentLengthInBytes": "1126"
    }

Stack trace on one of my endpoints

As soon as cats starts up against one of my endpoints, it blows up:

[********* ][*****] ▶ start    Start fuzzing path /v1/my/endpointl
[********* ][*****] ✖ error    Something went wrong while running CATS!
java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 14
	at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
	at java.base/java.lang.String.substring(String.java:1874)
	at com.endava.cats.model.factory.FuzzingDataFactory.lambda$addNewCombination$9(FuzzingDataFactory.java:320)
	at java.base/java.util.HashMap.forEach(HashMap.java:1336)
	at com.endava.cats.model.factory.FuzzingDataFactory.addNewCombination(FuzzingDataFactory.java:318)
	at com.endava.cats.model.factory.FuzzingDataFactory.getPayloadCombinationsBasedOnOneOfAndAnyOf(FuzzingDataFactory.java:305)
	at com.endava.cats.model.factory.FuzzingDataFactory.generateSample(FuzzingDataFactory.java:289)
	at com.endava.cats.model.factory.FuzzingDataFactory.getResponsePayloads(FuzzingDataFactory.java:441)
	at com.endava.cats.model.factory.FuzzingDataFactory.getFuzzDataForNonBodyMethods(FuzzingDataFactory.java:110)
	at com.endava.cats.model.factory.FuzzingDataFactory.getFuzzingDataForGet(FuzzingDataFactory.java:87)
	at com.endava.cats.model.factory.FuzzingDataFactory.fromPathItem(FuzzingDataFactory.java:72)
	at com.endava.cats.CatsMain.fuzzPath(CatsMain.java:360)
	at com.endava.cats.CatsMain.startFuzzing(CatsMain.java:174)
	at com.endava.cats.CatsMain.doLogic(CatsMain.java:165)
	at com.endava.cats.CatsMain.run(CatsMain.java:143)
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:819)
	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:803)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:346)
	at com.endava.cats.CatsMain.main(CatsMain.java:102)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
	at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
	at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
	at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:467)

My API does not throw any errors when this happens. Suggestions for what might cause this?

Time delta between request and response

Is it possible to make a time delta between response and request? This feature will greatly help to search for DOS vectors on app in the security fuzzer.

Reporting to JSON format?

Will the report be implemented in the JSON format?
There is not enough for uploading into the defectdojo. At the moment we have to convert html to json an additional script that parses html 😢

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.