Skip to main content

Scan APIs

Use Dynamic Analysis in the Veracode Platform, or using the REST API, to test the security of your REST API specifications or Postman Collections. You can also integrate the analysis with your development pipeline. The scans crawl and analyze the endpoints in an API specification file or the requests in a Postman Collection. The results identify the vulnerabilities you might need to resolve.

For an improved experience, we recommend using DAST Essentials. See the quickstart.

In the Veracode Platform, you create a Dynamic Analysis and upload or select the API specification or Postman Collection you want to analyze. An analysis can contain a maximum of 250 specifications. To learn about API specification support, see How we process API specifications.

If you want to scan an API but don't have an OpenAPI or Postman specification, you can create an HTTP Archive (HAR) file using a free tool, such as Chrome Developer Tools. To reduce extraneous traffic, such as third-party traffic, select Fetch/XHR to apply filtering before exporting the HAR.

Create an analysis

Create an analysis in the Veracode Platform to perform a Dynamic Analysis of the following:

  • Endpoints in one or more API specifications.
  • Requests in one or more Postman Collections.

You can also create an analysis using the REST API.

Before you begin:

note

You can only link one application profile to an API scan or web application scan. Also, you cannot use the same analysis for both API and web application scans.

To complete this task:

  1. Sign in to the Veracode Platform.

  2. Select Scans and Analysis > Dynamic Analysis.

  3. Select Scan API Specifications. The Create page opens.

  4. For Dynamic Analysis Name, enter a name for this analysis. Ensure the name is unique to your organization and provides a human-readable description of the analysis.

  5. For API Specifications, select Options. Then, select to upload a new API specification to scan or select an existing API specification. You only need to upload a new specification one time, and it remains available to other analyses. The specification is also available on the API Specification Management tab on the Dynamic Analysis page.

  6. For a new API specification, in the Upload API Specification window, select Choose File.

  7. Locate and select a valid API specification file. If you do not enter a name for the API specification, by default, the Veracode Platform uses the filename of the uploaded specification. Depending on the size of your specification file, the upload might take several seconds to complete. Also, the Veracode Platform shows messages about any issues with the specification, such as unsupported file format, invalid syntax, or an issue with the relative URL.

  8. To add the specification to your analysis, select Add to Analysis. Your analysis is listed in the API Specifications to Scan table.

  9. To add additional specifications to the same analysis, repeat steps 5-8.

  10. To link the analysis and the scan results to an application profile, in the API Specifications to Scan table, in the Actions column, select Link link_icon.png. Then, select an application profile and select Link. The name of the linked application profile appears in the Application Name column.

  11. Optionally, to configure a user agent string that the scanners add as a header to each API request, select Dynamic Analysis User Agent. For Browser, select one of the following:

    • API Scan Default: accept the default string. Veracode identifies as the originator of the scan with Veracode Security Scan/[email protected].
    • Custom: add your custom string to User Agent.

    Compared to the user agent string for web application scanning, this string does not include browser information. You can use this string to exempt Web Application Firewall (WAF) blocking or suppress pager notifications in an Intrusion Prevention System (IPS). For information about the solution for your organization, see your vendor documentation.

  12. Optionally, under Visibility Settings, select which user roles or teams can access this analysis and the scan results.

  13. Optionally, under Organization Information, enter information specific to your organization.

  14. To certify that your organization has the required permissions to scan the specifications added to this analysis, under Scanning Certification, select the checkbox.

  15. To schedule the analysis, including whether to run a prescan, select Schedule.

    By default, your Dynamic Analysis is not scheduled. To review the schedule of any Dynamic Analysis, select the clock icon in the row for that Dynamic Analysis on the All Dynamic Analyses page.

    To verify that Veracode can successfully reach and, if required, authenticate with the target API server, a prescan scans all endpoints or requests in the specification. If you do not want to schedule the analysis, select Review and Submit and Save. To review the schedule of any Dynamic Analysis, select the clock icon in the row for that Dynamic Analysis on the All Dynamic Analyses page.

    note

    Because Dynamic Analysis scans API specifications quickly, We recommend that you do not schedule the analysis to automatically pause and resume.

  16. Configure and run the analysis.

Configure an analysis

