Developer Documentation

Website Scanner

The Tinfoil Security Web Scanner API is a RESTful API designed to help you programatically do all of the things you can do via our web application. It runs over HTTPS and uses HTTP token authentication to ensure that only you can see your data. All responses can either be returned in JSON (the default) or XML, and HTTP response codes are used for error conditions, such as a 404 for resources that could not be found and 401 for failure to authenticate. Any HTTP client should work well, like cURL.

JSON

$ curl https://www.tinfoilsecurity.com/api/v1/sites -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

XML

$ curl https://www.tinfoilsecurity.com/api/v1/sites.xml -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

LIST YOUR SITES

Request

GET /api/v1/sites

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Response

{
  "total_pages":2,
  "page_number":1,
  "next_page":"https://www.tinfoilsecurity.com/api/v1/sites?page=2",
  "sites":[
    {
      "site":{
        "id":"example",
        "name":"Example Site",
        "url":"http://www.example.org",
        "request_rate":40,
        "auth_types":["saml", "basic"],
        "last_successful_scan":{
          "id":"se1353116801559949000",
          "start_time":"2012-11-17T01:46:49Z",
          "end_time":"2012-11-17T02:06:47Z",
          "scan_type":"full",
          "status":"done"
        },
        "configuration_add_ons": {
          "auto_throttle_disabled": false,
          "crawl_robots_txt_disabled": false,
          "crawl_sitemap_disabled": false,
          "dom_dedupe_disabled": false,
          "javascript_enabled": false,
          "path_customization": {
            "restricted_paths": [
                "/restricted"
            ],
            "inclusion_regexes": [
                "/go_here"
            ],
            "exclusion_regexes": [
                "/avoid_here"
            ]
          },
          "scan_webhooks": {
            "scan_started_webhook": "http://www.example.org",
            "scan_finished_webhook": "http://www.example.org"
          },
        },
        "schedule": {
          "frequency": "monthly",
          "scan_time_of_month": "4",
          "scan_time_of_week": "monday",
          "scan_time_of_day": "night"
        },
      }
    },
    "..."
  ]
}

Returns a list of all of the sites that you own or that are shared with you. Each site listing includes an ID of the last successful scan so you can go straight to its report.

Parameters

per_page - Optional (Default is 10). Use this to specify how many records are returned on each page.

page - Optional (Default is 1). Use this to specify which page of records to view.

Response Description

total_pages and page_number let you know where you are in the list of sites, and next_page provides you with a link to the next page of sites. If you are on the last page, the next_page attribute will not be present.

auth_type - zero or more of the following: form, javascript, custom_login_javascript, recorded_login, saml, basic, digest, ntlm, custom_login.


LIST YOUR PLANS

Request

GET /api/v1/plans

Example

$ curl https://www.tinfoilsecurity.com/api/v1/plans -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Response

[
  {
    "plan":{
      "id":1,
      "name":"Starter Plan"
    }
  },
  {
    "plan":{
      "id":2,
      "name":"Standard Plan"
    }
  },
  {
    "plan":{
      "id":3,
      "name":"All Access Plan"
    }
  }
]

Returns a list of all of the plans available for your sites. Each site listing includes an ID of the plan that can be assigned to the site. Some plans (like those typically labeled "Free") may have other restrictions that need to be met before they can be assigned to a site. Assigning a plan to a site will update your billing invoice right away, and may result in additional charges. Please see your dashboard for more information.


ADD/UPDATE A SITE

Request

ADD:
POST /api/v1/sites
UPDATE:
PUT /api/v1/sites/:site_id/

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites -X POST -d 'site[name]=Example' -d 'site[url]=http://example.org' -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Success Response

HTTP Response Code: 201
{
"site": {
  "id": "example",
  "url": "http://example.org",
  "request_rate": 40
  }
}

Sample Failure Response

HTTP Response Codes: 403, 412
{
  "errors": [
    "You have reached the maximum number of sites allowed for this account."
  ]
}

Creates or modifies an existing site profile for scanning. You must have full API access (not read-only) to perform this operation.

Parameters

site[name] - Required.

site[url] - Required.

site[plan_id] - Optional, but required for scans to be able to run.

site[basic_auth_username] - Optional.

site[basic_auth_password] - Optional.

