Mayhem for API always constructs URLs by concatenating each endpoint's path with a common server URL.
The paths are taken directly from the API specification.
The server URL is given via the --url <url>
argument to mapi run
. (There are other ways, but we'll focus on this one, as it is the most explicit!)
Sometimes the specification elides a common prefix from all endpoints. Consider a specification:
/version:
get:
...
/user:
get:
...
If the complete URLs are supposed to be https://localhost/api/v2/version and https://localhost/api/v2/user, the common prefix (/api/v2
) will need to be included in the server URL given to Mayhem for API:
mapi run ... --url 'https://localhost/api/v2'
Often, Mayhem for API just needs a bit more... specificity... in the specification, in order to successfully cover an endpoint.
If Mayhem for API is consistently unable to generate structurally valid payloads, this can usually be resolved by adding or refining schemas in the spec.
OpenAPI allows for parameters and request body types to be declared, in whatever level of detail is needed, using Schema Objects.
For example, just listing the required properties for an endpoint's request body makes Mayhem for API massively more likely to successfully cover that endpoint:
/example:
post:
summary: example
requestBody:
required: true
content:
application/json:
schema:
type: object
+ properties:
+ page:
+ type: integer
Mayhem for API will do a better job generating statefully valid payloads if stateful identifiers that are passed between endpoints have the same name and type.
For example, if you have an endpoint that lists resources and another that fetches a resource by id, make sure the identifiers share a name and type, so that Mayhem for API can more easily connect the dots:
/example:
get:
summary: list of examples
responses:
'200':
description: all the examples
content:
application/json:
schema:
type: array
items:
type: object
properties:
example_id:
type: integer
- /example/{id}:
+ /example/{example_id}:
get:
summary: details of a single example
parameters:
- in: path
- name: id
+ name: example_id
schema:
- type: string
+ type: integer
ℹ️ The spec changes you make to help Mayhem for API exercise your API will also improve anything else—code, documentation, and so on—that you derive from your specs! Win-win!
There are situations where Mayhem for API really just needs a hint. For example, consider endpoints that include the username of the currently-authenticated user, like '/user/{username}/settings'.
ℹ️ Examples are often needed when the service being tested has some pre-loaded state (like the user, for authentication!) that's difficult to naturally "discover" through fuzzing.
In this case, OpenAPI allows "example" values, and Mayhem for API will take the examples into account when generating request payloads. For the "{username}" parameterized endpoint, this might be as simple as:
/user/{username}/settings:
get:
summary: settings
parameters:
- in: path
name: username
schema:
type: string
+ example: mayhem4api-user
ℹ️ This option is currently in preview and is subject to change
Mayhem for API may need additional hints to make a successful requests to endpoints. Perhaps every request requires that a constant value is applied to every request body or path parameter. It is possible to provide hints for all generated requests by passing one or more --resource-hint
options to the mapi run
command.
In order to understand which resources are applicable to the --resource-hint
option, you should first list the available resources for your API specification with the mapi describe specfication
command.
For example, let's list the resources of the petstore demo API:
mapi describe specification \
"https://demo-api.mayhem4api.forallsecure.com/api/v3/openapi.json"
Spec path is https://demo-api.mayhem4api.forallsecure.com/api/v3/openapi.json
PUT /pet BODY category/id
PUT /pet BODY category/name
PUT /pet BODY id
PUT /pet BODY name
...
PUT /user/{username} BODY userStatus
PUT /user/{username} BODY username
DELETE /user/{username} PATH username
Every resource for the specification is flattened and listed out in the response. For example, the following represents a field value that is passed as part of a request body when generating a PUT
request against /pet
.
Method
|
| Path
| |
| | Request part (can be QUERY, PATH, HEADER or BODY)
v v v
PUT /pet BODY category/id
^
Fully qualified path to request body
Another example is a path parameter:
Method
|
| Path
| |
| | Request part
v v v
DELETE /user/{username} PATH username
^
Path parameter
The --resource-hint
option to mapi run
takes a tuple of resource path
and value
, separated by a colon.
For example, say we wanted to always use the same username
value of foo
for the DELETE
method noted above:
mapi run \
petstore auto "https://demo-api.mayhem4api.forallsecure.com/api/v3/openapi.json" \
--url "https://demo-api.mayhem4api.forallsecure.com/api/v3/" \
--resource-hint "DELETE /user/\{username\} PATH username:foo"
The --resource-hint
specifies that any request generated for this DELETE
resource will now use foo
for the username
parameter:
Resource Path split with ':'
v v
--resource-hint "DELETE /user/\{username\} PATH username:foo"
^ |
must escape '{' for |
valid regex |
^ Value to use
--resource-hint
will accept a regular expression for matching resource path as well. For instance, say you wanted to substitute foo
for EVERY username
value:
Match ANY request that requires a 'username'
v
--resource-hint "username$:foo"
When multiple --resource-hint
are specified that match the same resource path, Mayhem for API will randomly select one of the provided hints whenever it generates a request.
Choose between 'foo' ... or 'bar'
v v
--resource-hint "username$:foo" --resource-hint "username$:bar"
If, for some reason, your endpoint cannot be covered successfully, consider skipping it during fuzzing (using the --ignore-endpoint <endpoint>
argument to mapi run
), because we have low confidence in lack of findings.
Prime Your APIs for Performance ... In as Little as 5 Minutes.
At this point, Mayhem for API is able to exercise your API quite thoroughly and probably uncover all sorts of issues. More importantly in the long run, it will give you confidence that your API is free of the issues we don't find!
By submitting this form, you agree to our Terms of Use and acknowledge our Privacy Statement.