Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • A arachni
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 125
    • Issues 125
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 8
    • Merge requests 8
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Arachni - Web Application Security Scanner Framework
  • arachni
  • Wiki
  • Guides
  • Developer
  • REST API

REST API · Changes

Page history
Reorganized files authored Feb 02, 2016 by Tasos Laskos's avatar Tasos Laskos
Show whitespace changes
Inline Side-by-side
guides/developer/REST-API.md 0 → 100644
View page @ 36aa04d3
# REST API
* [Server](#server)
* [API](#api)
* [List scans](#list-scans)
* [Perform a new scan](#perform-a-new-scan)
* [Monitor scan progress](#monitor-scan-progress)
* [Pause a scan](#pause-a-scan)
* [Resume a scan](#resume-a-scan)
* [Retrieve a scan report](#retrieve-a-scan-report)
* [Abort or shutdown a scan](#abort-or-shutdown-a-scan)
* [Example](#example-client)
## <a id="server" href="#server">Server</a>
For server configuration please consult the [[relevant page | REST-Server]].
## <a id="api" href="#api">API</a>
### <a id="list-scans" href="#list-scans">List scans</a>
Scans are identified by their IDs, a list of which can be retrieved with:
#### Request
GET /scans
#### Response
```json
{
"ids": [
"b72154c25c82aef00fbf9a16d04c1894",
"34e9ba35a3d793ae6e2562303d1a5e87"
]
}
```
### <a id="perform-a-new-scan" href="#perform-a-new-scan">Perform a new scan</a>
Scans will run in parallel, each in its own process.
#### Request
POST /scans
Default options are:
```json
{
"url" : null,
"http" : {
"user_agent" : "Arachni/v2.0dev",
"request_timeout" : 10000,
"request_redirect_limit" : 5,
"request_concurrency" : 20,
"request_queue_size" : 100,
"request_headers" : {},
"response_max_size" : 500000,
"cookies" : {}
},
"audit" : {
"parameter_values" : true,
"exclude_vector_patterns" : [],
"include_vector_patterns" : [],
"link_templates" : []
},
"input" : {
"values" : {},
"default_values" : {
"(?i-mx:name)" : "arachni_name",
"(?i-mx:user)" : "arachni_user",
"(?i-mx:usr)" : "arachni_user",
"(?i-mx:pass)" : "5543!%arachni_secret",
"(?i-mx:txt)" : "arachni_text",
"(?i-mx:num)" : "132",
"(?i-mx:amount)" : "100",
"(?i-mx:mail)" : "arachni@email.gr",
"(?i-mx:account)" : "12",
"(?i-mx:id)" : "1"
},
"without_defaults" : false,
"force" : false
},
"browser_cluster" : {
"wait_for_elements" : {},
"pool_size" : 6,
"job_timeout" : 25,
"worker_time_to_live" : 100,
"ignore_images" : false,
"screen_width" : 1600,
"screen_height" : 1200
},
"scope" : {
"redundant_path_patterns" : {},
"dom_depth_limit" : 5,
"exclude_path_patterns" : [],
"exclude_content_patterns" : [],
"include_path_patterns" : [],
"restrict_paths" : [],
"extend_paths" : [],
"url_rewrites" : {}
},
"session" : {},
"checks" : [],
"platforms" : [],
"plugins" : {},
"no_fingerprinting" : false,
"authorized_by" : null
}
```
* Only the `url` option is mandatory.
* These options are passed to [Arachni::Options#update](http://www.rubydoc.info/github/Arachni/arachni/Arachni/Options#update-instance_method).
* Options expecting a type of `Regexp` (unavailable in JSON) can be specified as
type `String`.
* The string should not be enclosed in `/`; for example, use `test.*` instead of `/test.*/`.
#### Response
Currently, the response only contains the scan's ID.
```json
{
"id" : "1a34b6aca50bcf0065aca0a06a8d21ba"
}
```
##### Errors
A `500` error will be returned on invalid options:
```json
{
"error" : "Arachni::RPC::Exceptions::RemoteException: undefined method `stuff=' for #<Arachni::Options:0x00000001fa0dd8>",
"backtrace" : [
"/home/zapotek/workspace/arachni/lib/arachni/options.rb:276:in `block in update'",
"/home/zapotek/workspace/arachni/lib/arachni/options.rb:271:in `each'",
"/home/zapotek/workspace/arachni/lib/arachni/options.rb:271:in `update'",
"/home/zapotek/workspace/arachni/lib/arachni/rpc/server/active_options.rb:34:in `set'",
"/home/zapotek/workspace/arachni/lib/arachni/rpc/server/instance.rb:584:in `scan'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-rpc-0.2.1.2/lib/arachni/rpc/server.rb:207:in `call'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-rpc-0.2.1.2/lib/arachni/rpc/server/handler.rb:57:in `receive_request'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-rpc-0.2.1.2/lib/arachni/rpc/server/handler.rb:96:in `receive_object'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-rpc-0.2.1.2/lib/arachni/rpc/protocol.rb:52:in `on_read'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor/connection.rb:255:in `block in _read'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor/connection/error.rb:26:in `call'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor/connection/error.rb:26:in `translate'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor/connection.rb:254:in `_read'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor/connection/tls.rb:115:in `_read'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor.rb:574:in `each'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor.rb:574:in `block in process_connections'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor.rb:574:in `each'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor.rb:574:in `process_connections'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor.rb:316:in `block in run'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor.rb:307:in `loop'",
"/home/zapotek/.rvm/gems/ruby-2.2.0/gems/arachni-reactor-0.1.0/lib/arachni/reactor.rb:307:in `run'",
"/home/zapotek/workspace/arachni/lib/arachni/rpc/server/instance.rb:152:in `initialize'",
"/home/zapotek/workspace/arachni/lib/arachni/processes/executables/instance.rb:13:in `new'",
"/home/zapotek/workspace/arachni/lib/arachni/processes/executables/instance.rb:13:in `<top (required)>'",
"/home/zapotek/workspace/arachni/lib/arachni/processes/executables/base.rb:9:in `load'",
"/home/zapotek/workspace/arachni/lib/arachni/processes/executables/base.rb:9:in `<main>'"
]
}
```
### <a id="monitor-scan-progress" href="#monitor-scan-progress">Monitor scan progress</a>
#### Request
GET /scans/:id
#### Response
```json
{
"status": "scanning",
"busy": true,
"seed": "c0c039750bef4f5688da4fba929b06ac",
"statistics": {
"http": {
"request_count": 1312,
"response_count": 1208,
"time_out_count": 0,
"total_responses_per_second": 145.55173283136,
"burst_response_time_sum": 0,
"burst_response_count": 0,
"burst_responses_per_second": 0,
"burst_average_response_time": 0,
"total_average_response_time": 0.12118887582781,
"max_concurrency": 20,
"original_max_concurrency": 20
},
"browser_cluster": {
"seconds_per_job": 1.6666666666667,
"total_job_time": 25,
"queued_job_count": 31,
"completed_job_count": 15
},
"runtime": 9.251885252,
"found_pages": 10,
"audited_pages": 2,
"current_page": "http:\/\/testhtml5.vulnweb.com\/ajax\/popular?offset=0"
},
"errors": [],
"messages": [],
"issues": [],
"sitemap": {}
}
```
* `status` can be:
* `ready` -- Initialised and waiting for instructions.
* `preparing` -- Getting ready to start (i.e. initializing plugins etc.).
* `scanning` -- The instance is currently scanning the webapp.
* `pausing` -- The instance is being paused.
* `paused` -- The instance has been paused.
* `cleanup` -- The scan has completed and the instance is cleaning up
after itself (i.e. waiting for plugins to finish etc.).
* `aborted` -- The scan has been aborted, you can grab the report and shutdown.
* `done` -- The scan has completed, you can grab the report and shutdown.
* `busy`
* `true` -- The scan is still in progress.
* `false` -- The scan has finished, it is safe to grab the report and shutdown.
* `errors` -- Recoverable runtime errors.
* `issues` -- Identified issues.
* `sitemap` -- Scanned pages by URL and their HTTP status code.
* `url`: `code`
* `messages` -- Status messages.
So long as the client maintains a session with the service, only new `issues`, `sitemap`
entries and `errors` will be returned.
If no session is being maintained, each call will always return all data.
### <a id="pause-a-scan" href="#pause-a-scan">Pause a scan</a>
This is a soft pause, it will not kill the scanner process but merely make it
wait for a resume signal in order to continue the scan.
#### Request
PUT /scans/:id/pause
### <a id="resume-a-scan" href="#resume-a-scan">Resume a scan</a>
#### Request
PUT /scans/:id/resume
### <a id="retrieve-a-scan-report" href="#retrieve-a-scan-report">Retrieve a scan report</a>
#### Request
GET /scans/:id/report
GET /scans/:id/report.json
GET /scans/:id/report.xml
GET /scans/:id/report.yaml
GET /scans/:id/report.html.zip
When the extension is missing, it will default to `json`.
#### Response
- [JSON](http://www.arachni-scanner.com/reports/report.json) (`json`)
- [XML](http://www.arachni-scanner.com/reports/report.xml) (`xml`).
- [YAML](http://www.arachni-scanner.com/reports/report.yml) (`yaml`)
- [HTML](http://www.arachni-scanner.com/reports/report.html/)
([zip](http://www.arachni-scanner.com/reports/report.html.zip)) (`html`).
### <a id="abort-or-shutdown-a-scan" href="#abort-or-shutdown-a-scan">Abort or shutdown a scan</a>
#### Request
DELETE /scans/:id
This call needs to take place after each scan is done in order to prevent zombie processes.
Once that call is made, the scan process will be killed and removed from the
service, if you wish to retrieve the report you will need to do so prior to performing
this call.
## <a id="example-client" href="#example-client">Example client</a>
```ruby
#!/usr/bin/env ruby
require 'ap'
require 'typhoeus'
require 'json'
# Base URL of the REST service.
URL = 'http://localhost:7331'
# Cookie-Jar for the session.
#
# Allows for optimizations such as scan progress calls only returning issues not
# previously seen by previous calls, instead of all issues every single time.
COOKIE_JAR = '/tmp/arachni_rest_client.cookiejar'
#
# HTTP helpers
###############
def request( path, options = {} )
if (data = options.delete(:data))
options[:body] = JSON.dump( data )
end
response = Typhoeus::Request.new(
"#{URL}/#{path}",
options.merge(
# Maintain a session.
cookiefile: COOKIE_JAR,
cookiejar: COOKIE_JAR,
# Enable compression.
accept_encoding: 'gzip, deflate',
)
).run
fail response.return_message if response.code == 0
JSON.load( response.body )
end
def get( path )
request( path )
end
def post( path, data = nil )
request( path, data: data, method: :post )
end
def delete( path )
request( path, method: :delete )
end
#
# Usage example
###############
# Start a new scan with the given options.
#
# The `id` included in the response data will allow us to manage it.
id = post( '/scans',
url: 'http://testhtml5.vulnweb.com',
# Only scan a few pages.
scope: {
page_limit: 10
},
# Load all checks.
checks: ['*']
)['id']
# Poll until the scan is finished.
loop do
print '.'
# Get the scan's progress.
#
# Status messages, runtime statistics, new issues, new errors etc.
progress = get( "/scans/#{id}" )
# Status messages (initializing something, pausing in a bit, etc.).
if progress['messages'].any?
puts
puts 'Messages:'
puts progress['messages'].join( "\n" )
end
# Because we're maintaining a session with the REST server, only issues
# which have not been previously seen will be returned by each call.
if progress['issues'].any?
puts
puts 'Issues:'
progress['issues'].each do |issue|
summary = "#{issue['name']} in '#{issue['vector']['type']}'"
# Passive issues don't have this.
if issue['affected_input_name']
summary << " input '#{issue['affected_input_name'].inspect}'"
summary << " using #{issue['affected_input_value'].inspect}"
end
summary << " at: #{issue['page']['dom']['url']}"
puts summary
end
end
# Same thing as before, only new sitemap entries will be returned for each call.
if progress['sitemap'].any?
puts
puts 'Scanned pages:'
progress['sitemap'].each do |url, code|
puts "[#{code}] #{url}"
end
end
# Same thing as before, only new errors will be returned for each call.
if progress['errors'].any?
puts
puts 'Errors:'
puts progress['errors'].join( "\n" )
end
# When `busy` is set to `false`, it means that the scan has completed.
break if !progress['busy']
sleep 1
end
puts
# Get the full scan report.
ap get( "/scans/#{id}/report" )
# Get a list of all living scan processes, of course, it will include ours.
puts 'Scan list:'
ap get( '/scans' )
# Since we're done with this one, kill it.
#
# Don't forget this, we don't want any zombie processes laying around.
print 'Shutting down scan...'
delete "/scans/#{id}"
puts '... done!'
# Lo and behold, our scan is no longer listed.
puts 'Scan list:'
ap get( '/scans' )
```
Clone repository

Pages [all]

  • Home
  • Installation instructions
  • For users
    • Executables
    • Command Line Interface
    • Web User Interface
    • Distributed components
      • RPC Client
      • RPC Server (Dispatcher)
      • REST Server
  • For developers
    • REST API
    • RPC API
    • Core API documentation
    • Development environment

Can't find what you're looking for? Why not have a look at the support portal?