site[auth_url] - Optional. The URL where a form with the inputs specified by auth_username_field and auth_password_field is expected to be found.

site[auth_username] - Optional.

site[auth_username_field] - Optional. The name attribute of a form input expecting the username.

site[auth_password] - Optional.

site[auth_password_field] - Optional. The name attribute of a form input expecting the password.

site[max_request_rate] - Optional (default is 40). Value between 2 and 100.

site[audit_contact_forms] - Optional. Boolean.

site[discover_unknown_paths] - Optional. Boolean.

site[custom_headers] - Optional. Object; keys are the header names, and values are the header values. Set custom headers to send along with every scan. Example: site[custom_headers][X-Custom-Tag]=#interesting-tag

site[raw_stack_tags] - Optional. String with frameworks and programming languages in your software stack. Separate technologies with a comma.

schedule[frequency] - Optional. One of "monthly", "weekly", "daily", "none".

schedule[scan_time_of_month] - Optional. One of "1", "2", "3", "4". For Monthly schedules, represents the nth chosen day of the week the scan will occur on (eg. Setting scan_time_of_month to "4" and scan_time_of_week to "friday" would create a schedule that scans on the 4th Friday of each month)

schedule[scan_time_of_week] - Optional. One of "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday". For Monthly or Weekly schedules.

schedule[scan_time_of_day] - Optional. One of "morning", "afternoon", "evening", "night". For all schedules, represents the 6-hour PST windows the scan will begin in. The windows are (14:00-20:00 UTC), (20:00-02:00 UTC), (02:00-08:00 UTC), (08:00-14:00 UTC) respectively.

configuration_add_ons[auto_throttle_disabled] - Optional. Boolean.

configuration_add_ons[crawl_robots_txt_disabled] - Optional. Boolean.

configuration_add_ons[crawl_sitemap_disabled] - Optional. Boolean.

configuration_add_ons[dom_dedupe_disabled] - Optional. Boolean.

configuration_add_ons[javascript_enabled] - Optional. Boolean.

configuration_add_ons[path_customization] - Optional. Object; Accepted keys include restricted_paths, inclusion_regexes, and exclusion_regexes with strings as values.

configuration_add_ons[scan_webhooks] - Optional. Object; Accepted keys include scan_started_webhook and scan_finished_webhook, with strings representing valid URLs as values.

configuration_add_ons[javascript_customization] - Optional. Object; Accepted keys include javascript_wait_function: a Javascript function to wait for a specific condition for each page load when scanning with Javascript is enabled. Javascript function must return a boolean.

Response Description

If successful, returns the ID of the new site, along with a summary of associated information.

Note: modifying the site name can change the returned ID to be used in subsequent requests.


DELETE A SITE

Request

DELETE /api/v1/sites/:site_id

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites/:site_id -X DELETE -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Success Response

HTTP Response Code: 200

Sample Failure Response

HTTP Response Codes: 403, 404

Unrecoverably destroys a website and all associated scans. You must have full API access (not read-only) to perform this operation.

Parameters

:site_id - Required. This is the ID of your site, as returned by GET /api/v1/sites.

Response Description

If successful, destroys a website and all associated scans.


START A SCAN

Request

POST /api/v1/sites/:site_id/scans

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites/:site_id/scans -X POST -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Success Response

HTTP Response Code: 201(created)
{
  "scan": {
    "end_time": null,
    "id": "se1353976376418547000",
    "scan_type": "full",
    "start_time": null,
    "status": "unknown"
  }
}

Sample Failure Response

HTTP Response Codes: 409(conflict), 412(precondition failed)
{
  "errors": [
    "Scans cannot be run on <strong>Example.org</strong> because you must verify ownership first."
  ]
}

Begins a scan for a site. You must have full API access (not read-only) to perform this operation. The new scan is queued to begin shortly after the request returns successfully.

Parameters

:site_id - Required. This is the ID of your site, as returned by GET /api/v1/sites.

Response Description

If successful, returns the ID of the new scan. If the site is not eligible to be scanned, either due an already running scan or a site that fails a precondition like verification, an error object is returned specifying the details.


STOP A SCAN

Request

PUT /api/v1/sites/:site_id/scans/:scan_id/cancel

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites/:site_id/scans/:scan_id/cancel -X PUT -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Success Response