After you create an analysis, configure specific scan settings, such as the target API server, the server authentication method, and, if the server is behind a firewall, an Internal Scanning Management (ISM) gateway and endpoint.

Before you begin:

Before you begin, you must have created an analysis for the API you want to scan.

To complete this task:

  1. Sign in to the Veracode Platform.

  2. Select Scans and Analysis > Dynamic Analysis.

  3. In the All Dynamic Analyses table, locate the analysis that references the API specification you want to configure.

  4. In the Actions column, select Configure Analysis.

  5. In the API Specifications to Scan table, locate the specification you want to configure.

  6. In the Actions column, select Configure. The Configure window opens.

  7. Under API Specification Information, for Server, select the URL of the server you want to use with this specification. OpenAPI 2.0 specifications and Postman Collections only support a single server, while OpenAPI 3.1 or 3.0 specifications and HAR files support multiple servers. If you are scanning a HAR file that you captured using a browser, but you have not filtered the HAR file, ensure that the correct server is selected. The scanners attempt to select the correct server by analyzing network traffic in the HAR file.

  8. To open the Endpoints (OpenAPI or HAR) or Requests (Postman Collections) table, select the server name in bold. The table lists all endpoints or requests in the specification.

  9. In the Endpoints or Requests table, under Scope, select from the following options:

    • Include: include the endpoint or request in the scan. By default, all endpoints or requests are included.
    • Exclude: exclude the endpoint or request from the scan. The scanners do not send requests to excluded endpoints or requests.
    • Ignore: for Postman Collections only, send the request during the scan, but do not detect vulnerabilities for it. The scanners only send the request and run any pre- or post-processing in the Postman Collection. For example, you might want to ignore a request that you do not want to scan, but that request is a dependency of another request that you do want to scan.
  10. To configure authentication methods that the scanners use to access the selected server, under Authentication, for Authentication required, select Required.

  11. Optionally, to define variables that you can reference in a login script, select Scanner Variables. Then, add a reference key and value for a variable. If a variable is for multifactor authentication (MFA), select TOTP seed and ensure the reference key value matches the reference key in your login script. You can also configure this setting with the REST API.

  12. Optionally, for Postman Collections, to block or exclude requests to target URLs, select URL-Specific Blocklist and Ignorelist. The scanners send requests to these URLs, but the URLs are not included in the scan. Then, select from the following:

    • BLOCKLIST: to send all requests to any URLs, select Do not exclude any specific URLs (the default). To block requests to a URL, select Exclude the following URLs and enter the URL. To add additional URLs, select Add URL.
    • IGNORELIST: to send all requests to any URLs, but not include the requests in the scan, select Do not ignore any specific URLs. To ignore a request based on a target URL, select Ignore the following URLs and enter the URL. To add additional URLs, select Add URL.

    Any requests that are blocked in the Requests table take precedence over the blocklist and ignorelist. For example, if you block a request in the Requests table and add a target URL for that request to an ignorelist, or you don't block any target URLs, that request is blocked and excluded from the scan. Conversely, if you include or ignore a request in the Requests table and add a target URL for that request to a blocklist, that request is blocked and excluded from the scan.

  13. To select an Internal Scanning Management (ISM) gateway and endpoint, select Internal Scanning. Then, select a gateway and endpoint. The scanners use ISM to access internal servers that are behind a firewall or not exposed to the public internet.

  14. To save the configuration, select Save. A prescan or full Dynamic Analysis runs on the configured schedule.

After the analysis completes, we recommend linking the results to the related application profile. With the results linked, you can access results from multiple scan types for the same application, and review aggregated results from all scans in the Dynamic Analysis Coverage Report If you ran a prescan, learn more about prescan results for API scans.

Authentication

This section explains the following authentication methods you can use when configuring an analysis.

Client Certificate

Use for authenticating with servers configured with TLS authentication. The scanners respond to any client certificate requests for certificates from a matching issuer with the configured certificate. Ensure the file format of the certificate is PKCS#12, which usually has a .pfx or .p12 extension. Also, you must specify a passphrase that decrypts the private key in the .p12 file.

Basic Authentication

Use basic and NTLMv2 authentication for authenticating with internal servers. API specifications that use basic authentication typically have scheme: basic defined in their OpenAPI definitions. For example, in OpenAPI 3.0:

