Azure DevOps: 42Crunch Dynamic API Security Testing (Freemium)
42Crunch API Conformance Scan serves two purposes:
- Testing the resilience and behavior of APIs by automatically generating security tests from the APIs' OpenAPI (formerly Swagger) definition. Scan reproduces the typical behavior of a hacker by injecting bad payloads, bad tokens, and using invalid HTTP verbs and paths. This helps detect vulnerabilities early in the API life cycle, especially those associated with the OWASP API Security Top 10.
- Validating that the implementation of the API conforms to its established contract: Scan checks all responses against the OpenAPI definition and detects unexpected responses and data leaks.
APIs which thoroughly enforce compliance to an established contract are far more resilient to all types of attacks.
You can use this task to test an individual API, identified by its OpenAPI definition. You must supply a target URL and a credential to invoke the API.
You can learn more about 42Crunch Scan by watching a 5 minute introduction video here.
We recommend that you do not target a production system. While the tool does not try to inject malicious payloads, it is possible that the API implementation is not resilient enough to handle the tests and may crash or behave unexpectedly.
You may only use 42Crunch Scan against APIs that you own, but not those of third parties.
Requirements
This task is leveraging 42Crunch's Python CLI and requires a Python runtime. You must either use a base image which has Python 3.10 or later installed, or install Python using the UsePythonVersion@0
task.
apiDefinition
Filename of the API to scan, relative to the workspace root, for example myOAS.json
or OASFiles/openweather.yaml
apiCredential
The API key or token required to invoke the API hosted at target-url
. This value can come from a GitHub secret or can be dynamically obtained from a previous pipeline step, as per the example below.
targetUrl
The URL of the API deployment used by the scan. This URL contains the host as well as the API basePath, for example : https://apis.acme.com/apis/v1. It must be accessible from the CI/CD platform.
logLevel
Sets the level of details in the logs, one of: FATAL
, ERROR
, WARN
, INFO
, DEBUG
.
Default is INFO
.
sarifReport
Converts the raw scan JSON format to SARIF and saves the results into a specified file. If not present, the SARIF report is not generated.
exportAsPDF
(Linux only)
If set, the task exports a summary of the scan report as a PDF file. If not present, the PDF report is not generated.
This option only works on ubuntu-based agents.
scanReport
If set, the task saves the scan report in the specified file in JSON format. If not present, the scan report is not saved.
Examples
Individual step example
A typical new step in an existing workflow would look like this:
- task: APISecurityScanFreemium@1
displayName: Scan API
inputs:
apiDefinition: '$(Build.Repository.LocalPath)/api-specifications/PhotoManager.json'
APICredentials: $(setusertoken.PIXI_TOKEN)
targetURL: '$(TARGET_URL)'
logLevel: 'DEBUG'
sarifReport: '$(Build.Repository.LocalPath)/$(Build.BuildId)-scanreport.sarif'
scanReport: '$(Build.Repository.LocalPath)/$(Build.BuildId)-scanreport.json'
exportAsPDF: '$(Build.Repository.LocalPath)/$(Build.BuildId)-scanreport.pdf'
Full workflow example
A typical workflow which dynamically invokes an endpoint to obtain a token and then scans the API would look like this:
trigger:
branches:
include:
- main
variables:
TARGET_URL: "http://localhost:8090/api"
# For illustration purposes only - This is fake data.
# Use Secrets when dealing with sensitive data.
USER_NAME: "sampleuser@demo.mail"
USER_PASS: "mypasswd"
jobs:
- job: run_42crunch_scan
displayName: 'Run Scan'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: DockerCompose@0
displayName: Run services
inputs:
action: Run services
dockerComposeFile: docker-compose.yaml
projectName: photomanager
qualifyImageNames: true
abortOnContainerExit: true
ports: 8090:8090
detached: true
- task: UsePythonVersion@0
inputs:
versionSpec: '3.11'
addToPath: true
architecture: 'x64'
- task: PythonScript@0
name: setusertoken
displayName: Get User Credential
inputs:
scriptSource: 'filePath' # Options: filePath, inline
scriptPath: $(Build.Repository.LocalPath)/.42c/scripts/pixi-login.py
arguments: -u $(USER_NAME) -p $(USER_PASS) -t $(TARGET_URL)
- task: APISecurityScanFreemium@1
displayName: Scan API
inputs:
apiDefinition: '$(Build.Repository.LocalPath)/api-specifications/PhotoManager.json'
apiCredential: $(setusertoken.PIXI_TOKEN)
targetURL: '$(TARGET_URL)'
logLevel: 'DEBUG'
exportAsPDF: '$(Build.Repository.LocalPath)/$(Build.BuildId)-scanreport.pdf'
sarifReport: '$(Build.Repository.LocalPath)/$(Build.BuildId)-scanreport.sarif'
scanReport: '$(Build.Repository.LocalPath)/$(Build.BuildId)-scanreport.json'
- task: PublishBuildArtifacts@1
displayName: publishScanSarif
inputs:
PathtoPublish: '$(Build.Repository.LocalPath)/$(Build.BuildId)-scanreport.sarif'
ArtifactName: 'CodeAnalysisLogs'
publishLocation: 'Container'
Limitations
The freemium version lets you fully test 42Crunch scan features. It does have usage limitations:
- Organizations on freemium service are limited to 25 scans per repository, with a maximum of three repositories per GitHub organization. The limit is reset every calendar month.
- Only the default security quality gates (SQGs) are included.
- Only the standard data dictionary is included.
Testing this task
If you want to test this task with a sample API, you can follow the tutorial here. This repository contains a sample API and a workflow that will scan it for vulnerabilities.
Support
The task is maintained by the 42Crunch ecosystems team. If you run into an issue, or have a question not answered here, you can create a support ticket at support.42crunch.com and we will be happy to help.
When reporting an issue, do include:
- The version of the AzureDevOps task
- Relevant logs and error messages
- Steps to reproduce the issue