When performing an authenticated scan of your web application, the scan will usually require a GoScript to complete the authentication process. A GoScript guides the scanner through the process of authenticating with your application using a browser.
To start, click GoScripts in the main menu, then New GoScript.
You can generate a GoScript automatically, or write one yourself. If you choose to write a script yourself you will need to be familiar with the basic commands described in A Guide to GoScript before proceeding.
Once your script is complete, save it, then return to your scan configuration and import it:
- Web Application Scanner Settings
- Authenticated Scanning
- Select GoScript
- Authenticated Scanning
Contents
See also: Managing Credentials for Scans
Outline
AppCheck supports a number of Multi-Factor Authentication (MFA) machanisms:
- Email-based One-Time Passwords (OTP)
- Email-based magic links
- Time-Based One-Time Passwords (TOTP)
If your application uses a supported MFA mechanism, finish this guide first then proceed to the relevant OTP guide in our Advanced GoScript section.
A standard Authentication GoScript contains two functions, auth.login, auth.confirm.
auth.login
auth.login is used to authenticate with the application, beginning an authenticated session. It should end with a "wait for:" command that looks for a string that appears once authentication has completed. If that string does not appear, the script will fail, and the scanner will know that authentication was not successful.
A common pattern for a login function is:
- Go to the login page.
- Enter the username.
- Enter the password (you might need to submit the username first, if the boxes are on different pages).
- Submit.
- Wait for a string that confirms we are logged in.
- Click on to another page that can only be accessed when authenticated.
- Wait for a string that appears on that page.
The last two steps are to confirm that the authenticated session is working, and to demonstrate to the scanner what authenticated requests look like (ie requests made after the authentication process has completed - until that point it has only seen requests made during the authentication process). This is important to help the scanner make artificial authenticated requests as part of its testing process.
if you are scanning an API alongside the front end application, make sure the thing you click for step 6 is something that triggers an API request - the scanner needs to witness an authenticated API request so that it can make its own such requests in order to scan the API.
auth.confirm
auth.confirm is run periodically to confirm that the authenticated session is still alive. Like auth.login, it should end with a "wait for:" command that looks for a string that appears only when in an authenticated session. If that string does not appear, the script will fail, and the scanner will know that it needs to log in again.
A common pattern for a confirm function is:
- Go to a page that can only be accessed when authenticated.
- Wait for a string that appears on that page.
Auth Analysis
The purpose of your Authentication GoScript is to demonstrate a successful log-in and log-out flow to the scanner. The scanner analyses the results of this process to build a profile which it will use to submit authenticated requests while scanning your application.
If the scanner was able to authenticate with and analyse your application's authentication barrier then your scan results will contains two Info level findings: "Successful Authentication" and "Successful Auth Analysis". If these do not appear and you have not written a script then you will need to write one. If these do not appear and you have written a script then the script is not sufficient, in this situation you may wish to contact AppCheck Support for further help.
An authentication profile consists of you parts:
- The Auth Mechanism - this is the process for submitting an authenticated request - this is usually a token (or tokens) that must be submitted in a request to make that request authenticated. This could be a header, a cookie, a URL parameter, or a combination. The scanner will determine this by observing requests made post-login (as demonstrated in your auth.confirm function), and testing those requests with components removed to see which are required to maintain the authenticated status.
- The Auth Indicator - this is an example authenticated request, one which will succeed if the session is still authenticated, and will fail otherwise (for example if we do not use the correct Auth Mechanism, or if the session has expired). This request is sent every ten seconds to confirm that the authenticated session is still active. This request will often be one seen during your auth.confirm function.
Even if your login script completes successfully (as indicated by a "Successful Authentication" info level finding in the scan results), if the scanner is not able to determine the above components then the scan will not remain authenticated for its duration, so it is important that your scan results also contain a "Successful Auth Analysis" info level finding.
In this example you can see that the script completed successfully, but the analysis failed:
The GoScript development and testing tool at https://scanner.appcheck-ng.com/goscript/ allows you test the auth analysis process independently of any scan (so you don't need to wait until a scan runs to find out if it will work).
To test auth analysis for your script, follow these steps:
- Ensure the script itself completes successfully
-
Select the targets to be in scope for the test. These should be the targets you want to log in to, and should mirror the targets you intend to put in your scan once your script is finished.
If your account scope is not all visible to select, click "Load Organisation Scope"
- Then click this icon at the bottom of the GoScript page:
The analysis will involve running the script multiple times and could take a couple of minutes to complete. Once finished the results will be shown on the Auth Profile tab:
It is important that you see an "Auth Detected" Analysis outcome, highlighted in green.
Username and Password Variables
See GoScript Variables for an introduction to variables.
The scanner passes a number of variables into authentication GoScripts, including the username and password supplied in the configuration. This means you can avoid hardcoding the username and password into the script, which is more secure (since scripts are printed to logs on the scan hubs) and easier to maintain (since the username and password can be changed independently of the script).
The examples below use these variables, using the {variableName} syntax.
To select your username and password for use in the script, first configure the Credentials as per Managing Credentials for Scans, then click Import Credential to import them into the script:
Examples
Basic Example
def auth.login
# Go to the login page and wait for it to load
go: https://www.example.com/
wait for: Forgot password?
# Submit our credentials and wait for the next page to load
username = {username}
password = {password}
click: Login
click: My Account
wait for: Change address
# If "Change address" does not appear on the page then the login has failed
def auth.confirm
go: https://www.example.com
click: My Account
wait for: Change address
# If "Change address" does not appear on the page then we have failed to confirm
# that we are still logged in, so the scanner will run auth.login again
Some applications, particularly Single Page Applications (SPAs), use data submitted with each request to maintain the session, so navigating to a page using the browser's address bar will log you out. In these situations avoid using go: commands - instead look for an element which always appears and click: it. This is often the company logo in the top left, which might take you back to a dashboard for example, and this can be used to confirm you're still logged in:
def auth.confirm
click: #company_logo
click: My Account
wait for: Change address
# In this example if the GoScript engine cannot click an element
# with ID company_logo (because it isn't there), or if clicking
# it does not take us to a page containing "My Account" (and so on)
# then the function fails, and the GoScript engine knows it is logged
# out and that it should run auth.login again.
Advanced auth.login Example Using Conditional Logic
This example uses conditional logic to handle a situation where the login process changes after the first visit. See Conditionals for a guide to using conditional login in GoScripts.
def auth.login
go: https://www.example.com
if see {username}
click: {username}
else
wait for: Forgot password?
username = {username}
# The above conditional logic clicks the user's name if it appears,
# otherwise it types the user's name into the username box. In
# either case, it then carries on to the next step.
password = {password}
click: Login
click: My Account
wait for: Change address
# The above "wait for:" command will time out if "Change address" does not
# appear on the page within 30 seconds. This counts as an authentication
# failure.
# If any commands earlier in the script fail or time out that also counts
# as an authentication failure.
Comments
0 comments
Article is closed for comments.