components:
securitySchemes:
basicAuth:
type: http
scheme: basic # specifies to use basic authentication.

Custom HTTP Header

Common type of authentication for scanning APIs. You can define one or more name/value pairs. When defining the name, do not add any trailing colons. Values typically do not include a colon, but this is legal according to the RFC. You cannot use these reserved header names:

  • Accept-Charset
  • Accept-Encoding
  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Connection
  • Content-Length
  • Cookie
  • Cookie2
  • Date
  • DNT
  • Expect
  • Host
  • Keep-Alive
  • Origin
  • Referer
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrading
  • Via

Custom headers in OpenAPI specifications use apiKey or bearerAuth security scheme types. Because authentication might occur at a different layer of the solution, such as through an API gateway, you might not need to add it to the API specification. Ensure you check with the development team that created the specification to confirm the authentication solution.

This example shows a custom header with the name X-API-KEY:

openapi: 3.0.0
...
components:
securitySchemes:
ApiKeyAuth: # arbitrary name for the security scheme
type: apiKey
in: header # can be "header" or "cookie"
name: X-API-KEY # name of the header, query parameter, or cookie

This example shows a JWT bearer token:

openapi: 3.0.0
...
components:
securitySchemes:
bearerAuth: # arbitrary name for the security scheme
type: http
scheme: bearer
bearerFormat: JWT

You can configure this token as a custom header with name Authorization and value Bearer $JWT_CONTENT, where $JWT_CONTENT is a series of period-delimited, base64-encoded JSON fragments.

OAuth 2.0

Authenticate with servers that require the OAuth 2.0 protocol. Dynamic Analysis supports both the Client Credentials and Password Credentials grant types, which you can select from the Grant Types dropdown menu. For both grant types, a scope is optional. If you need to enter multiple scope values, separate each value with a space. Veracode sends all authorization data as an HTTP Authorization Header.

If you select the Client Credentials grant type, you can select the Use OpenID Connect checkbox to use OAuth 2.0 with OpenID Connect. After selecting the checkbox, enter the URL for the authentication server in the OpenID Connect URL field.

Scriptable Request Modification

Use a plain text JavaScript file to provide logic that can modify an HTTP request at runtime. Example modifications include changing the request URI, HTTP headers, or the request body.

After uploading your JavaScript file to the Veracode Platform, we recommend running a prescan() to ensure that:

  • Your script is free of errors. The Veracode Platform alerts you to any errors in your script.
  • Your authentication credentials are valid.
  • The Veracode Platform can use the script to successfully make requests to the target host.

We provide example scripts for modifying request authentication.

Add one or more HTTP cookies that the scanner can use to authenticate with the target server. For Cookie, enter the cookie data. For example, mycookie=chocolate; domain=veracode.com. To add additional cookies, select Add Another.

Scanner Variables

Configure scanner variables in the Veracode Platform to define information that you can reference in your login scripts for web application scans. The variables consist of a reference key and value. You typically create scanner variables that define sign in credentials you want to keep safe and reuse in multiple scripts.

To indicate that the variable defines a time-based one-time password (TOTP) secret for multifactor authentication, select TOTP seed. For more information, see Configure scanner variables.

Internal Scanning

If scanning an internal web application behind a firewall, select the ISM gateway and the associated endpoint that can access the URL.

If you select a gateway that is not associated with an accessible ISM endpoint, or the endpoint isn't ready for scanning, or you select an endpoint that is not reachable by the URL, the Dynamic Analysis fails.

Endpoints are identified as Ready, Pending, or Offline.

Gateway

Select the gateway associated with an endpoint that can access the URL. If you select a gateway that is not associated with an accessible endpoint or is not ready for scanning, the Dynamic Analysis fails.

Endpoint

Select an endpoint that can access the URL. If you select an endpoint that is not reachable by the URL or is not ready for scanning, the Dynamic Analysis fails. The scan identifies the endpoints as Ready, Pending, or Offline.

note

All of your configured gateways and endpoints are available for selection. If you do not know which gateways and endpoints are reachable by the URL, work with your ISM administrators to identify them.

Advanced Options

Expand Advanced Options to configure the following setings.

User Agent

