Skip to content

Commit eb3300f

Browse files
committed
documentation for WFC Authentication
1 parent 84c8592 commit eb3300f

2 files changed

Lines changed: 246 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ But future versions of WFC will likely be extended to support GraphQL and RPC as
2121

2222
There are 4 main contributions in WFC:
2323

24-
1) _WFC Authentication_: a JSON Schema definition to represent authentication information for fuzzers. Currently under [src/main/resources/wfc/schemas/auth.yaml](src/main/resources/wfc/schemas/auth.yaml). Documentation on how to use is can be found at [UNDER-CONSTRUCTION]. Examples of configurations files can be found in the [Web Fuzzing Dataset (WFD) repository](https://github.com/WebFuzzing/Dataset).
24+
1) _WFC Authentication_: a JSON Schema definition to represent authentication information for fuzzers. Currently under [src/main/resources/wfc/schemas/auth.yaml](src/main/resources/wfc/schemas/auth.yaml). Documentation on how to use it [can be found here](./auth.md). Examples of configurations files can be found in the [Web Fuzzing Dataset (WFD) repository](https://github.com/WebFuzzing/Dataset).
2525

2626
2) _WFC Faults_: classification of existing automated oracles proposed in the literature of fuzzing web APIs. Currently under [src/main/resources/wfc/faults/fault_categories.json](src/main/resources/wfc/faults/fault_categories.json).
2727