HTTP Response Code: 200
{
  "scan": {
    "end_time": "2012-11-28T02:38:02Z",
    "id": "se1353976376418547000",
    "scan_type": "full",
    "start_time": "2012-11-28T02:28:02Z",
    "status": "cancelled"
  }
}

Sample Failure Response

HTTP Response Code: 500
{
  "errors": [
    "Scan could not be cancelled."
  ]
  "scan": {
    "end_time": "2012-11-28T02:38:02Z",
    "id": "se1353976376418547000",
    "scan_type": "full",
    "start_time": "2012-11-28T02:28:02Z",
    "status": "done"
  }
}

Cancels a scan. You must have full API access (not read-only) to perform this operation. If the scan is already cancelled or done, will do nothing.

Parameters

:site_id - Required. This is the ID of your site, as returned by GET /api/v1/sites.

:scan_id - Required. This is the ID of your scan, as returned by GET /api/v1/sites/:site_id/scans.

Response Description

Returns the current status of the scan. An error object will be present in the case that the scanner could not immediately end the scan.


FINISH A SCAN EARLY

Request

PUT /api/v1/sites/:site_id/scans/:scan_id/finish_early

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites/:site_id/scans/:scan_id/finish_early -X PUT -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Success Response

HTTP Response Code: 202
{
  "text": "Scan is queued to end early.",
  "scan": {
    "id": "se145489778629771000",
    "start_time": "2012-11-28T02:16:31Z",
    "scanner_ip_address": "54.242.161.118",
    "end_time": null,
    "scan_type": "full",
    "status": "scanning"
    }
}

Finishes a scan early, adding a vulnerability that states it was not a complete scan, but providing results up to that point. This is not an immediate operation. You must have full API access (not read-only) to perform this operation. If the scan is already cancelled or done, will do nothing.

Parameters

:site_id - Required. This is the ID of your site, as returned by GET /api/v1/sites.

:scan_id - Required. This is the ID of your scan, as returned by GET /api/v1/sites/:site_id/scans.

Response Description

Returns the current status of the scan, and a message stating the scan is queued to be ended early.


LIST ALL SCANS FOR A SITE

Request

GET /api/v1/sites/:site_id/scans

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites/:site_id/scans?status=done -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Response

{
  "total_pages":3,
  "page_number":1,
  "next_page":"https://www.tinfoilsecurity.com/api/v1/sites/example/scans?page=2",
  "scans":[
     {
        "scan":{
           "id":"se1352947099875001000",
           "start_time":"2012-11-15T02:38:30Z",
           "end_time":null,
           "scan_type":"full",
           "status":"scanning",
           "scanner_ip_address":"54.242.161.118"
        }
     },
     {
        "scan":{
           "id":"se1352946907718082000",
           "start_time":"2012-11-15T02:35:18Z",
           "end_time":null,
           "scan_type":"full",
           "status":"cancelled",
           "scanner_ip_address":"23.23.17.84"
        }
     },
     {
        "scan":{
           "id":"se1352759585821550000",
           "start_time":"2012-11-12T22:33:15Z",
           "end_time":"2012-11-12T23:10:10Z",
           "scan_type":"rudimentary",
           "status":"done",
           "scanner_ip_address":"23.23.17.84"
        }
     },
     "..."
  ]
}

Returns a list of all of the scans run on a particular site, given by :site_id in the URL.

Parameters

:site_id - Required. This is the ID of your site, as returned by GET /api/v1/sites.

status - Optional. Use this to filter your scans by status. Allowed values are running, done, cancelled, and upcoming.

per_page - Optional (Default is 20). Use this to specify how many records are returned on each page.

page - Optional (Default is 1). Use this to specify which page of records to view.

Response Description

scan_type - one of the following: full, rudimentary, rescan, or unknown.

status - one of the following: scanning, done, upcoming, cancelled, or unknown.

total_pages and page_number let you know where you are in the list of scans, and next_page provides you with a link to the next page of scans. If you are on the last page, the next_page attribute will not be present.


GET REPORT FOR A SCAN

Request

GET /api/v1/sites/:site_id/scans/:scan_id/report

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites/:site_id/scans/:scan_id/report -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Response