Configure a user agent string that the scanners add as a header to each API request. For Browser, select one of the following:

  • API Scan Default: accept the default string. Veracode identifies as the originator of the request with Veracode Security Scan/[email protected].
  • Custom: add your custom string to User Agent.

Compared to the user agent string for web application scanning, this string does not include browser information. You can use this string to exempt Web Application Firewall (WAF) blocking or suppress pager notifications in an Intrusion Prevention System (IPS). For information about the solution for your organization, see your vendor documentation.

Requests Per Second

Enter the maximum number of requests the scanners send to the selected server every second. For Request Limit, select Unlimited or select Limit to and enter the number of requests.

Manage API specifications

You use the API Specification Management tab in the Veracode Platform to upload, update, and permanently delete your API specifications or Postman Collections.

You can also upload an API specification with the REST API.

Before you begin:

  • You have a Veracode account with the Creator, Submitter, or Security Lead role. Any member of the team associated with the Dynamic Analysis is able to view the analysis and its results.
  • You have removed any API specification you want to update or delete from the associated analyses.

To complete this task:

  1. Sign in to the Veracode Platform.
  2. Select Scans and Analysis > Dynamic Analysis.
  3. Select API Specification Management.
  4. To upload a new API specification, select Upload API Specification. To manage an existing specification, locate it in the API Specification Management table and select from the following actions in the Actions column.
ActionDescription
View API Specification Details eye_icon.pngOpens a read-only window with detailed information about the API scanning configuration for the selected specification. The Associated Analysis field provides a list of analyses to which this specification is associated. You can select an analysis to view additional information, including options for reconfiguring and rerunning an analysis.
Update pencil_icon.pngUpdate the following configuration settings for the selected specification.
  • Rename the specification. If you do not enter a name for the API specification, by default, the Veracode Platform uses the filename of the uploaded specification.
  • Delete the specification file attached to the configuration and replace it with a different file. Depending on the size of your specification file, the upload might take several seconds to complete. Also, the Veracode Platform shows messages about any issues with the specification, such as unsupported file format, invalid syntax, or an issue with the relative URL.
  • For OpenAPI specifications and Postman Collections, you can add or update a custom base URL, which Veracode uses to identify the server to use during scanning. OpenAPI 2.0 and Postman Collection only support a single server, while OpenAPI 3.0 and HAR files support multiple servers. You typically use these servers to select different environments, such as a production instance and a staging environment, or multiple production instances located in different regions.
  • Change the visibility of the specification to either Security Leads only or both Security Leads and specific teams. After you add the specification to an analysis, you cannot change its visibility.
Delete trash_icon.pngPermanently delete the API specification and its configuration settings from Veracode. You cannot undo this action or recover the deleted specification file or its configuration settings.

Next steps:

Associate the API specification to a new or existing analysis.

Remove an API specification from an analysis

You can remove an API specification or Postman Collection from a Dynamic Analysis. Removing the specification only removes its association to the analysis, but it is still available in the Veracode Platform. After you remove a specification, you can associate it to the same or a different analysis.

If you want to permanently delete an API specification, use the API Specification Management tab.

Before you begin:

  • You have a Veracode account with the Creator, Submitter, or Security Lead role. Any member of the team associated with the Dynamic Analysis is able to view the analysis and its results.
  • You have created an analysis.

To complete this task:

  1. Sign in to the Veracode Platform.
  2. Select Scans and Analysis > Dynamic Analysis.
  3. In the All Dynamic Analyses table, locate the analysis from which to remove the API specification.
  4. Select the analysis name or select Configure Analysis from the Actions column.
  5. In the Actions column, select Configure Analysis.
  6. In the API Specifications to Scan table, locate the specification you want to remove.
  7. In the Actions column, select Remove Specification from Analysis trash_icon.png.
  8. To confirm the deletion, select OK.

Example scripts for scriptable request modification

When configuring an analysis, you can use the Scriptable Request Modification (SRM) option to upload scripts that modify API requests during authentication with remote hosts. Use the example scripts in this section as a starting point.

After you create the script file, you save it as a plain text JavaScript file and upload it in the Veracode Platform during the scan configuration. When you submit a scan request, Veracode does a one-time evaluation of the script to ensure it is valid and free of any errors.

Script requirements