auth.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# Authentication with WFC
2+
3+
The API/SUT might require authenticated requests.
4+
And there are several different mechanism to do authentication.
5+
6+
This documentation explains, with some examples, how WFC can be used to create auth configuration files using the JSON Schema defined in [auth.yaml](src/main/resources/wfc/schemas/auth.yaml).
7+
8+
The idea is to define in configuration files (e.g., in YAML and TOML formats) how authentication can be done, by defining info for some users.
9+
This information needs to be actually existing and valid, as the APIs will need to validate it.
10+
11+
As this info is specific to the testing environment in which the fuzzing is done, it is not something that should be really specified in the API schemas (e.g., OpenAPI for REST).
12+
Therefore, separated configurations are a necessity.
13+
14+
These configuration files just specify _how_ authentication can be done with concrete values (e.g., user ids and passwords).
15+
Still, it is up to the fuzzers to read such information, and then make the correct authentication calls.
16+
17+
> __NOTE:__ If the type of authentication you need is not currently supported, please open a new feature request on [our issue page](https://github.com/WebFuzzing/Commons/issues).
18+
19+
20+
## Static Tokens
21+
22+
```
23+
auth:
24+
- name: FOO
25+
fixedHeaders:
26+
- name: Authorization
27+
value: " some static token for FOO"
28+
- name: BAR
29+
fixedHeaders:
30+
- name: Authorization
31+
value: " some static token for BAR"
32+
```
33+
34+
An array called `auth` is instantiated, having each entry representing the authentication info for different users.
35+
In this example, two users are defined: _FOO_ and _BAR_.
36+
The names here are just for documentation (e.g., fuzzers could use such names as comments when generating test cases using such info).
37+
38+
When they need to authenticate, these users require some fixed values in some specified HTTP header, sent on each HTTP call.
39+
This is for example what needed in HTTP Basic (RFC-7617).
40+
The "token" here is static, e.g., not changing.
41+
This could be for example including userid and password of the user, possibly encoded in different formats (e.g., Base64).
42+
Such credentials (i.e., userid/password) would not change per user, and so can be specified only once.
43+
44+
Everytime a fuzzer want to make an authenticated call with user _BAR_, based on that information it should send the HTTP requests with `Authorization: some static token for BAR` header.
45+
46+
Static tokens are not really recommended, and should be avoided.
47+
Still, WFC enables to support their definition, if needed.
48+
49+
## Dynamic Tokens
50+
51+
A common practice is to send a login request to a login endpoint (on same the API, or a third-party one), and extract a _dynamic_ token from the response.
52+
The token can be used in following HTTP requests.
53+
The token will be specific for the user, and have a limited lifespan in which it is valid for authentication.
54+
55+
Let's consider this following example of configuration:
56+
57+
```
58+
auth:
59+
- name: foo
60+
loginEndpointAuth:
61+
payloadRaw: "{\"username\": \"foo\", \"password\": \"123\"}"
62+
- name: bar
63+
loginEndpointAuth:
64+
payloadUserPwd:
65+
username: bar
66+
password: "456"
67+
usernameField: username
68+
passwordField: password
69+
70+
authTemplate:
71+
loginEndpointAuth:
72+
endpoint: /login
73+
verb: POST
74+
contentType: application/json
75+
expectCookies: true
76+
```
77+
78+
Here, 2 example users are specified under `auth`: `foo` and `bar`, with their passwords.
79+
80+
The payload sent to the login endpoint could be either specified as it is (i.e., with `payloadRaw`), or with username/password separately (from which the right payload is automatically derived and formatted based on the `contentType`, e.g., `application/json` or `application/x-www-form-urlencoded`).
81+
82+
There are several pieces of information that would be the same for both users:
83+
* `endpoint`: the path for the endpoint with the login (can use `externalEndpointURL` if it is on a different server).
84+
* `verb`: the HTTP verb used to make the request (typically it is a `POST`).
85+
* `contentType`: specify how the payload will be sent (e.g., JSON in this case).
86+
* `expectCookies`: tell the fuzzer that from the login endpoint we expect to get a cookie for the authentication.
87+
88+
To avoid duplication, shared info can be defined in the `authTemplate` object.
89+
90+
Note that, at times, username/password information might be passed via a header (e.g., with `Basic`), instead of with a body payload.
91+
This is supported with the array `headers`, in which each header can be specified with a `name` and `value`.
92+
For example:
93+
94+
```
95+
auth:
96+
- name: test
97+
loginEndpointAuth:
98+
endpoint: /api/login
99+
verb: POST
100+
headers:
101+
- name: Authorization
102+
value: "Basic dGVzdDp0ZXN0Cg=="
103+
```
104+
105+
106+
107+
If instead of cookies we have a token to be extracted from the JSON response of the login endpoint, we can use something like:
108+
109+
```
110+
auth:
111+
loginEndpointAuth:
112+
# ... other data here
113+
token:
114+
headerPrefix="Bearer "
115+
extractFromField = "/token/authToken"
116+
httpHeaderName="Authorization"
117+
```
118+
119+
What will happen here is that a fuzzer will make a POST to `/login` and then extract the field `token.authToken` from the JSON response (the entry `extractFromField` is treated as a JSON Pointer (RFC 6901)).
120+
Assume for example we have `token.authToken = 123456`.
121+
In the following auth requests, then the fuzzer will make requests with HTTP header: `Authorization:Bearer 123456`.
122+
123+
124+
## Fuzzer Configurations
125+
126+
Having right authentication credentials is essential when testing real-world APIs.
127+
As such, preparing an authentication configuration file would hence become a common practice.
128+
Still, the fuzzer itself might have different configuration settings not related to authentication (e.g., related to where to output the generated tests, and for how long to run the fuzzer).
129+
Such info could be passed on the command-line as program inputs, or specified in a configuration file.
130+
In this latter case, having two different configuration files (one for authentication and one for internal settings) might be cumbersome.
131+
132+
To avoid such issue, WFC Authentication supports the object `configs`.
133+
This is an object of string fields.
134+
It can be treated as a map/dictionary of `key:value` pairs.
135+
Each key is a fuzzer configuration property, with given chosen value.
136+
As each configuration property will be specific to each fuzzer, the map is generic from string keys to string values.
137+
138+
The following is an example for the fuzzer _EvoMaster_.
139+
If there is no `em.yaml` file, _EvoMaster_ generates automatically an empty configuration file `em.yaml`, where all available options are commented out.
140+
This includes the `config` object, as well as `auth` and `authTemplate`.
141+
142+
```
143+
### Template configuration file for EvoMaster.
144+
### Most important parameters are already present here, commented out.
145+
### Note that there are more parameters that can be configured. For a full list, see:
146+
### https://github.com/EMResearch/EvoMaster/blob/master/docs/options.md
147+
### or check them with the --help option.
148+
149+
150+
configs: {} # remove this {} when specifying properties
151+
# bbSwaggerUrl: ""
152+
# bbTargetUrl: ""
153+
# blackBox: false
154+
# configPath: "em.yaml"
155+
# endpointFocus: null
156+
# endpointPrefix: null
157+
# endpointTagFilter: null
158+
# header0: ""
159+
# header1: ""
160+
# header2: ""
161+
# maxTime: "5m"
162+
# outputFilePrefix: "EvoMaster"
163+
# outputFileSuffix: "Test"
164+
# outputFolder: "generated_tests"
165+
# outputFormat: "DEFAULT"
166+
# overrideOpenAPIUrl: ""
167+
# prematureStop: ""
168+
# ratePerMinute: 0
169+
# sutControllerHost: "localhost"
170+
# sutControllerPort: 40100
171+
# testTimeout: 60
172+
173+
174+
175+
### Authentication configurations.
176+
### For each possible registered user, can provide an AuthenticationDto object to define how to log them in.
177+
### Different types of authentication mechanisms can be configured here.
178+
### For more information, read: https://github.com/EMResearch/EvoMaster/blob/master/docs/auth.md
179+
180+
#auth:
181+
# - name: ?
182+
# fixedHeaders:
183+
# - name: ?
184+
# value: ?
185+
# loginEndpointAuth:
186+
# endpoint: ?
187+
# externalEndpointURL: ?
188+
# payloadRaw: ?
189+
# payloadUserPwd:
190+
# username: ?
191+
# password: ?
192+
# usernameField: ?
193+
# passwordField: ?
194+
# verb: GET | POST
195+
# contentType: ?
196+
# token:
197+
# extractFromField: ?
198+
# httpHeaderName: ?
199+
# headerPrefix: ?
200+
# expectCookies: true | false
201+
202+
203+
### Authentication Template.
204+
### When defining auth info for several test users, lot of info might be replicated, e.g.:
205+
### endpoint: /login
206+
### verb: POST
207+
### contentType: application/json
208+
### expectCookies: true
209+
### To avoid replicating same setting over and over again, common settings can be put in a template.
210+
### When this configuration file is loaded, all fields from the template are applied to all
211+
### fields in the auth settings, unless those are not 'null' (i.e., they will not be overridden).
212+
### Note that, as names must be unique, 'name' field should not be specified in the template.
213+
214+
215+
#authTemplate:
216+
# fixedHeaders:
217+
# - name: ?
218+
# value: ?
219+
# loginEndpointAuth:
220+
# endpoint: ?
221+
# externalEndpointURL: ?
222+
# payloadRaw: ?
223+
# payloadUserPwd:
224+
# username: ?
225+
# password: ?
226+
# usernameField: ?
227+
# passwordField: ?
228+
# verb: GET | POST
229+
# contentType: ?
230+
# token:
231+
# extractFromField: ?
232+
# httpHeaderName: ?
233+
# headerPrefix: ?
234+
# expectCookies: true | false
235+
```
236+
237+
238+
239+
240+
241+
242+
243+
244+
245+

0 commit comments

Comments
 (0)