DAST authentication steps script
## Executive summary
In https://gitlab.com/groups/gitlab-org/-/epics/13633+s we provided support for MFA one-time passwords. This provides users some relief for testing applications that require MFA. However, we need to cover more use cases for MFA. This will improve the user experience by reducing the need for workarounds either through: Selenium scripts, self-built automation, or removing/disabling MFA prior to executing a DAST scan. In the latter case we allow for testing, but are asking users to remove a key security control, which is frowned upon by Security professionals.
### Problem to solve
Support complex authentication flows that can include MFA (both TOTP and alternatives). Our existing workaround of pushing users to use Selenium or other web automation frameworks is overly technical and cumbersome. An easier to use integrated solution is needed for our customers.
### Proposal
Allow users to provide authentication steps that include inputting username, password, TOPT (one time passwords), and other data.
Goals:
* Usable by non coders. Should be easier than selenium/playwrite workaround.
* Growth path for advanced users/scripts
* Quick to build/integrate
* Easy to extend/add new functionality
* Complements existing authentication workflows
Non-goals:
* Replace existing authentication workflows
* Provide all features of selenium/playwrite
Nice to haves, but not required:
* Useful outside of authentication steps. For example providing a script to unlock a section of the application our crawler can't get too
### User experience goals
The user should be able to provide configuration variables that outline username, password, and be able to have a TOTP token generated for usage in testing.
We will not have user interface considerations for this work.
### Metrics
1. Volume of DAST scans initiated that include authentication
2. Volume of failed scans attributed to authentication errors
### Engineering Assessment
Make use of the [goja](https://github.com/dop251/goja) embedded JS runtime to make implementation easier, and more powerful. This will allow quickly adding scripting abilities around authentication.
- [Exploring Goja: A Golang JavaScript Runtime](https://jtarchie.com/posts/2024-08-30-exploring-goja-a-golang-javascript-runtime)
- [Sobek fork of goja from graphana](https://github.com/grafana/sobek)
Example actions that will be available:
- Navigate to URL
- Actions
- Left click
- Right click
- Input value
- Validation auth worked
Access to environment variables would follow the node pattern of `process.env.XXX`:
- `proces.env.DAST_AUTH_USERNAME` -- Send the authentication username (`DAST_AUTH_USERNAME`)
- `proces.env.DAST_AUTH_PASSWORD` -- Send the authentication password (`DAST_AUTH_PASSWORD`)
- `proces.env.DAST_AUTH_OTP_TOKEN` -- Generate and send a TOTP token
- `proces.env.CUSTOM_FIELD` -- Send variable `CUSTOM_FIELD`
### Option 1 -- Script
```
DAST_AUTH_SCRIPT=auth_script.dast
```
_auth_script.dast_
```
doc.actionLeftClick('css:xyz')
doc.actionFormInput('css:xyz', proces.env.DAST_AUTH_USERNAME)
doc.actionFormInput('css:xyz', proces.env.DAST_AUTH_PASSWORD)
doc.actionFormInput('css:xyz', proces.env.ORGANIZATION)
doc.actionLeftClick('css:xyz')
doc.actionFormInput('css:cyz', proces.env.DAST_AUTH_OTP_TOKEN)
doc.actionFormSubmit('css:xyz')
auth.successIfAtUrl('https://...')
```
## Specification
### Class `DastAuthContext`
Singleton instance exposed as `auth` variable.
#### Method `navigateUrl(url)`
Navigate to a provided URL.
Arguments:
- URL string -- URL to navigate too
#### Method `actionLeftClick(selector)`
Left mouse click on selector.
Arguments:
- Selector string -- Selector for item to click
#### `actionRightClick(selector)`
Right mouse click on selector.
Arguments:
- Selector string -- Selector for item to click
#### `actionFormInput(selector, username)`
Form input, textual.
Arguments:
- Selector string -- Selector for item to click
- Input string -- Text to input
#### `actionFormSubmit(selector)`
Form submit
Arguments:
- Selector string -- Selector for item to click
#### `successIfAtUrl(urlOrRegex, regex=False)`
Authentication success if end at specific URL. Supports both a static string and also regexes.
Arguments:
- URL or regex
- Is this a regex (defaults to False)
### Dependencies
* Team dependencies:
* None
* Epic/issue dependencies:
* None
* External dependencies
* None
### DRIs
* Engineer: TBD
* EM: @mikeeddington (acting)
* PM: @abellucci
* Engineering Owner: @rvider
epic