The scripts have access to standard ECMAScript syntax, which is commonly referred to as JavaScript, but cannot load any external libraries. The scripts can reference and set objects in the global scope and these values are accessible to all requests. For example, a script can define constants that it reuses, or save a value during one request and then retrieve that value during a future request.

Initial function

The script must define one initial function named run() that accepts no parameters and returns no value. At runtime, every request calls this function one time. For example:

function run() {
// modification logic goes here
}

Global object and scope

The script context has a reference to a global object named vc. The vc object contains the values of any user-defined credentials variables within an object named variables. This example extracts the value mapped to a credentials variable with the name API_KEY to a script variable named key:

function run() {
let key = vc.variables['API_KEY'];
}

When the run() function is called, the current request is accessible in the global scope as a variable named request. The script can extract the properties of the request from this object:

function run() {
let headers = request.headers;
let uri = request.uri;
}

Example script for HMAC signing

This example script signs a request with HMAC. To support this script, we provide the Crypto.js library.

Ensure you have read the requirements.

The script contains two credentials variables named key_id and key_secret. For your script, the logic for generating an HMAC header might vary.

const id = vc.variables['key_id'];
const key = vc.variables['key_secret'];

const authorizationScheme = 'VERACODE-HMAC-SHA-256';
const requestVersion = "vcode_request_version_1";
const nonceSize = 16;

function computeHashHex(message, key_hex) {
return CryptoJS.HmacSHA256(message, CryptoJS.enc.Hex.parse(key_hex)).toString(CryptoJS.enc.Hex);
}

function calulateDataSignature(key, nonceBytes, dateStamp, data) {
let kNonce = computeHashHex(nonceBytes, key);
let kDate = computeHashHex(dateStamp, kNonce);
let kSig = computeHashHex(requestVersion, kDate);
let kFinal = computeHashHex(data, kSig);
return kFinal;
}

function newNonce() {
return CryptoJS.lib.WordArray.random(nonceSize).toString().toUpperCase();
}

function toHexBinary(input) {
return CryptoJS.enc.Hex.stringify(CryptoJS.enc.Utf8.parse(input));
}

function calculateVeracodeAuthHeader(request) {
let data = `id=${id}&host=${request.getHost()}&url=${request.uri}&method=${request.method}`;
let dateStamp = Date.now().toString();
let nonceBytes = newNonce(nonceSize);
let dataSignature = calulateDataSignature(key, nonceBytes, dateStamp, data);
let authorizationParam = `id=${id},ts=${dateStamp},nonce=${toHexBinary(nonceBytes)},sig=${dataSignature}`;
let header = authorizationScheme + " " + authorizationParam;
return header;
}

function run() {
let hmacSignedHeader = calculateVeracodeAuthHeader(request);
request.addHeader('Authorization', hmacSignedHeader);
};

The global object named request is available to scripts upon each call to the initial run() function. The following sections describe the functions and properties of this global object.

Request object properties

The following table describes the properties of the request object.

PropertyTypeDescription
methodStringHTTP method for this request. The value is usually a GET or POST, but other common values are PUT, PATCH, and DELETE.
uriStringStandard URI portion of the HTTP request message. The value is the filepath or endpoint of the request, without the host, port, or protocol. For example, a request to the URL https://example.com/path/file.html has a URI of /path/file.html. You can modify the URI to change the target, endpoint, or to add URL parameters.
versionStringVersion of the HTTP request. The value is commonly HTTP/1.1. Veracode does not recommend changing this value.
headersArrayOne or more HTTP headers associated with the current request. The objects in the array are instances of a Header class that has its own properties. You can modify this array as-is or use helper methods on the request object to more easily modify the headers. We recommend that you only use this property for read-only operations.
bodyIntegerBody message for the HTTP request. The body contains a series of bytes encoded in UTF-8, by default, unless the request headers specify a different encoding.

Request object functions

The following table describes the functions, methods, and return type for the request object.

FunctionTypeDescription
getHost()StringReturns the host name of the host receiving the request. A Host header also contains this value. Veracode does not recommend changing the header value because this does not change the target host and it can cause the request to fail.
addHeader(name, value)NullAdds a header to the header array for this request. If a header with the specified name already exists, this method adds an additional header with the same name. Optionally, you can use this method to send multiple headers with the same name.
setHeader(name, value)NullSets a header with the provided name in the header array to the provided value. If one or more headers with the provided name already exists, this function removes the headers before setting this value. For example, if there are multiple headers with the same name, this function removes the headers after a call to this method, and leaves only one header with the given name.
removeHeader(name)NullRemoves all headers with the given name from the header array for this request. If multiple headers with the given name already exist, this function removes all headers with the same name.

