Authentication
Web applications often have a section for registered users only. This part of the web application can only be assessed by logging in to the app, and the process for logging in is called "Authentication". AppSpider supports a number of ways to authenticate into your application. You can configure these authentication methods in the Authentication tab of the scan config wizard.
Automated Login
If the URL you've defined as the scope of your scan includes forms to enter in credentials and login, you can leverage the Automated Login option:
- Click the checkbox Site requires Form authentication.
- Enter the User Name and Password fields with a valid set of credentials that AppSpider can use to log in to the app, crawl it, and scan for vulnerabilities.
- If you use SSO (Single Sign-On) to authenticate to the app, expand the Advanced Options for SSO and configure your SSO details accordingly so that AppSpider can leverage Active Directory (AD) credentials to authenticate to the app.
Macro Authentication
AppSpider may sometimes be unable to reach the login page of your application, or the login form may become available only after a certain specific sequence of actions has been carried out on your website. For example, the login form may be in a pop-up that gets dynamically generated with Javascript when the "Login" button is pressed from the "Administration" window. You can enable AppSpider to perform this sequence of steps by recording a macro.
A macro is a sequence of actions such as the clicking of buttons or text entry in a web page. AppSpider records these sequences in xml format within a .rec
file. During a scan, AppSpider can replay the actions in this file to log in to the web application. If you wish to use macro authentication, you can configure it using the following steps:
- Open the Authentication > Macro Authentication tab.
- Select the Use login macro (for Form Authentication) checkbox.
- If you have previously recorded a login macro on this system, you can select it by opening the file explorer with the ellipsis (...) button. If you do not have a previously recorded macro, follow the next steps.
- Click the Record button. This will open the Browser Macro Recorder in a new tab. The Browser Macro Recorder will open your target application by default.
- Follow the steps for logging in to your application. Save the macro into a .rec file on your local system. By default, AppSpider will save the macro file in the "Macro" folder under the AppSpider data directory.
Note
As AppSpider records your actions and translates them into XPath commands, do not perform any actions apart from those required for logging in while recording the login macro. Additionally we advise that you click into each field you are injecting data into instead of using the “Tab” or “Return” buttons. During a scan, the engine will replay the macro and then look for the patten from the "Advanced Options > Logged-in Regex" field in the page on your screen. Once AppSpider confirms that the authentication was successful, it will move forward with the scan.
If the indicator for a logged-in state is hidden under a menu item, expand it so that AppSpider can examine it and check the logged-in state. This is especially important if your application is built using modern frameworks such as Angular, React or Ember. Often times these frameworks will render these fields using javascript which can not be seen within the Document Object Model (DOM). If you are having issues with getting the “Logged-in Regex” to work we recommend that you enable traffic logs and inspect the html response returned at the end of the macro. This will allow you to see what the scanner is seeing and help you create a regex that will work.
- Close the Browser Macro Recorder tool and return to the Scan Config wizard.
- Optionally, you can test the macro by replaying it using the Test button.
- If your macro does not work correctly and you wish to debug it, you can select the Display Macro Replay checkbox. During the scan, a browser window will open and show you all the steps carried out by AppSpider while replaying your macro. This will let you figure out where the engine runs into trouble and you can fix your macro recording accordingly.
- Determine whether the Chrome or Internet Explorer browser displays your website correctly, and select the respective entry from the Browser dropdown. The default browser is Chrome.
Note
The Browser setting configures the browser used for playback of the macro. If you wish to change the browser used for recording the macro, click the Options menu of the Menu Bar and go to Options > Environment > Macro Recording > Browser Engine.
HTTP Authentication
The HTTP protocol supports authentication using a username and password. You can use this reference article to learn more about HTTP Authentication: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/understanding-http-authentication
AppSpider supports the Basic, NTLM, and Kerberos protocols for HTTP authentication. If your target app uses HTTP authentication, you can configure the authentication process using the following steps:
- Open the Authentication > HTTP Authentication tab.
- Select the Site requires HTTP authentication (Basic, NTLM, or Kerberos) checkbox to enable HTTP authentication.
- Enter your Username and Password in the respective fields. If the username and password are the same as those entered in the Simple Form Authentication section, enable the Use Form credentials checkbox.
Note
NTLM authentication will require the user account's domain and username, both of which are case sensitive. Forgetting to include the domain or using the incorrect case will cause the authentication action to fail
Multi-factor authentication
Many modern web applications use security measures like two-factor authentication that require manual intervention for logging in to the application. For example, suppose your application requires you to enter a one time password sent to you via SMS, or the text in a CAPTCHA box. You can use multi-factor authentication in these cases.
During the scan, a browser window will open and allow you to manually guide the scanner to the login area and complete all the steps to log the scanner into the web site. After the login process has been completed, AppSpider can continue scanning your application for vulnerabilities in an automated fashion. If the scan engine gets logged out during the scan, it will trigger multi-factor authentication to re-authenticate in to the application. In this case, a browser window will pop up again so you can manually log in to the application. You can use the following steps to configure multi-factor authentication:
- Open the Authentication > Multi-factor tab.
- Select the Allow Multi-factor checkbox.
- Set the amount of time in seconds that you feel you will require for logging in to your application. The default value is 60 seconds.
Note
During the scan, carry out only the steps required for logging into the application. After the login process is completed, leave the browser window open as AppSpider will close it automatically. AppSpider will look for the patten from the "Advanced Options > Logged-in Regex" field in the web page open in the browser. If the indicator for logged-in state is hidden under a menu item, expand it so that AppSpider can examine it and check the logged-in state. Once it confirms that the authentication was successful, it will move forward with the scan.
Selenium Script Authentication
Selenium is a framework for automated testing of web applications. Users can record actions like entering data in forms and clicking buttons using Selenium and replay them on demand to ensure that the web application behaves as desired.
AppSpider supports authentication using Selenium files, so you can record the actions needed to log in to your application in a Selenium script. During the scan, AppSpider can replay the actions in this script to log in to the web application.
Use the following steps to authenticate with a Selenium script:
- Open the Authentication > Selenium Script Authentication tab.
- Select the Use Selenium script (for Form Authentication) checkbox.
- Select the Web Driver (reference: https://www.seleniumhq.org/docs/03_webdriver.jsp) for your Selenium script. AppSpider is installed with the Chrome webdriver which will be used by default.
- Click the ellipsis (...) button next to the Selenium Script File text box. This opens the file explorer. Navigate to a Selenium file of a supported format and select it.
- Optionally test the Selenium script authentication by replaying it using the Test button. If authentication is successful, you will see a popup that says "Selenium Login executed successfully".
The following are some examples of Selenium authentication scripts in different formats:
Note
You must use port 32768 for Selenium authentication scripts.
HTML - Selenium Script
xml
1<?xml version="1.0" encoding="UTF-8"?>2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">4<head profile="http://selenium-ide.openqa.org/profiles/test-case">5<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />6<link rel="selenium.base" href="http://webscantest.com/" />7<title>selenium</title>8</head>9<body>10<table cellpadding="1" cellspacing="1" border="1">11<thead>12<tr><td rowspan="1" colspan="3">selenium</td></tr>13</thead><tbody>14<tr>15<td>open</td>16<td>/</td>17<td></td>18</tr>19<tr>20<td>clickAndWait</td>21<td>link=Login</td>22<td></td>23</tr>24<tr>25<td>type</td>26<td>name=login</td>27<td>admin</td>28</tr>29<tr>30<td>type</td>31<td>name=passwd</td>32<td>admin</td>33</tr>34<tr>35<td>clickAndWait</td>36<td>name=submit_login</td>37<td></td>38</tr>39</tbody></table>40</body>41</html>4243
Jar - Java Selenium Script
java
1package automationFramework;23import java.util.concurrent.TimeUnit;4import org.openqa.selenium.By;5import org.openqa.selenium.Keys;6import org.openqa.selenium.Proxy;7import org.openqa.selenium.WebDriver;8import org.openqa.selenium.chrome.ChromeDriver;9import org.openqa.selenium.chrome.ChromeOptions;1011public class TestCase {12public static void main(String[] args) throws InterruptedException {13ChromeOptions options = new ChromeOptions();14Proxy proxy = new Proxy();15proxy.setHttpProxy("127.0.0.1:32768");16proxy.setSslProxy("127.0.0.1:32768");17options.setProxy(proxy);18WebDriver driver = new ChromeDriver(options);19driver.manage().timeouts().implicitlyWait(60,TimeUnit.SECONDS);20driver.navigate().to("http://webscantest.com/login.php");21driver.findElement(By.cssSelector("input[name=login]")).sendKeys("admin");22driver.findElement(By.cssSelector("input[name=passwd]")).sendKeys("admin");23driver.findElement(By.cssSelector("input[name=passwd]")).sendKeys(Keys.ENTER);24Thread.sleep(3000);25driver.quit();26}27}
Exe - C# Selenium Script
csharp
1using System;2using OpenQA.Selenium;3using OpenQA.Selenium.Support.UI;4using OpenQA.Selenium.Chrome;5//username test_user6//password 1234567namespace Selenium_Demo8{9class Program10{11static void Main(string[] args)12{13string URL = "http://hackazon.webscantest.com/user/login";14ChromeOptions options = new ChromeOptions();15ChromeOptions headlessOptions = new ChromeOptions();16string appSpider_port = "32768";17Proxy proxy = new Proxy18{19HttpProxy = "127.0.0.1:" + appSpider_port,20SslProxy = "127.0.0.1:" + appSpider_port21};22options.Proxy = proxy;23headlessOptions.Proxy = proxy;24//THIS CHECKS IF THE LOGIN SCRIPT IS RUNNING IN APPSPIDER OR NOT (CHROME ONLY)25headlessOptions.AddArguments("headless");26IWebDriver driver = new ChromeDriver(headlessOptions);27driver.Url = URL;28if (driver.PageSource.Equals("<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body></body></html>"))29{30options.Proxy = null;31}32driver.Quit();33//THIS CHECKS IF THE LOGIN SCRIPT IS RUNNING IN APPSPIDER OR NOT (CHROME ONLY)34driver = new ChromeDriver(options);35driver.Url = URL;36driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(60);37////GATHER YOUR ELEMENTS38IWebElement userName = driver.FindElement(By.Id("username"));39IWebElement password = driver.FindElement(By.CssSelector("input[placeholder='Password']"));40////GATHER YOUR ELEMENTS41////EXECUTE THE LOGIN42userName.SendKeys("test_user");43password.SendKeys("123456");44password.SendKeys(Keys.Enter);45////EXECUTE THE LOGIN46////WAIT FOR AN ELEMENT THAT APPEARS WHEN YOU'RE LOGGED IN47IWebElement loggedInElement = driver.FindElement(By.LinkText("Logout"));48////WAIT FOR AN ELEMENT THAT APPEARS WHEN YOU'RE LOGGED IN49driver.Quit();50}51}
Proxy Log Authentication
You can authenticate into your applications using a web proxy tool such as the Traffic Recorder. Using the proxy tool, you can record the interactions (e.g. HTTP GET and POST requests) between the front end application and the back end server in a proxy file. AppSpider can replay these interactions to authenticate into your application. Proxy log files can be of the following formats:
- AppSec toolkit Traffic Files (*.trec)
- Burp Files (*.xml)
- Paros Files (*.txt)
- WebScarab Files (conversationlog)
- HAR (HTTP Archive) Files (*.har)
- Fiddler Files (*.saz)
Use the following steps to authenticate with a Traffic file:
- Open the Authentication > Macro Authentication tab.
- Select the Use Proxy Log (for Form Authentication) checkbox.
- If you do not have a proxy file already, use the Traffic Recorder tool to record the interactions involved in the login process.
- Click the ellipsis (...) button beside the Proxy Log File textbox. This will open the file explorer. Navigate to a proxy file of a supported format and select it.
- Optionally test the proxy log authentication by replaying it using the Test button. If authentication is successful you will see a popup that says "Proxy Login executed successfully".
Session Hijacking
If your web application uses session cookies for maintaining a logged-in state, you can capture this cookie and use the Session Hijacking method for authentication. Use the following steps to set up this authentication method:
- Capture the session cookies related to authentication using your browser’s developer tool.
- Open the Authentication > Session Hijacking (relogin not supported) tab.
- Select the Session Hijacking checkbox.
- Click the Utilize Captured Session Cookie link. The “Session settings” window will appear.
- Enter the session cookie from step 1 in the Session Cookie field. Separate multiple cookies with a semicolon. For example, consider the following cookies captured from http://webscantest.com:
- If these cookie values need to be maintained throughout the scan, you can select the Lock cookie values for duration of scan checkbox. You can apply this setting to all cookies using the Apply to all cookies checkbox, or enter specific cookies in the table.
- Click Ok to return to the “Authentication” screen.
This is the least preferred authentication method, since the scanner cannot re-authenticate in case it loses the session during the scan.
OAUTH
OAuth (https://oauth.net/) is an authorization method that is used by applications to grant fine grained access to clients. AppSpider supports OAuth 2.0 which is the industry-standard protocol for authorization. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices. If your application has granted AppSpider the access to certain capabilities, you can enter the required details in the Authentication > OAUTH tab. When starting a scan, AppSpider can provide these details to your application and receive an access token.
Depending on your use case, you will need to use a different OAuth flow. The “grant type” property determines the OAuth flow that your application is using. You can learn more about grant types here: https://oauth.net/2/grant-types/.
AppSpider supports the following grant types:
The following chart can help you choose the appropriate grant type for your application.
Set Up OAuth Authentication
If you want to scan an application that uses OAuth, you will need to know the grant type used by your application. You can usually get this information from your application developers. If you examine the traffic from a connection, you can also often see the grant type in the URL.
The Authentication > OAUTH screen has a number of options to configure your application's OAuth properties. You will need to select the OAuth enabled option to enable OAuth authentication, and then provide the required values based on your grant type.
- Resource Server URL - The identifier for your API server. The resource server handles authenticated requests after the application has obtained an access token
- Authorization Server URL - The authorization server URL, obtained from your identity provider (reference: https://en.wikipedia.org/wiki/Identity_provider)
- Redirect URI - The URL that the authorization server will redirect the user back to, with an authorization code or access token in the URL. Resource Server URL will be used if empty
- Client Scope - One or more space-separated strings indicating which permissions the application is requesting. The specific OAuth API you’re using will define the scopes that it supports
- Client Id - The public identifier for the application, obtained from your identity provider
- Client Secret - The application’s client secret, obtained from your identity provider. This ensures that the request to get the access token is made only from the application
- Client State - The application generates a random string and includes it in the request. It should then check that the same value is returned after the user authorizes the app. This is used to prevent CSRF attacks
- Username - The username of the end user in case of using the “Resource Owner Password Credentials” or “Client Credentials” grant types
- Password - The password of the end user in case of using the “Resource Owner Password Credentials” or “Client Credentials” grant types
OAuth Grant Types
The following sections describe which OAuth properties you need to provide to AppSpider based on your grant type.
Authorization Code
The Authorization Code grant type is used by web and mobile apps. It differs from most of the other grant types by first requiring the app launch a browser to begin the flow. At a high level, the flow has the following steps:
- The application opens a browser to send the user to the OAuth server
- The user sees the authorization prompt and approves the app’s request
- The user is redirected back to the application with an authorization code in the query string
- The application exchanges the authorization code for an access token
The Authorization Code flow is best used by server-side apps where the source code is not publicly exposed. The apps should be server-side because the request that exchanges the authorization code for a token requires a client secret, which will have to be stored in your client. The server-side app requires an end-user, however, because it relies on interaction with the end-user’s web browser which will redirect the user and then receive the authorization code. See https://developer.okta.com/authentication-guide/auth-overview/#authorization-code-flow and https://developer.okta.com/authentication-guide/implementing-authentication/auth-code for more information.
Mandatory properties
- Resource Server URL
- Client Id
Implicit
The Implicit grant type is a simplified flow that can be used by public clients, where the access token is returned immediately without an extra authorization code exchange step.
It is generally not recommended to use the implicit flow (and some servers prohibit this flow entirely). In the time since the spec was originally written, the industry best practice has changed to recommend that public clients should use the authorization code flow with the PKCE extension instead.
Mandatory properties
- Resource Server URL
- Client Id
NOTE: PKCE is not supported yet
Resource Owner Password Credentials
The resource owner password credentials grant type is suitable in cases where the resource owner has a trust relationship with the client, such as the device operating system or a highly privileged application. The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable. See https://tools.ietf.org/html/rfc6749#4.3 for more information.
Mandatory properties
- Resource Server URL
- Username
- Password
Client Credentials
The Client Credentials grant is used when applications request an access token to access their own resources, not on behalf of a user. The client needs to authenticate themselves for this request. Typically the service will allow either additional request parameters Client Id and Client Secret, or accept the Client Id and Client Secret in the HTTP Basic auth header.
Mandatory properties
- Resource Server URL
Additional OAuth Properties
In addition to the properties in the OAuth section of the Authentication screen, there are some Advanced Options that can be helpful to configure the OAuth flow for your application.
- Resource Owner URL - An entity capable of granting access to a protected resource. Optional, in most cases should be equal to Resource Server URL
- UsernameForm/PasswordForm - The username and password for additional form authentication flow on the application
- ExtensionGrant - Can be ignored at this moment
- AuthorizationGrantType - Digital representation of the supported grant types
- NeverDoBasicAuth - Prevents AppSpider from sending HTTP Basic authentication header (base65 encoded Username and Password values) in case of using “Resource Owner Password Credentials” or “Client Credentials”. Enabled by default (value is 0)
- JsonPostBodies - To support JSON format on OAuth Authorization Server requests and responses
- Azure* - All properties with Azure at the beginning are obsolete and should not be used
- OAuthCustomField - To support any additional parameters that should be sent to the Authorization Server
Note
In most cases, except the Implicit grant type, OAuth authentication can be bypassed using a macro. If you are having trouble configuring OAuth with AppSpider, you should try Macro authentication.
SSL Certificates
You may need to authenticate your application on the client side so you can scan pages found behind your SSL. This authentication method can be used with both cloud and on-premise scan engines.
PFX Certificate Format
The SSL Certificate must be a .pfx file.
Configure SSL authentication
- Go to Authentication > SSL.
- In the Type dropdown, choose Certificate.
- Choose your SSL .pfx file.
- Optional: If a password is required, enter it in the provided box.
ADAL
You can authenticate your InsightAppSec scans using the Azure Active Directory Authentication Library (ADAL).
Configure ADAL
To configure ADAL authentication, you must go to Authentication > ADAL screen in the scan config wizard, and set the following options:
- Resource ID - This will depend on your Azure Active Directory (AD) usage. If you are using an Azure Native AD, this should be one of two defaults, either graph.windows.net or graph.microsoft.com. If you are not using a native Azure AD, your AD admin may be able to help you get the correct ID for your instance.
- Tenant - The domain name of your Azure AD tenant, such as example.onmicrosoft.com. This can be found on the Azure Active Directory overview screen.
- Client ID - The Application (client) ID under the app that you have registered.
- Authority URL - Defaults to https://login.microsoftonline.com/ so if left blank this is what will be passed up.
- Username - If you are using the Client ID, Username, and Password authentication flow, this will be the username for your account.
- Password - The password is not the password of your user account, instead it's the secret key that is created under the 'Certificate & secrets' section. You can use ADAL in conjunction with OAuth as your authentication protocol (Reference: https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-implicit-grant-flow).
HMAC
HMAC is a MAC (Message Authentication Code) that uses a cryptographic hash function and a secret key to authenticate. To learn more about HMAC, see https://en.wikipedia.org/wiki/HMAC.
Configure HMAC authentication
- Go to the Authentication > HMAC.
- Use the toggle button to Enable HMAC.
- Enter the following information:
Username - The username for your hash algorithm.
Secret Key - A unique code used to compute the HMAC. It is known by both the sender and receiver.
Hash Algorithm - Choose the hash algorithm type.
- Md5
- Sha1
- Sha256
Header Generation DLL Filename - A user created DLL file, which contains the cryptographic hash function. This is only needed if using an on-premise engine. If you don’t provide a file, they system will use the DLL provided by the engine.
HMAC Header Generation
The HMACHeaderGenerator.dll that ships with AppSpider is the default one used for HMAC header generation. It is coded as a .dll so that 3rd parties who want to use a custom scheme for generating HMAC headers can write a custom .DLL for that purpose and then configure AppSpider to use it instead of the default HMACHeaderGenerator.dll.
In an HMAC configured scan, AppSpider uses the HMAC .dll to generate headers that are included in every request it generates.
The following 3 data structures are necessary for passing data in/out of the HMAC functions. They are coded specifically to be as simple as possible with regard to minimising disparities in memory allocation between the main process and the .dll:
1template <typename T> struct FUNCTORIZER2{3bool (*m_pfnCompareOrOrder)(const T& o1, const T& o2);4// ---5inline FUNCTORIZER(bool (*pfnCompareOrOrder)(const T& o1, const T& o2)) :6m_pfnCompareOrOrder(pfnCompareOrOrder)7{8}9inline bool operator()(const T& o1, const T& o2) const10{11return m_pfnCompareOrOrder(o1, o2);12}13};
1template <typename T> struct SIMPLELIST2{3template <typename T> inline static void PlacementDestructor(T& p)4{5p.~T();6}7// ---8SIMPLELIST<T> *m_plNext;9T m_tObject;10// ---11inline SIMPLELIST<T>() :12m_plNext(nullptr)13{14}15inline SIMPLELIST<T>(const SIMPLELIST<T>& o) :16m_plNext(nullptr)17{18operator=(o);19}20inline SIMPLELIST<T>(const T& tObject) :21m_plNext(nullptr),22m_tObject(tObject)23{24}25inline ~SIMPLELIST<T>()26{27Reset();28}29inline void Reset()30{31SIMPLELIST<T> *plCurrent,32*plNext;3334plNext = m_plNext;35while (plNext)36{37plCurrent = plNext;38plNext = plCurrent->m_plNext;39plCurrent->m_plNext = nullptr;40// ---41PlacementDestructor<SIMPLELIST<T> >(*plCurrent);42free(plCurrent);43}44m_plNext = nullptr;45}46inline SIMPLELIST<T>* First()47{48return m_plNext;49}50inline SIMPLELIST<T>* Next()51{52return m_plNext;53}54inline bool Add(const T& tObjectToCopy)55{56SIMPLELIST<T> *plThat;5758plThat = this;59while (plThat->m_plNext)60{61plThat = plThat->m_plNext;62}63plThat->m_plNext = new SIMPLELIST<T>(tObjectToCopy);64if (plThat->m_plNext)65{66plThat = plThat->m_plNext;67// ---68return true;69}70// ---71return false;72}73inline T* AddAtHead(const T& tObjectToCopy)74{75SIMPLELIST<T> *plThat;7677plThat = m_plNext;78m_plNext = (SIMPLELIST<T>*)malloc(sizeof(SIMPLELIST<T>));79new(m_plNext) SIMPLELIST<T>(tObjectToCopy);80if (m_plNext)81{82m_plNext->m_plNext = plThat;83// ---84return &m_plNext->m_tObject;85}86m_plNext = plThat;87// ---88return nullptr;89}90inline T* AddUnique(const T& tObjectToCopy, bool (*pfnCompare)(const T& o1, const T& o2), bool bFailIfExists = false)91{92return AddUnique(tObjectToCopy, FUNCTORIZER<T>(pfnCompare), bFailIfExists);93}94template <typename FUNCTOR> inline T* AddUnique(const T& tObjectToCopy, FUNCTOR& pfnCompare, bool bFailIfExists = false)95{96SIMPLELIST<T> *plThat;9798plThat = this;99while (plThat->m_plNext && !pfnCompare(plThat->m_plNext->m_tObject, tObjectToCopy))100{101plThat = plThat->m_plNext;102}103if (plThat->m_plNext)104{105if (!bFailIfExists)106{107// Leave the old one alone and return pointer to it.108return &plThat->m_plNext->m_tObject;109}110}111else112{113plThat->m_plNext = (SIMPLELIST<T>*)malloc(sizeof(SIMPLELIST<T>));114new(plThat->m_plNext) SIMPLELIST<T>(tObjectToCopy);115if (plThat->m_plNext)116{117return &plThat->m_plNext->m_tObject;118}119}120// ---121return nullptr;122}123};
1struct STRINGPAIR2{3TCHAR m_szFirst[1024],4m_szSecond[1024];5// ---6STRINGPAIR()7{8}9STRINGPAIR(LPCTSTR szFirst, LPCTSTR szSecond)10{11_tcscpy_s<sizeof(m_szFirst)/sizeof(*m_szFirst)>(m_szFirst, szFirst);12_tcscpy_s<sizeof(m_szSecond)/sizeof(*m_szSecond)>(m_szSecond, szSecond);13}14};
Replacing the default DLL
The following functions must be implemented in any .dll that will replace the default HMACHeaderGenerator.dll.
Get last error
Any error or exceptional condition that is informative to the user generated by the following functions should be stored in a global variable and returned by this function. AppSpider will report the error the same way it does with any errors.
1extern "C" int __declspec(dllexport) WINAPI GetLastHMACError(IN int nSizeofError, OUT LPSTR szError)2{3// nSizeofError = size limit of szError.4// szError = pointer to character buffer to receive the error.5}
Generate header
This is the core function for generating the HMAC HTTP headers.
1extern "C" bool __declspec(dllexport) WINAPI GenerateHMACHeader(IN ALG_ID eHashAlgorithm, IN LPCWSTR wszHttpVerb, IN DATE dtExpireDate, IN LPCWSTR wszUrl, IN LPCWSTR wszUsername, IN LPCWSTR wszSecretKey, IN BYTE* pbtContent, IN DWORD dwContentLength, OUT SIMPLELIST<STRINGPAIR>& lpszHeaders)2{3// Here is a code sample for populating lpszHeaders:4lpszHeaders.Add(STRINGPAIR("CustomHMACField1", szValue1));5lpszHeaders.Add(STRINGPAIR("CustomHMACField2", szValue2));6// If szValue1 = "foo" and szValue2 = "bar" then resulting HTTP requests will7// be something like this:8GET /somepage.html HTTP/1.19Host: server.example.com10CustomHMACField1: foo11CustomHMACField2: bar12<other headers>13}
ALG_ID is from wincrypt.h and specifies the crypto hash algorithm to use. In a custom implementation, it can be whatever is desired including ignoring it, e.g. a scenario in which MD5 is always used. The rest of the input parameters are combined in the standard HMAC way in HMACHeaderGenerator.dll to generate headers "Authorization" and "Date" and their values in lpszHeaders. Similarly, any custom scheme would take the input parameters (algorithm, date, the string parameters and optionally, binary content (pbtContent, dwContentLength) and combine them as prescribed by the custom approach to create however many name-value pairs in lpszHeaders are desired, which AppSpider will then include in the request headers when crawling and attacking.
Clear headers list
1extern "C" void __declspec(dllexport) WINAPI FreeTheHeadersList(IN SIMPLELIST<STRINGPAIR>& lpszHeaders)2{3// Free lpszHeaders using the same scheme GenerateHMACHeader() used4// to allocate it. Likely simply lpszHeaders.Reset().5}
Generate arbitrary headers (NOT USED)
1extern "C" bool __declspec(dllexport) WINAPI GenerateArbitraryHeaders(IN SIMPLELIST<STRINGPAIR>& lpszInputs, OUT SIMPLELIST<STRINGPAIR>& lpszHeaders)2{3// This function is currently not used. It was written in anticipation4// of future functionality. The stub should however be included in any5// custom HMAC .dll.6}
Advanced Settings
While attempting authenticated scanning of an app, AppSpider needs a way to learn that authentication has been successful. It attempts to deduce the logged-in state of the app by examining the headers and body of web pages. The fields in the Authentication > Advanced tab can be used to train AppSpider to recognize the logged-in state of your application. You can use the Regex Builder to test your regular expressions before using them in AppSpider.
- Configure SSL certificate link - Opens SSL configuration window where user may configure the SSL certificate
- Logged-in Regex - If the text on your page matches this regular expression, AppSpider assumes that you are still logged in. This regex usually matches the "Sign out" link, since the sign-out option is only available if the user is still logged in.
- Assume Good Login - You may sometimes be unable to find a regex that matches the logged-in state of the app. There may be multiple login links leading to different areas of the product, and AppSpider might be attempting the same credentials everywhere leading to account lockouts. You can enable the Assume Good Login checkbox to instruct AppSpider not to check for logged-in state after the initial log in.