{
  "report":{
    "total_pages":5,
    "page_number":1,
    "next_page":"https://www.tinfoilsecurity.com/api/v1/sites/example/scans/se1352759585821550000/report?page=2",
    "classification":"very_unsafe",
    "site":{
      "name":"Example Site",
      "url":"http://www.example.org"
    },
    "scan":{
      "start_time":"2012-11-12T22:33:15Z",
      "end_time":"2012-11-12T23:10:10Z"
    },
    "issues":[
      {
        "issue":{
          "id":"53f5226abd0e019ed111000a",
          "signature":"9cc17ebe9e8d58f2049b9719678cd2e2d972ce7aa497b2c6437911328aef69a3",
          "url":"http://www.example.org/search.aspx",
          "type":"Cross-Site Scripting (XSS)",
          "dismissible?": false,
          "dismissed?": false,
          "rescannable?": true,
          "fixed": false,
          "severity":"High",
          "method":"GET",
          "element":{
            "type":"form",
            "name":"txtSearch"
          },
          "attack":{
            "injected":"<tinfoil_xss_9d18d1d12725466697a759028742a5502a3aa78694bfe1bd89129a22ad68c0a8/>",
            "request_headers":[
                {
                  "key":"Accept",
                  "value":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
                },
                "..."
              ],
              "response_headers":[
                {
                  "key":"Date",
                  "value":"Tue, 13 Nov 2012 00:29:44 GMT"
                },
                "..."
              ],
              "params":[
                {
                  "key":"txtSearch",
                  "value":"<tinfoil_xss_c6c8f8e873d71f7d84b4f358540e18a0a80b89ee4d3fe69af9497bf380bd20db/>"
                }
              ]
            }
          }
        }
      },
      "..."
    ]
  }
}

Returns the full report for a completed scan, given a :site_id and a :scan_id.

Parameters

:site_id - Required. This is the ID of your site, as returned by GET /api/v1/sites.

:scan_id - Required. This is the ID of your scan, as returned by GET /api/v1/sites/:site_id/scans.

per_page - Optional (Default is 10). Use this to specify how many records are returned on each page.

page - Optional (Default is 1). Use this to specify which page of records to view.

Response Description

Reports can get very large, as they include the request and response headers for each vulnerability we found. Therefore, the report is paginated. total_pages and page_number let you know where you are in the list of issues, and next_page provides you with a link to the next page of issues. If you are on the last page, the next_page attribute will not be present.

Note: if a report is requested from a scan that is not finished, a reponse code of 202 will be returned.

Generate a PDF

You can also generate a PDF of a report with GET https://www.tinfoilsecurity.com/api/v1/sites/:site_id/scans/:scan_id/report/export_pdf. If the PDF does not yet exist, a response code of 202 will be given, and a link to download this report will be emailed out once the PDF has been generated. If the PDF already exists, the URL to download it will be returned.


GET DETAILED INFO FOR AN ISSUE

Request

GET /api/v1/sites/:site_id/scans/:scan_id/report/issues/:issue_id

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites/:site_id/scans/:scan_id/report/issues/:issue_id -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Response

{
    "issue": {
        "url": "https://example.org",
        "id": "5bff361344774c4ad7000004",
        "signature": "0275fcd8f67cc9d08604ac7f2e8b865e22d4fe9d53203d7f3bf49404a6200ccb",
        "type": {
            "name": "SQL Injection",
            "description": "SQL Command Injection is a technique where an attacker creates or alters existing SQL commands to expose hidden data, or to override valuable ones, or even to execute dangerous system level commands on the database host. This is accomplished by the application taking user input and combining it with static parameters to build an SQL query. This is arguably one of the worst possible attacks on any web application."
        },
        "dismissible?": false,
        "dismissed?": false,
        "rescannable?": true,
        "fixed" false,
        "severity": "High",
        "method": "POST",
        "element": {
            "type": "form",
            "name": "btnSubmit"
        },
        "remedy": {
            "how_to_fix": "<p>User inputs must be validated and filtered before being included in database queries. We highly recommend making use of bind variables in your SQL queries. Database permissions should also be set carefully; for example it is likely a web application should not be allowed to drop tables. Database users and permissions can be segmented further to limit the damage or disclosure during a breach. If you take an approach of sanitizing and stripping inputs, it is very important to take a whitelist approach rather than a blacklist approach if you strip specific commands or strings out. Using a blacklist of disallowed commands or symbols is always vulnerable, as a skilled attacker can get around your filters by simply putting commands/symbols inside other ones and crafting strings in other ingenious ways. With a whitelist, an attacker is limited to only those you allow.</p>\n",
            "stack_tag": null
        },
        "attack": {...}
    }
}