Header object properties

The following table describes the properties of the header object.

PropertyTypeDescription
nameStringName of a header.
valueStringValue associated with a header.

Example script for OAuth token authorization

This example script for Scriptable Request Modification (SRM) uses OAuth to authenticate with a target endpoint during an HTTP request. The script is not limited to OAuth and you can configure it to work with other authorization services.

Ensure you have read the requirements.

This script does the following:

  • Creates and sends a request to an access token URL.
  • Parses the response for the returned bearer token.
  • Adds the bearer token as a header on the original request for authentication.
  • Saves the bearer token in the global scope for reuse on subsequent requests to the target URL.
const clientId = "your-client-ID";

var bearerToken = null;

function run() {

if (bearerToken === null) {
let tokenRequest = createTokenRequest();
bearerToken = fetchToken(tokenRequest)
}

updateRequestHeaders(bearerToken);
}

function createTokenRequest() {
let username = "your-OAuth-username";
let password = "your-OAuth-password";
let grantType = "password";

let tokenRequest = httpClient.createRequest("https://your-api/token");
tokenRequest.addHeader("content-type", "application/x-www-form-urlencoded");
tokenRequest.setBody("grant_type=" + grantType + "&client_id=" + clientId + "&username=" + username + "&password=" + password);
tokenRequest.setMethod("POST");

return tokenRequest;
}

function fetchToken(tokenRequest) {
let response = tokenRequest.send();
let message = response.asString();
let parsedBearerToken = JSON.parse(message).access_token;

return parsedBearerToken;
}

function updateRequestHeaders(token) {
request.addHeader("authorization", "Bearer " + token);
request.addHeader("client_id", clientId);
}

In this example, the global object named httpClient is available to scripts upon each call to the initial run() function. The following sections describe the functions and properties of this global object.

HttpClient object function

The following describes the function and return type for the HttpClient object.

FunctionTypeDescription
createRequest(url)ClientRequestReturns a new instance of the ClientRequest class object that sends the request to the target URL. You specify the target URL as a string for the url parameter. To set properties for the ClientRequest object, use the functions in the ClientRequest Object Functions table. Ensure you set the properties on the specific instance of the ClientRequest object that this function returns.

ClientRequest object functions

The following table describes the functions and return type for the ClientRequest object.

FunctionTypeDescription
addHeader(name, value)NullAdds a header to the headers array for this request. Both parameter values are strings. If a header with the specified name already exists, this function adds an additional header with the same name.
setUrl(url)NullSets the URL for this ClientRequest as a string. Typically, the URL is already set when the object is instantiated. However, this function can set the URL if the value is null.
setBody(body)NullSets the body on this ClientRequest as a string. Ensure that you add the appropriate Content-Type header for the type of body you want to send in the request. Common body types are application/x-www-form-urlencoded and key-value. For example: param1=data1&param2=data2&param3=data3.
setMethod(name)NullSets the HTTP method for this ClientRequest as a string. The value is usually a GET or POST, but other common values are PUT, PATCH, and DELETE.
setVersion(version)NullSets the HTTP version for this ClientRequest as a string. The default is HTTP/1.1.
send()ModifiableHttpResponseReturns a ModifiableHttpResponse class object, which is a basic implementation of an HTTP response. To get properties for the ModifiableHttpResponse object, use the functions in the ModifiableHttpResponse Object Functions table. This function is synchronous.

ModifiableHttpResponse object functions

The following table describes the functions and return type for the ModifiableHttpResponse object.

FunctionTypeDescription
body()Byte ArrayReturns the body message of the response. The body contains a series of bytes encoded in UTF-8, by default, unless the headers specify a different encoding.
asString()StringReturns the response body message as a string. We recommend that you use this function to simplify parsing the response.
status()StringReturns the HTTP response status code as a string. For example, 200 OK or 404 NOT FOUND.
headers()List<Header>Returns the response headers as an iterable list.