Returns detailed information on an issue, given a :site_id, :scan_id, and :issue_id. This includes description information under "type" as well as suggested fixes under "remedy"

Parameters

:site_id - Required. This is the ID of your site, as returned by GET /api/v1/sites.

:scan_id - Required. This is the ID of your scan, as returned by GET /api/v1/sites/:site_id/scans.

:issue_id - Required. This is the ID of an issue on your scan, as returned from GET /api/v1/sites/:site_id/scans/:scan_id/report.

Response Description

This returns the issue with its full type, including its description and remedy information for various software stack, formatted both as markdown and html.


START RESCAN FOR AN ISSUE

Request

POST /api/v1/sites/:site_id/scans/:scan_id/report/issues/:issue_id/rescan

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites/:site_id/scans/:scan_id/report/issues/:issue_id/rescan -X POST -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Response

{
    "scan": {
      "end_time": "2012-11-28T02:38:02Z",
      "id": "se1353976376418547000",
      "scan_type": "rescan",
      "start_time": "2012-11-28T02:28:02Z",
      "status": "scanning"
  }
}

Sample Failure Response

HTTP Response Codes: 412
{
  "errors": [
    "Issue not rescannable."
  ]
}

Initiates a rescan for a rescannable issue, given a :site_id, :scan_id, and :issue_id.

Parameters

:site_id - Required. This is the ID of your site, as returned by GET /api/v1/sites.

:scan_id - Required. This is the ID of your scan, as returned by GET /api/v1/sites/:site_id/scans.

:issue_id - Required. This is the ID of an issue on your scan, as returned from GET /api/v1/sites/:site_id/scans/:scan_id/report.

Response Description

Returns the current status of the rescan.


TOGGLE ISSUE DISMISSED

Request

POST /api/v1/sites/:site_id/scans/:scan_id/report/issues/:issue_id/toggle_dismiss

Example

$ curl https://www.tinfoilsecurity.com/api/v1/sites/:site_id/scans/:scan_id/report/issues/:issue_id/toggle_dismiss -X POST -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Response

{
    "issue": {
        "url": "https://example.org",
        "id": "5b6a0093b8811071b4000006",
        "signature": "5d9adf8ac930ac28d12b324da8d967e8a7a642e8076daaff8f4",
        "type": {
            "name": "Insecure Cookies",
            "description": "...",
            "remedies": [...]
        },
        "dismissible?": true,
        "dismissed?": true,
        "rescannable?": true,
        "fixed": false,
        "severity": "Info",
        "method": "",
        "element": {
            "type": "cookie",
            "name": "amSessionId"
        },
        "attack": {...}
    }
}

Sample Failure Response

HTTP Response Codes: 412
{
  "errors": [
    "Issue not dismissible."
  ]
}

Toggles whether an issue is dismissed, given a :site_id, :scan_id, and :issue_id.

Parameters

:site_id - Required. This is the ID of your site, as returned by GET /api/v1/sites.

:scan_id - Required. This is the ID of your scan, as returned by GET /api/v1/sites/:site_id/scans.

:issue_id - Required. This is the ID of an issue on your scan, as returned from GET /api/v1/sites/:site_id/scans/:scan_id/report.

Response Description

Returns the updated issue.


GET INFORMATION ON THE CURRENT API KEY

Request

GET /api/v1/api_keys/info

Example

$ curl https://www.tinfoilsecurity.com/api/v1/api_keys/info -H 'Authorization:Token token=YOUR_API_SECRET_KEY, access_key=YOUR_API_ACCESS_KEY'

Sample Response

{
  "api_key":{
    "name":"API Key",
    "active":true,
    "access_key":"YOUR_API_ACCESS_KEY",
    "read_only":false
  }
}

Returns information about the current API key being used.

Response Description

read_only will be true for read_only keys, and false for full_access keys.