66 | {{ /* backwards compatibility */ }}
67 |
68 |
69 |
70 |
71 |
72 | {{? data.options.yaml }}
73 | ```yaml
74 | {{=data.utils.yaml.stringify(data.utils.getSample(schema,data.options,{quiet:true},data.api))}}
75 | {{??}}
76 | ```json
77 | {{=data.utils.safejson(data.utils.getSample(schema,data.options,{quiet:true},data.api),null,2)}}
78 | {{?}}
79 | ```
80 |
81 | {{ var enums = []; }}
82 | {{ var blocks = data.utils.schemaToArray(origSchema,-1,{trim:true,join:true},data); }}
83 | {{ for (var block of blocks) {
84 | for (var p of block.rows) {
85 | if (p.schema && p.schema.enum) {
86 | for (var e of p.schema.enum) {
87 | enums.push({name:p.name,value:e});
88 | }
89 | }
90 | }
91 | }
92 | }}
93 |
94 | {{~ blocks :block}}
95 | {{? block.title }}{{= block.title}}{{= '\n\n'}}{{?}}
96 | {{? block.externalDocs}}
97 | {{=block.externalDocs.description||'External documentation'}}
98 | {{?}}
99 |
100 | {{? block===blocks[0] }}
101 | {{= data.tags.section }}
102 |
103 | ### Properties
104 | {{?}}
105 |
106 | {{? block.rows.length}}|Name|Type|Required|Restrictions|Description|
107 | |---|---|---|---|---|{{?}}
108 | {{~ block.rows :p}}|{{=p.displayName}}|{{=p.safeType}}|{{=p.required}}|{{=p.restrictions||'none'}}|{{=p.description||'none'}}|
109 | {{~}}
110 | {{~}}
111 | {{? (blocks[0].rows.length === 0) && (blocks.length === 1) }}
112 | *None*
113 | {{?}}
114 |
115 | {{? enums.length > 0 }}
116 | {{= data.tags.section }}
117 |
118 | #### Enumerated Values
119 |
120 | |Property|Value|
121 | |---|---|
122 | {{~ enums :e}}|{{=e.name}}|{{=data.utils.toPrimitive(e.value)}}|
123 | {{~}}
124 |
125 | {{= data.tags.endSection }}
126 | {{?}}
127 |
128 | {{= data.tags.endSection }}
129 | {{= data.tags.endSection }}
130 |
131 | {{ } /* of schemas */ }}
132 |
133 | {{?}}
134 |
135 | {{#def.footer}}
136 |
137 | {{? data.options.discovery}}
138 | {{#def.discovery}}
139 | {{?}}
140 |
--------------------------------------------------------------------------------
/font-selection.json:
--------------------------------------------------------------------------------
1 | {
2 | "IcoMoonType": "selection",
3 | "icons": [
4 | {
5 | "icon": {
6 | "paths": [
7 | "M438.857 73.143q119.429 0 220.286 58.857t159.714 159.714 58.857 220.286-58.857 220.286-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857zM512 785.714v-108.571q0-8-5.143-13.429t-12.571-5.429h-109.714q-7.429 0-13.143 5.714t-5.714 13.143v108.571q0 7.429 5.714 13.143t13.143 5.714h109.714q7.429 0 12.571-5.429t5.143-13.429zM510.857 589.143l10.286-354.857q0-6.857-5.714-10.286-5.714-4.571-13.714-4.571h-125.714q-8 0-13.714 4.571-5.714 3.429-5.714 10.286l9.714 354.857q0 5.714 5.714 10t13.714 4.286h105.714q8 0 13.429-4.286t6-10z"
8 | ],
9 | "attrs": [],
10 | "isMulticolor": false,
11 | "tags": [
12 | "exclamation-circle"
13 | ],
14 | "defaultCode": 61546,
15 | "grid": 14
16 | },
17 | "attrs": [],
18 | "properties": {
19 | "id": 100,
20 | "order": 4,
21 | "prevSize": 28,
22 | "code": 58880,
23 | "name": "exclamation-sign",
24 | "ligatures": ""
25 | },
26 | "setIdx": 0,
27 | "iconIdx": 0
28 | },
29 | {
30 | "icon": {
31 | "paths": [
32 | "M585.143 786.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-54.857v-292.571q0-8-5.143-13.143t-13.143-5.143h-182.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h54.857v182.857h-54.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h256q8 0 13.143-5.143t5.143-13.143zM512 274.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-109.714q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h109.714q8 0 13.143-5.143t5.143-13.143zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z"
33 | ],
34 | "attrs": [],
35 | "isMulticolor": false,
36 | "tags": [
37 | "info-circle"
38 | ],
39 | "defaultCode": 61530,
40 | "grid": 14
41 | },
42 | "attrs": [],
43 | "properties": {
44 | "id": 85,
45 | "order": 3,
46 | "name": "info-sign",
47 | "prevSize": 28,
48 | "code": 58882
49 | },
50 | "setIdx": 0,
51 | "iconIdx": 2
52 | },
53 | {
54 | "icon": {
55 | "paths": [
56 | "M733.714 419.429q0-16-10.286-26.286l-52-51.429q-10.857-10.857-25.714-10.857t-25.714 10.857l-233.143 232.571-129.143-129.143q-10.857-10.857-25.714-10.857t-25.714 10.857l-52 51.429q-10.286 10.286-10.286 26.286 0 15.429 10.286 25.714l206.857 206.857q10.857 10.857 25.714 10.857 15.429 0 26.286-10.857l310.286-310.286q10.286-10.286 10.286-25.714zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z"
57 | ],
58 | "attrs": [],
59 | "isMulticolor": false,
60 | "tags": [
61 | "check-circle"
62 | ],
63 | "defaultCode": 61528,
64 | "grid": 14
65 | },
66 | "attrs": [],
67 | "properties": {
68 | "id": 83,
69 | "order": 9,
70 | "prevSize": 28,
71 | "code": 58886,
72 | "name": "ok-sign"
73 | },
74 | "setIdx": 0,
75 | "iconIdx": 6
76 | },
77 | {
78 | "icon": {
79 | "paths": [
80 | "M658.286 475.429q0-105.714-75.143-180.857t-180.857-75.143-180.857 75.143-75.143 180.857 75.143 180.857 180.857 75.143 180.857-75.143 75.143-180.857zM950.857 950.857q0 29.714-21.714 51.429t-51.429 21.714q-30.857 0-51.429-21.714l-196-195.429q-102.286 70.857-228 70.857-81.714 0-156.286-31.714t-128.571-85.714-85.714-128.571-31.714-156.286 31.714-156.286 85.714-128.571 128.571-85.714 156.286-31.714 156.286 31.714 128.571 85.714 85.714 128.571 31.714 156.286q0 125.714-70.857 228l196 196q21.143 21.143 21.143 51.429z"
81 | ],
82 | "width": 951,
83 | "attrs": [],
84 | "isMulticolor": false,
85 | "tags": [
86 | "search"
87 | ],
88 | "defaultCode": 61442,
89 | "grid": 14
90 | },
91 | "attrs": [],
92 | "properties": {
93 | "id": 2,
94 | "order": 1,
95 | "prevSize": 28,
96 | "code": 58887,
97 | "name": "icon-search"
98 | },
99 | "setIdx": 0,
100 | "iconIdx": 7
101 | }
102 | ],
103 | "height": 1024,
104 | "metadata": {
105 | "name": "slate",
106 | "license": "SIL OFL 1.1"
107 | },
108 | "preferences": {
109 | "showGlyphs": true,
110 | "showQuickUse": true,
111 | "showQuickUse2": true,
112 | "showSVGs": true,
113 | "fontPref": {
114 | "prefix": "icon-",
115 | "metadata": {
116 | "fontFamily": "slate",
117 | "majorVersion": 1,
118 | "minorVersion": 0,
119 | "description": "Based on FontAwesome",
120 | "license": "SIL OFL 1.1"
121 | },
122 | "metrics": {
123 | "emSize": 1024,
124 | "baseline": 6.25,
125 | "whitespace": 50
126 | },
127 | "resetPoint": 58880,
128 | "showSelector": false,
129 | "selector": "class",
130 | "classSelector": ".icon",
131 | "showMetrics": false,
132 | "showMetadata": true,
133 | "showVersion": true,
134 | "ie7": false
135 | },
136 | "imagePref": {
137 | "prefix": "icon-",
138 | "png": true,
139 | "useClassSelector": true,
140 | "color": 4473924,
141 | "bgColor": 16777215
142 | },
143 | "historySize": 100,
144 | "showCodes": true,
145 | "gridSize": 16,
146 | "showLiga": false
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/source/javascripts/app/_lang.js:
--------------------------------------------------------------------------------
1 | //= require ../lib/_jquery
2 |
3 | /*
4 | Copyright 2008-2013 Concur Technologies, Inc.
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License"); you may
7 | not use this file except in compliance with the License. You may obtain
8 | a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 | License for the specific language governing permissions and limitations
16 | under the License.
17 | */
18 | ;(function () {
19 | 'use strict';
20 |
21 | var languages = [];
22 |
23 | window.setupLanguages = setupLanguages;
24 | window.activateLanguage = activateLanguage;
25 | window.getLanguageFromQueryString = getLanguageFromQueryString;
26 |
27 | function activateLanguage(language) {
28 | if (!language) return;
29 | if (language === "") return;
30 |
31 | $(".lang-selector a").removeClass('active');
32 | $(".lang-selector a[data-language-name='" + language + "']").addClass('active');
33 | for (var i=0; i < languages.length; i++) {
34 | $(".highlight.tab-" + languages[i]).hide();
35 | $(".lang-specific." + languages[i]).hide();
36 | }
37 | $(".highlight.tab-" + language).show();
38 | $(".lang-specific." + language).show();
39 |
40 | window.recacheHeights();
41 |
42 | // scroll to the new location of the position
43 | if ($(window.location.hash).get(0)) {
44 | $(window.location.hash).get(0).scrollIntoView(true);
45 | }
46 | }
47 |
48 | // parseURL and stringifyURL are from https://github.com/sindresorhus/query-string
49 | // MIT licensed
50 | // https://github.com/sindresorhus/query-string/blob/7bee64c16f2da1a326579e96977b9227bf6da9e6/license
51 | function parseURL(str) {
52 | if (typeof str !== 'string') {
53 | return {};
54 | }
55 |
56 | str = str.trim().replace(/^(\?|#|&)/, '');
57 |
58 | if (!str) {
59 | return {};
60 | }
61 |
62 | return str.split('&').reduce(function (ret, param) {
63 | var parts = param.replace(/\+/g, ' ').split('=');
64 | var key = parts[0];
65 | var val = parts[1];
66 |
67 | key = decodeURIComponent(key);
68 | // missing `=` should be `null`:
69 | // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
70 | val = val === undefined ? null : decodeURIComponent(val);
71 |
72 | if (!ret.hasOwnProperty(key)) {
73 | ret[key] = val;
74 | } else if (Array.isArray(ret[key])) {
75 | ret[key].push(val);
76 | } else {
77 | ret[key] = [ret[key], val];
78 | }
79 |
80 | return ret;
81 | }, {});
82 | };
83 |
84 | function stringifyURL(obj) {
85 | return obj ? Object.keys(obj).sort().map(function (key) {
86 | var val = obj[key];
87 |
88 | if (Array.isArray(val)) {
89 | return val.sort().map(function (val2) {
90 | return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
91 | }).join('&');
92 | }
93 |
94 | return encodeURIComponent(key) + '=' + encodeURIComponent(val);
95 | }).join('&') : '';
96 | };
97 |
98 | // gets the language set in the query string
99 | function getLanguageFromQueryString() {
100 | if (location.search.length >= 1) {
101 | var language = parseURL(location.search).language;
102 | if (language) {
103 | return language;
104 | } else if (jQuery.inArray(location.search.substr(1), languages) != -1) {
105 | return location.search.substr(1);
106 | }
107 | }
108 |
109 | return false;
110 | }
111 |
112 | // returns a new query string with the new language in it
113 | function generateNewQueryString(language) {
114 | var url = parseURL(location.search);
115 | if (url.language) {
116 | url.language = language;
117 | return stringifyURL(url);
118 | }
119 | return language;
120 | }
121 |
122 | // if a button is clicked, add the state to the history
123 | function pushURL(language) {
124 | if (!history) { return; }
125 | var hash = window.location.hash;
126 | if (hash) {
127 | hash = hash.replace(/^#+/, '');
128 | }
129 | history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash);
130 |
131 | // save language as next default
132 | localStorage.setItem("language", language);
133 | }
134 |
135 | function setupLanguages(l) {
136 | var defaultLanguage = localStorage.getItem("language");
137 |
138 | languages = l;
139 |
140 | var presetLanguage = getLanguageFromQueryString();
141 | if (presetLanguage) {
142 | // the language is in the URL, so use that language!
143 | activateLanguage(presetLanguage);
144 |
145 | localStorage.setItem("language", presetLanguage);
146 | } else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) {
147 | // the language was the last selected one saved in localstorage, so use that language!
148 | activateLanguage(defaultLanguage);
149 | } else {
150 | // no language selected, so use the default
151 | activateLanguage(languages[0]);
152 | }
153 | }
154 |
155 | // if we click on a language tab, activate that language
156 | $(function() {
157 | $(".lang-selector a").on("click", function() {
158 | var language = $(this).data("language-name");
159 | pushURL(language);
160 | activateLanguage(language);
161 | return false;
162 | });
163 | });
164 | })();
165 |
--------------------------------------------------------------------------------
/source/includes/advanced.md:
--------------------------------------------------------------------------------
1 | # Advanced Settings
2 |
3 | The following section shows advanced configurations of the APIs.
4 |
5 | ## Spider Settings
6 |
7 | The following image shows the advanced configurations tab of Spider in the desktop UI.
8 |
9 | 
10 |
11 | Use the [setOptionMaxDepth](#spideractionsetoptionmaxdepth) API to set the maximum depth the spider can crawl, where 0 refers to unlimited depth.
12 | The [setOptionMaxChildren](#spideractionsetoptionmaxchildren) API sets the maximum number of child nodes (per node) that can be crawled,
13 | where 0 means no limit. The [setOptionMaxDuration](#spideractionsetoptionmaxduration) API can be used to set the maximum duration the Spider will run.
14 | Use the [setOptionMaxParseSizeBytes](#spideractionsetoptionmaxparsesizebytes) API to limit the amount of data parsed by the spider.
15 | This allows the spider to skip big responses/files.
16 |
17 | View the [Spider section](#spider) in the API Catalogue for additional APIs.
18 |
19 | ## Ajax Spider Settings
20 |
21 | The following image shows the advanced configurations tab of Ajax Spider in the desktop UI.
22 |
23 | 
24 |
25 | Similar to the Spider API, the Ajax spider also provides APIs to set the [maximum depth](#), [crawl state](#), and [maximum duration](#).
26 |
27 | ## Passive Scan Settings
28 |
29 | The scanning rules can be enabled/disabled using the [enableScanners](#pscanactionenablescanners) and [disableScanners]((#pscanactiondisablescanners)) APIs.
30 | Also use the [setScanOnlyInScope](#pscanviewscanonlyinscope) API to limit the passive scanning to a scope. View
31 | the advanced section to learn how to configure a context or scope using ZAP APIs.
32 |
33 | Passive scanning can also be used to automatically add tags and raise alerts for potential issues. A set of rules for
34 | automatic tagging are provided by default. These can be changed, deleted or added to via the Options Passive Scan Tags Screen.
35 |
36 | ## Active Scan Settings
37 |
38 | ### General Options
39 |
40 | The general options for Active Scan can be configured using the options tab in the desktop UI shown below.
41 |
42 | 
43 |
44 | Use the [setOptionMaxScanDurationInMins](#ascanactionsetoptionmaxscandurationinmins) API to limit the duration of scan and
45 | [setOptionMaxRuleDurationInMins](#ascanactionsetoptionmaxruledurationinmins) API to limit the time of individual active scan rules.
46 | This can be used to prevent rules from running for an excessive amount of time.
47 |
48 | Use the [setOptionHostPerScan](#ascanactionsetoptionhostperscan) API to set the maximum number of hosts that will be scanned at the same time.
49 | Furthermore, use the [setOptionThreadPerHost](#ascanactionsetoptionthreadperhost) API to set the number of threads the scanner will use per host.
50 | Increasing both of these values will reduce the active scanning time but this may put extra strain on the server ZAP is running on.
51 |
52 | Use the [setOptionDelayInMs](#ascanactionsetoptiondelayinms) API to delay each request from ZAP in milliseconds. Setting this to a non zero value will increase
53 | the time an active scan takes, but will put less of a strain on the target host. View the [Active Scan](#zap-api-ascan) section in
54 | the API Catalogue for additional information regarding the APIs.
55 |
56 | ### Input Vectors
57 |
58 | Input vectors refers to the elements that Active Scan will target. Specifying the exact elements to target will improve the
59 | scanning time and accuracy of the results. For example, for the following configuration the [optionTargetParamsInjectable](#ascanviewoptiontargetparamsinjectable) and
60 | [optionTargetParamsEnabledRPC](#ascanviewoptiontargetparamsenabledrpc) will yield the results of 11 and 39.
61 | The numbers can be deconstructed in the following manner:
62 |
63 | - 1+2+8 = 11 [Query String(1), Post Data(2), HTTP Headers(8)]
64 | - 1+2+4+32 = 39 [Multipart (1), XML (2), JSON (4), DWR (32)]
65 |
66 | 
67 |
68 | Thus, to change the values of `Injectable targets` and `Input Vector Handlers` calculate the exact values and
69 | use the [setoptiontargetparamsinjectable](#ascanactionsetoptiontargetparamsinjectable) and [setoptiontargetparamsenabledrpc](#ascanactionsetoptiontargetparamsenabledrpc) APIs accordingly.
70 |
71 | The `Add URL query parameter` option under the `Injectable Tragets` sets whether or not the active scanner should add a query param
72 | to GET requests which do not have parameters to start with. This option can be enabled using the [setoptionaddqueryparam](#ascanactionsetoptionaddqueryparam) API.
73 |
74 | ### Technology
75 |
76 | 
77 |
78 | The Technology tab allows you to specify which types of technologies to scan. Un-selecting technologies that you know are
79 | not present in the target application may speed up the scan, as rules which target that technology can skip those tests.
80 | For an example, if the target web application does not have a database then removing it will increase the performance of the Active Scan.
81 |
82 | Use the [includeContextTechnologies](#contextactionincludecontexttechnologies) and [excludeContextTechnologies](#contextactionexcludecontexttechnologies)
83 | API endpoints to include and exclude the technology list from the context.
84 |
85 | ### Policy
86 |
87 | A scan policy defines exactly which rules are run as part of an active scan. It also defines how these rules run influencing
88 | how many requests are made and how likely potential issues are to be flagged. You can define as many scan policies as you
89 | like and select the most appropriate one when you start the scan via the Active Scan.
90 |
91 | 
92 |
93 | The Policy tab shown in the above image allows you to override any of the settings specified in the selected scan policy.
94 |
--------------------------------------------------------------------------------
/source/includes/results.md:
--------------------------------------------------------------------------------
1 | # Getting the Results
2 |
3 | ```python
4 | #!/usr/bin/env python
5 | from zapv2 import ZAPv2
6 |
7 | # The URL of the application to be tested
8 | target = 'https://public-firing-range.appspot.com'
9 | # Change to match the API key set in ZAP, or use None if the API key is disabled
10 | apiKey = 'changeMe'
11 |
12 | # By default ZAP API client will connect to port 8080
13 | zap = ZAPv2(apikey=apiKey)
14 | # Use the line below if ZAP is not listening on port 8080, for example, if listening on port 8090
15 | # zap = ZAPv2(apikey=apiKey, proxies={'http': 'http://127.0.0.1:8090', 'https': 'http://127.0.0.1:8090'})
16 |
17 | # TODO: Check if the scanning has completed
18 |
19 | # Retrieve the alerts using paging in case there are lots of them
20 | st = 0
21 | pg = 5000
22 | alert_dict = {}
23 | alert_count = 0
24 | alerts = zap.alert.alerts(baseurl=target, start=st, count=pg)
25 | blacklist = [1,2]
26 | while len(alerts) > 0:
27 | print('Reading ' + str(pg) + ' alerts from ' + str(st))
28 | alert_count += len(alerts)
29 | for alert in alerts:
30 | plugin_id = alert.get('pluginId')
31 | if plugin_id in blacklist:
32 | continue
33 | if alert.get('risk') == 'High':
34 | # Trigger any relevant postprocessing
35 | continue
36 | if alert.get('risk') == 'Informational':
37 | # Ignore all info alerts - some of them may have been downgraded by security annotations
38 | continue
39 | st += pg
40 | alerts = zap.alert.alerts(start=st, count=pg)
41 | print('Total number of alerts: ' + str(alert_count))
42 | ```
43 |
44 | ```java
45 | public class Alerts {
46 |
47 | private static final String ZAP_ADDRESS = "localhost";
48 | private static final int ZAP_PORT = 8080;
49 | // Change to match the API key set in ZAP, or use NULL if the API key is disabled
50 | private static final String ZAP_API_KEY = "change me";
51 | // The URL of the application to be tested
52 | private static final String TARGET = "https://public-firing-range.appspot.com";
53 |
54 | private static List blackListPlugins = Arrays.asList("1000", "1025");
55 |
56 |
57 | public static void main(String[] args) {
58 | ClientApi api = new ClientApi(ZAP_ADDRESS, ZAP_PORT, ZAP_API_KEY);
59 |
60 | try {
61 | // TODO: Check if the scanning has completed
62 |
63 | // Retrieve the alerts using paging in case there are lots of them
64 | int start = 0;
65 | int count = 5000;
66 | int alertCount = 0;
67 | ApiResponse resp = api.alert.alerts(TARGET, String.valueOf(start), String.valueOf(count), null);
68 |
69 | while (((ApiResponseList) resp).getItems().size() != 0) {
70 | System.out.println("Reading " + count + " alerts from " + start);
71 | alertCount += ((ApiResponseList) resp).getItems().size();
72 |
73 | for (ApiResponse l : (((ApiResponseList) resp).getItems())) {
74 |
75 | Map element = ((ApiResponseSet) l).getValuesMap();
76 | if (blackListPlugins.contains(element.get("pluginId").toString())) {
77 | // TODO: Trigger any relevant postprocessing
78 | } else if ("High".equals(element.get("risk").toString())) {
79 | // TODO: Trigger any relevant postprocessing
80 | } else if ("Informational".equals(element.get("risk").toString())) {
81 | // TODO: Ignore all info alerts - some of them may have been downgraded by security annotations
82 | }
83 | }
84 | start += count;
85 | resp = api.alert.alerts(TARGET, String.valueOf(start), String.valueOf(count), null);
86 | }
87 | System.out.println("Total number of Alerts: " + alertCount);
88 |
89 | } catch (Exception e) {
90 | System.out.println("Exception : " + e.getMessage());
91 | e.printStackTrace();
92 | }
93 | }
94 | }
95 | ```
96 |
97 | ```shell
98 | # To view the alerts
99 | $ curl "http://localhost:8080/JSON/alert/view/alerts/?apikey=&baseurl=&start=0&count=5000&riskId="
100 |
101 | # To view the summary of the alerts
102 | $ curl "http://localhost:8080/JSON/alert/view/alertsSummary/?apikey=baseurl="
103 |
104 | # To view alerts by risk category
105 | $ curl "http://localhost:8080/JSON/alert/view/alertsByRisk/?apikey=&url=&recurse="
106 | ```
107 |
108 | After the scanning (Active/Passive) completes, ZAP provides the security vulnerabilities in the form of alerts. The alerts
109 | are categorized into high-priority, medium-priority, low-priority and informational priority risks. The priority indicates the degree of risk associated with each alert.
110 | For example, a high priority risk means that the issues listed in that category has more threat or risk potential than a medium-priority alert.
111 |
112 | The [alerts](#alertviewalerts) endpoint provides all the alerts which are identified by ZAP. View the sample code on the right to retrieve the
113 | alerts from the alerts endpoint. The results can be used to raise security alerts in the CI/CD pipeline or to trigger any custom workflows.
114 |
115 | 
116 |
117 | The [alerts summary](#alertviewalertssummary) gets the number of alerts grouped by each risk level and optionally filtering by URL.
118 | A Summary report can be also generated using the core module. Use the [htmlreport](#coreotherhtmlreport)
119 | or [jsonreport](#coreotherjsonreport) or [xmlreport](#coreotherxmlreport) endpoint to generate this summary report.
120 | The following image shows the report generated via the HTML report API. The report categories the alerts to risk level
121 | and provides a brief description about each alert.
122 |
123 | 
124 |
--------------------------------------------------------------------------------
/source/javascripts/lib/_energize.js:
--------------------------------------------------------------------------------
1 | /**
2 | * energize.js v0.1.0
3 | *
4 | * Speeds up click events on mobile devices.
5 | * https://github.com/davidcalhoun/energize.js
6 | */
7 |
8 | (function() { // Sandbox
9 | /**
10 | * Don't add to non-touch devices, which don't need to be sped up
11 | */
12 | if(!('ontouchstart' in window)) return;
13 |
14 | var lastClick = {},
15 | isThresholdReached, touchstart, touchmove, touchend,
16 | click, closest;
17 |
18 | /**
19 | * isThresholdReached
20 | *
21 | * Compare touchstart with touchend xy coordinates,
22 | * and only fire simulated click event if the coordinates
23 | * are nearby. (don't want clicking to be confused with a swipe)
24 | */
25 | isThresholdReached = function(startXY, xy) {
26 | return Math.abs(startXY[0] - xy[0]) > 5 || Math.abs(startXY[1] - xy[1]) > 5;
27 | };
28 |
29 | /**
30 | * touchstart
31 | *
32 | * Save xy coordinates when the user starts touching the screen
33 | */
34 | touchstart = function(e) {
35 | this.startXY = [e.touches[0].clientX, e.touches[0].clientY];
36 | this.threshold = false;
37 | };
38 |
39 | /**
40 | * touchmove
41 | *
42 | * Check if the user is scrolling past the threshold.
43 | * Have to check here because touchend will not always fire
44 | * on some tested devices (Kindle Fire?)
45 | */
46 | touchmove = function(e) {
47 | // NOOP if the threshold has already been reached
48 | if(this.threshold) return false;
49 |
50 | this.threshold = isThresholdReached(this.startXY, [e.touches[0].clientX, e.touches[0].clientY]);
51 | };
52 |
53 | /**
54 | * touchend
55 | *
56 | * If the user didn't scroll past the threshold between
57 | * touchstart and touchend, fire a simulated click.
58 | *
59 | * (This will fire before a native click)
60 | */
61 | touchend = function(e) {
62 | // Don't fire a click if the user scrolled past the threshold
63 | if(this.threshold || isThresholdReached(this.startXY, [e.changedTouches[0].clientX, e.changedTouches[0].clientY])) {
64 | return;
65 | }
66 |
67 | /**
68 | * Create and fire a click event on the target element
69 | * https://developer.mozilla.org/en/DOM/event.initMouseEvent
70 | */
71 | var touch = e.changedTouches[0],
72 | evt = document.createEvent('MouseEvents');
73 | evt.initMouseEvent('click', true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
74 | evt.simulated = true; // distinguish from a normal (nonsimulated) click
75 | e.target.dispatchEvent(evt);
76 | };
77 |
78 | /**
79 | * click
80 | *
81 | * Because we've already fired a click event in touchend,
82 | * we need to listed for all native click events here
83 | * and suppress them as necessary.
84 | */
85 | click = function(e) {
86 | /**
87 | * Prevent ghost clicks by only allowing clicks we created
88 | * in the click event we fired (look for e.simulated)
89 | */
90 | var time = Date.now(),
91 | timeDiff = time - lastClick.time,
92 | x = e.clientX,
93 | y = e.clientY,
94 | xyDiff = [Math.abs(lastClick.x - x), Math.abs(lastClick.y - y)],
95 | target = closest(e.target, 'A') || e.target, // needed for standalone apps
96 | nodeName = target.nodeName,
97 | isLink = nodeName === 'A',
98 | standAlone = window.navigator.standalone && isLink && e.target.getAttribute("href");
99 |
100 | lastClick.time = time;
101 | lastClick.x = x;
102 | lastClick.y = y;
103 |
104 | /**
105 | * Unfortunately Android sometimes fires click events without touch events (seen on Kindle Fire),
106 | * so we have to add more logic to determine the time of the last click. Not perfect...
107 | *
108 | * Older, simpler check: if((!e.simulated) || standAlone)
109 | */
110 | if((!e.simulated && (timeDiff < 500 || (timeDiff < 1500 && xyDiff[0] < 50 && xyDiff[1] < 50))) || standAlone) {
111 | e.preventDefault();
112 | e.stopPropagation();
113 | if(!standAlone) return false;
114 | }
115 |
116 | /**
117 | * Special logic for standalone web apps
118 | * See http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window
119 | */
120 | if(standAlone) {
121 | window.location = target.getAttribute("href");
122 | }
123 |
124 | /**
125 | * Add an energize-focus class to the targeted link (mimics :focus behavior)
126 | * TODO: test and/or remove? Does this work?
127 | */
128 | if(!target || !target.classList) return;
129 | target.classList.add("energize-focus");
130 | window.setTimeout(function(){
131 | target.classList.remove("energize-focus");
132 | }, 150);
133 | };
134 |
135 | /**
136 | * closest
137 | * @param {HTMLElement} node current node to start searching from.
138 | * @param {string} tagName the (uppercase) name of the tag you're looking for.
139 | *
140 | * Find the closest ancestor tag of a given node.
141 | *
142 | * Starts at node and goes up the DOM tree looking for a
143 | * matching nodeName, continuing until hitting document.body
144 | */
145 | closest = function(node, tagName){
146 | var curNode = node;
147 |
148 | while(curNode !== document.body) { // go up the dom until we find the tag we're after
149 | if(!curNode || curNode.nodeName === tagName) { return curNode; } // found
150 | curNode = curNode.parentNode; // not found, so keep going up
151 | }
152 |
153 | return null; // not found
154 | };
155 |
156 | /**
157 | * Add all delegated event listeners
158 | *
159 | * All the events we care about bubble up to document,
160 | * so we can take advantage of event delegation.
161 | *
162 | * Note: no need to wait for DOMContentLoaded here
163 | */
164 | document.addEventListener('touchstart', touchstart, false);
165 | document.addEventListener('touchmove', touchmove, false);
166 | document.addEventListener('touchend', touchend, false);
167 | document.addEventListener('click', click, true); // TODO: why does this use capture?
168 |
169 | })();
--------------------------------------------------------------------------------
/source/javascripts/lib/_imagesloaded.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * imagesLoaded PACKAGED v3.1.8
3 | * JavaScript is all like "You images are done yet or what?"
4 | * MIT License
5 | */
6 |
7 | (function(){function e(){}function t(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var i=e.prototype,r=this,o=r.EventEmitter;i.getListeners=function(e){var t,n,i=this._getEvents();if("object"==typeof e){t={};for(n in i)i.hasOwnProperty(n)&&e.test(n)&&(t[n]=i[n])}else t=i[e]||(i[e]=[]);return t},i.flattenListeners=function(e){var t,n=[];for(t=0;e.length>t;t+=1)n.push(e[t].listener);return n},i.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},i.addListener=function(e,n){var i,r=this.getListenersAsObject(e),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===t(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(e){return this.getListeners(e),this},i.defineEvents=function(e){for(var t=0;e.length>t;t+=1)this.defineEvent(e[t]);return this},i.removeListener=function(e,n){var i,r,o=this.getListenersAsObject(e);for(r in o)o.hasOwnProperty(r)&&(i=t(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},i.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},i.manipulateListeners=function(e,t,n){var i,r,o=e?this.removeListener:this.addListener,s=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(i=n.length;i--;)o.call(this,t,n[i]);else for(i in t)t.hasOwnProperty(i)&&(r=t[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(e){var t,n=typeof e,i=this._getEvents();if("string"===n)delete i[e];else if("object"===n)for(t in i)i.hasOwnProperty(t)&&e.test(t)&&delete i[t];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(e,t){var n,i,r,o,s=this.getListenersAsObject(e);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(e,n.listener),o=n.listener.apply(this,t||[]),o===this._getOnceReturnValue()&&this.removeListener(e,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},i.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},e.noConflict=function(){return r.EventEmitter=o,e},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return e}):"object"==typeof module&&module.exports?module.exports=e:this.EventEmitter=e}).call(this),function(e){function t(t){var n=e.event;return n.target=n.target||n.srcElement||t,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(e,t,n){e.addEventListener(t,n,!1)}:n.attachEvent&&(i=function(e,n,i){e[n+i]=i.handleEvent?function(){var n=t(e);i.handleEvent.call(i,n)}:function(){var n=t(e);i.call(e,n)},e.attachEvent("on"+n,e[n+i])});var r=function(){};n.removeEventListener?r=function(e,t,n){e.removeEventListener(t,n,!1)}:n.detachEvent&&(r=function(e,t,n){e.detachEvent("on"+t,e[t+n]);try{delete e[t+n]}catch(i){e[t+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):e.eventie=o}(this),function(e,t){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return t(e,n,i)}):"object"==typeof exports?module.exports=t(e,require("wolfy87-eventemitter"),require("eventie")):e.imagesLoaded=t(e,e.EventEmitter,e.eventie)}(window,function(e,t,n){function i(e,t){for(var n in t)e[n]=t[n];return e}function r(e){return"[object Array]"===d.call(e)}function o(e){var t=[];if(r(e))t=e;else if("number"==typeof e.length)for(var n=0,i=e.length;i>n;n++)t.push(e[n]);else t.push(e);return t}function s(e,t,n){if(!(this instanceof s))return new s(e,t);"string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=o(e),this.options=i({},this.options),"function"==typeof t?n=t:i(this.options,t),n&&this.on("always",n),this.getImages(),a&&(this.jqDeferred=new a.Deferred);var r=this;setTimeout(function(){r.check()})}function f(e){this.img=e}function c(e){this.src=e,v[e]=this}var a=e.jQuery,u=e.console,h=u!==void 0,d=Object.prototype.toString;s.prototype=new t,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var e=0,t=this.elements.length;t>e;e++){var n=this.elements[e];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var f=r[o];this.addImage(f)}}},s.prototype.addImage=function(e){var t=new f(e);this.images.push(t)},s.prototype.check=function(){function e(e,r){return t.options.debug&&h&&u.log("confirm",e,r),t.progress(e),n++,n===i&&t.complete(),!0}var t=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return this.complete(),void 0;for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",e),o.check()}},s.prototype.progress=function(e){this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded;var t=this;setTimeout(function(){t.emit("progress",t,e),t.jqDeferred&&t.jqDeferred.notify&&t.jqDeferred.notify(t,e)})},s.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var t=this;setTimeout(function(){if(t.emit(e,t),t.emit("always",t),t.jqDeferred){var n=t.hasAnyBroken?"reject":"resolve";t.jqDeferred[n](t)}})},a&&(a.fn.imagesLoaded=function(e,t){var n=new s(this,e,t);return n.jqDeferred.promise(a(this))}),f.prototype=new t,f.prototype.check=function(){var e=v[this.img.src]||new c(this.img.src);if(e.isConfirmed)return this.confirm(e.isLoaded,"cached was confirmed"),void 0;if(this.img.complete&&void 0!==this.img.naturalWidth)return this.confirm(0!==this.img.naturalWidth,"naturalWidth"),void 0;var t=this;e.on("confirm",function(e,n){return t.confirm(e.isLoaded,n),!0}),e.check()},f.prototype.confirm=function(e,t){this.isLoaded=e,this.emit("confirm",this,t)};var v={};return c.prototype=new t,c.prototype.check=function(){if(!this.isChecked){var e=new Image;n.bind(e,"load",this),n.bind(e,"error",this),e.src=this.src,this.isChecked=!0}},c.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},c.prototype.onload=function(e){this.confirm(!0,"onload"),this.unbindProxyEvents(e)},c.prototype.onerror=function(e){this.confirm(!1,"onerror"),this.unbindProxyEvents(e)},c.prototype.confirm=function(e,t){this.isConfirmed=!0,this.isLoaded=e,this.emit("confirm",this,t)},c.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s});
--------------------------------------------------------------------------------
/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -o errexit #abort if any command fails
3 | me=$(basename "$0")
4 |
5 | help_message="\
6 | Usage: $me [-c FILE] []
7 | Deploy generated files to a git branch.
8 |
9 | Options:
10 |
11 | -h, --help Show this help information.
12 | -v, --verbose Increase verbosity. Useful for debugging.
13 | -e, --allow-empty Allow deployment of an empty directory.
14 | -m, --message MESSAGE Specify the message used when committing on the
15 | deploy branch.
16 | -n, --no-hash Don't append the source commit's hash to the deploy
17 | commit's message.
18 | --source-only Only build but not push
19 | --push-only Only push but not build
20 | "
21 |
22 |
23 | run_build() {
24 | bundle exec middleman build --clean
25 | }
26 |
27 | parse_args() {
28 | # Set args from a local environment file.
29 | if [ -e ".env" ]; then
30 | source .env
31 | fi
32 |
33 | # Parse arg flags
34 | # If something is exposed as an environment variable, set/overwrite it
35 | # here. Otherwise, set/overwrite the internal variable instead.
36 | while : ; do
37 | if [[ $1 = "-h" || $1 = "--help" ]]; then
38 | echo "$help_message"
39 | return 0
40 | elif [[ $1 = "-v" || $1 = "--verbose" ]]; then
41 | verbose=true
42 | shift
43 | elif [[ $1 = "-e" || $1 = "--allow-empty" ]]; then
44 | allow_empty=true
45 | shift
46 | elif [[ ( $1 = "-m" || $1 = "--message" ) && -n $2 ]]; then
47 | commit_message=$2
48 | shift 2
49 | elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then
50 | GIT_DEPLOY_APPEND_HASH=false
51 | shift
52 | else
53 | break
54 | fi
55 | done
56 |
57 | # Set internal option vars from the environment and arg flags. All internal
58 | # vars should be declared here, with sane defaults if applicable.
59 |
60 | # Source directory & target branch.
61 | deploy_directory=build
62 | deploy_branch=gh-pages
63 |
64 | #if no user identity is already set in the current git environment, use this:
65 | default_username=${GIT_DEPLOY_USERNAME:-deploy.sh}
66 | default_email=${GIT_DEPLOY_EMAIL:-}
67 |
68 | #repository to deploy to. must be readable and writable.
69 | repo=origin
70 |
71 | #append commit hash to the end of message by default
72 | append_hash=${GIT_DEPLOY_APPEND_HASH:-true}
73 | }
74 |
75 | main() {
76 | parse_args "$@"
77 |
78 | enable_expanded_output
79 |
80 | if ! git diff --exit-code --quiet --cached; then
81 | echo Aborting due to uncommitted changes in the index >&2
82 | return 1
83 | fi
84 |
85 | commit_title=`git log -n 1 --format="%s" HEAD`
86 | commit_hash=` git log -n 1 --format="%H" HEAD`
87 |
88 | #default commit message uses last title if a custom one is not supplied
89 | if [[ -z $commit_message ]]; then
90 | commit_message="publish: $commit_title"
91 | fi
92 |
93 | #append hash to commit message unless no hash flag was found
94 | if [ $append_hash = true ]; then
95 | commit_message="$commit_message"$'\n\n'"generated from commit $commit_hash"
96 | fi
97 |
98 | previous_branch=`git rev-parse --abbrev-ref HEAD`
99 |
100 | if [ ! -d "$deploy_directory" ]; then
101 | echo "Deploy directory '$deploy_directory' does not exist. Aborting." >&2
102 | return 1
103 | fi
104 |
105 | # must use short form of flag in ls for compatibility with macOS and BSD
106 | if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then
107 | echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2
108 | return 1
109 | fi
110 |
111 | if git ls-remote --exit-code $repo "refs/heads/$deploy_branch" ; then
112 | # deploy_branch exists in $repo; make sure we have the latest version
113 |
114 | disable_expanded_output
115 | git fetch --force $repo $deploy_branch:$deploy_branch
116 | enable_expanded_output
117 | fi
118 |
119 | # check if deploy_branch exists locally
120 | if git show-ref --verify --quiet "refs/heads/$deploy_branch"
121 | then incremental_deploy
122 | else initial_deploy
123 | fi
124 |
125 | restore_head
126 | }
127 |
128 | initial_deploy() {
129 | git --work-tree "$deploy_directory" checkout --orphan $deploy_branch
130 | git --work-tree "$deploy_directory" add --all
131 | commit+push
132 | }
133 |
134 | incremental_deploy() {
135 | #make deploy_branch the current branch
136 | git symbolic-ref HEAD refs/heads/$deploy_branch
137 | #put the previously committed contents of deploy_branch into the index
138 | git --work-tree "$deploy_directory" reset --mixed --quiet
139 | git --work-tree "$deploy_directory" add --all
140 |
141 | set +o errexit
142 | diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD --)$?
143 | set -o errexit
144 | case $diff in
145 | 0) echo No changes to files in $deploy_directory. Skipping commit.;;
146 | 1) commit+push;;
147 | *)
148 | echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to master, use: git symbolic-ref HEAD refs/heads/master && git reset --mixed >&2
149 | return $diff
150 | ;;
151 | esac
152 | }
153 |
154 | commit+push() {
155 | set_user_id
156 | git --work-tree "$deploy_directory" commit -m "$commit_message"
157 |
158 | disable_expanded_output
159 | #--quiet is important here to avoid outputting the repo URL, which may contain a secret token
160 | git push --quiet $repo $deploy_branch
161 | enable_expanded_output
162 | }
163 |
164 | #echo expanded commands as they are executed (for debugging)
165 | enable_expanded_output() {
166 | if [ $verbose ]; then
167 | set -o xtrace
168 | set +o verbose
169 | fi
170 | }
171 |
172 | #this is used to avoid outputting the repo URL, which may contain a secret token
173 | disable_expanded_output() {
174 | if [ $verbose ]; then
175 | set +o xtrace
176 | set -o verbose
177 | fi
178 | }
179 |
180 | set_user_id() {
181 | if [[ -z `git config user.name` ]]; then
182 | git config user.name "$default_username"
183 | fi
184 | if [[ -z `git config user.email` ]]; then
185 | git config user.email "$default_email"
186 | fi
187 | }
188 |
189 | restore_head() {
190 | if [[ $previous_branch = "HEAD" ]]; then
191 | #we weren't on any branch before, so just set HEAD back to the commit it was on
192 | git update-ref --no-deref HEAD $commit_hash $deploy_branch
193 | else
194 | git symbolic-ref HEAD refs/heads/$previous_branch
195 | fi
196 |
197 | git reset --mixed
198 | }
199 |
200 | filter() {
201 | sed -e "s|$repo|\$repo|g"
202 | }
203 |
204 | sanitize() {
205 | "$@" 2> >(filter 1>&2) | filter
206 | }
207 |
208 | if [[ $1 = --source-only ]]; then
209 | run_build
210 | elif [[ $1 = --push-only ]]; then
211 | main "$@"
212 | else
213 | run_build
214 | main "$@"
215 | fi
216 |
--------------------------------------------------------------------------------
/source/includes/contributing.md:
--------------------------------------------------------------------------------
1 | # Contributions Welcome!
2 |
3 | Contributions are welcome! There are many ways you can contribute to ZAP, both as a user and as a developer.
4 |
5 | **1. Creating High-level API/Automation Docs**
6 |
7 | Create high level docs or example guides on how to use the APIs to perform any action/view with ZAP.
8 | The source files for the ZAP API documentation is hosted on GitHub. The repository is available at [Github](https://github.com/zaproxy/zap-api-docs).
9 | The source files are in `Markdown` (md) format.
10 |
11 | **2. REST API Documentation**
12 |
13 | ZAP's rest API is documented using the OpenAPI specification. The specification could be improved by enhancing the description of
14 | parameters/ results/ data types etc. The open API specification is available via [GitHub](https://github.com/zaproxy/zap-api-docs/blob/main/openapi.yaml).
15 |
16 | **3. Feature Documentation**
17 |
18 | Feature documentation related to ZAP is available on [ZAP wiki](https://github.com/zaproxy/zaproxy/wiki),
19 | [ZAP user guide](https://www.zaproxy.org/docs/desktop/), and [ZAP extensions](https://github.com/zaproxy/zap-extensions/wiki) repositories.
20 |
21 |
22 | ## How to Contribute
23 |
24 | The ZAP API documentation is developed according to the [docs as code](https://www.writethedocs.org/guide/docs-as-code/) philosophy.
25 | The most direct and effective way to contribute to the docs is to submit a pull request(PR) or raise an
26 | issue in the GitHub repository containing the docs content that you want to change.
27 |
28 | There are 2 different workflows which you can use to make changes or PRs. Use what you are most comfortable with!
29 |
30 | **1. "Edit this File on GitHub"**
31 |
32 | You can edit the documentation in the browser via navigating to the relevant source file and clicking the edit this file button.
33 | This workflow is recommended for minor changes. For example correcting typos/spellings/grammar etc.
34 | For extensive changes, please use the local setup and editing option.
35 |
36 | **2. Local Setup and Editing**
37 |
38 | You can fork the repository on GitHub and submit the changes via [pull requests](https://help.github.com/en/articles/creating-a-pull-request-from-a-fork).
39 | Please see the local setup for API docs section to setup and render the docs locally.
40 |
41 |
44 |
45 | ## Local Setup for API Docs
46 |
47 | ZAP uses git for its code repository.
48 | To submit a documentation update, use the following steps:
49 |
50 | **1. Clone the ZAP Docs repository:**
51 | `git clone https://github.com/zaproxy/zap-api-docs`
52 |
53 | **2. Navigate to the cloned repository:**
54 | `cd zap-api-docs`
55 |
56 | **3. Use the following guide to install [Ruby](https://www.ruby-lang.org/en/documentation/installation/)**
57 |
58 | **4. To install the dependencies:** `$ bundle install`
59 |
60 | **5. To start the server:** `$ bundle exec middleman server`
61 |
62 | ## Documentation Style
63 |
64 | This style guide provides a set of editorial guidelines for anyone writing documentation for ZAP.
65 |
66 | ### General Guidelines
67 |
68 | * Check for the grammar and spellings before sending the pull request. Most of the modern editors comes with a spell
69 | check option or plugin.
70 |
71 | * Use a friendly and conversational tone. Always use simple sentences. If the sentence is lengthy try to break it in to smaller sentences.
72 | Also avoid sentences with complicated words or jargon.
73 |
74 | * Write positively and avoid using negative sentences.
75 |
76 | - Recommended: If you are not familiar with the Spider, then read this documentation.
77 | - Not Recommended: Read this documentation to get familiarized with the Spider.
78 |
79 | * The documentation should be neutral, without judgments, opinions. For example, words like "easily" or "simple" come with
80 | a lot of assumptions. Things that are easier for you might be difficult for another person. Avoid this type of wordings
81 | when contributing to the document.
82 |
83 | ### Language and Grammar
84 |
85 | * Abbreviation
86 |
87 | Spell out the abbreviation or acronym before introducing them in the sentence. If the abbreviation is well known such as
88 | API or ZAP or HTML, you can use it without spelling it first.
89 |
90 | * Active Voice
91 |
92 | In general use active voice when formulating the sentence instead of passive voice. A sentence written in the active voice will emphasize
93 | the person or thing who is performing an action (eg.The dog chased the ball). In contrast, the passive voice will highlight
94 | the recipient of the action (The ball was chased by the dog). Therefor use the passive voice, only when it's less important
95 | who or what completed the action and more important that the action was completed. For example:
96 |
97 | - Recommended: The Spider crawls the URLs.
98 | - Not recommended: The URLs are crawled by the Spider.
99 |
100 | * Gender References
101 |
102 | Use gender neutral pronouns (they/their/them) when referring to a hypothetical person such as "a user with a logged in session".
103 | For example, instead of:
104 | - he or she, use they;
105 | - him or her, use them;
106 | - his or her, use their;
107 | - his or hers, use theirs;
108 | - himself or herself, use themselves;
109 |
110 | * Method Description
111 |
112 | When you're writing reference documentation for a method, phrase the main method description in terms of what it does
113 | ("Gets," "Starts," "Creates," "Lists"), rather than what the developer would use it to do ("Get," "Start," "Create," "List").
114 |
115 | - Recommended: action.scan: Starts the Spider on the specified URL.
116 | - Not recommended: action.scan: Start the Spider on the specified URL.
117 |
118 | * Second Person
119 |
120 | In general, use second person in your docs rather than first person. For example:
121 |
122 | - Recommended: You are recommended to use the Spider.
123 | - Not Recommended: We recommend to use the Spider.
124 |
125 | * Spellings
126 |
127 | Use [American spellings](https://www.oxfordinternationalenglish.com/differences-in-british-and-american-spelling/) when
128 | contributing to the documentation.
129 |
130 | ### Formatting
131 |
132 | * Capitalization:
133 |
134 | * Use the Chicago manual for capitalization rules for the documentation.
135 |
136 | * For titles of a section, Capitalize of the first letter of each word except for the [closed-class words](http://babelnet.sbg.ac.at/themepark/grammar/classes.htm)
137 | such as determiners, pronouns, conjunctions, and prepositions. Use the following [link](https://capitalizemytitle.com/#Chicago) for guidance.
138 | - Recommended: The Spider Tutorial **with** APIs
139 |
140 | * For normal sentences don't [capitalize](https://www.grammarly.com/blog/capitalization-rules/) random words in the middle of the sentences.
141 |
142 | * Number formatting
143 | * In general spell out the number if it starts a sentence or is less than ten or an ordinal number.
144 | - Recommended: Seventeen requests has been intercepted by the passive scanner.
145 | - Recommended: The passive scan showed nine warnings.
146 | - Recommended: The fifth alert was a high priority alert.
147 |
148 | * Use numerals for numbers higher than ten or fractions or unit prices.
149 | - Recommended: The active scanner detected 24 issues.
150 | - Recommended: The scanner took 23.4 seconds to complete the crawling.
151 |
152 | ### Punctuation
153 |
154 | * Commas
155 | * Use oxford commas when writing a list of three or more items
156 | - Recommended: The API can return the results in XML, JSON, and HTML.
157 | - Not Recommended: The API can return the results in XML, JSON and HTML.
158 |
159 | * Periods
160 | * Do not add period to headings or titles.
161 | * Avoid using periods at the end of URLs. Try to modify the sentence so the URL can be in the middle of the sentence.
162 |
163 | ## Markdown Syntax
164 |
165 | The API docs are created using standard markdown files. This section contains information regarding the syntax and linting of the Markdown files.
166 | Refer to the [Slate documentation](https://github.com/slatedocs/slate/wiki/Markdown-Syntax). Also refer to this
167 | [document](https://github.com/markdownlint/markdownlint/edit/master/docs/RULES.md) to properly lint the Markdown files.
168 |
169 | ### Writing Code
170 |
171 | **Inline Code**
172 |
173 | Put \``backticks`\` around the following symbols when used in text:
174 |
175 | * Data types: `json`, `xml`, `html`
176 | * File name: `test.py`, `/path-to-your-data/xml/example-name`
177 |
178 | **Code Block**
179 |
180 | Use three back ticks to open and close a code block. Specify the programming language after the first backtick group.
181 | The documentation currently supports `python`, `java`, and `shell` languages.
182 |
183 | 
184 |
--------------------------------------------------------------------------------
/source/stylesheets/_normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11
29 | * and Firefox.
30 | * Correct `block` display not defined for `main` in IE 11.
31 | */
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | main,
42 | menu,
43 | nav,
44 | section,
45 | summary {
46 | display: block;
47 | }
48 |
49 | /**
50 | * 1. Correct `inline-block` display not defined in IE 8/9.
51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52 | */
53 |
54 | audio,
55 | canvas,
56 | progress,
57 | video {
58 | display: inline-block; /* 1 */
59 | vertical-align: baseline; /* 2 */
60 | }
61 |
62 | /**
63 | * Prevent modern browsers from displaying `audio` without controls.
64 | * Remove excess height in iOS 5 devices.
65 | */
66 |
67 | audio:not([controls]) {
68 | display: none;
69 | height: 0;
70 | }
71 |
72 | /**
73 | * Address `[hidden]` styling not present in IE 8/9/10.
74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
75 | */
76 |
77 | [hidden],
78 | template {
79 | display: none;
80 | }
81 |
82 | /* Links
83 | ========================================================================== */
84 |
85 | /**
86 | * Remove the gray background color from active links in IE 10.
87 | */
88 |
89 | a {
90 | background-color: transparent;
91 | }
92 |
93 | /**
94 | * Improve readability when focused and also mouse hovered in all browsers.
95 | */
96 |
97 | a:active,
98 | a:hover {
99 | outline: 0;
100 | }
101 |
102 | /* Text-level semantics
103 | ========================================================================== */
104 |
105 | /**
106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
107 | */
108 |
109 | abbr[title] {
110 | border-bottom: 1px dotted;
111 | }
112 |
113 | /**
114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
115 | */
116 |
117 | b,
118 | strong {
119 | font-weight: bold;
120 | }
121 |
122 | /**
123 | * Address styling not present in Safari and Chrome.
124 | */
125 |
126 | dfn {
127 | font-style: italic;
128 | }
129 |
130 | /**
131 | * Address variable `h1` font-size and margin within `section` and `article`
132 | * contexts in Firefox 4+, Safari, and Chrome.
133 | */
134 |
135 | h1 {
136 | font-size: 2em;
137 | margin: 0.67em 0;
138 | }
139 |
140 | /**
141 | * Address styling not present in IE 8/9.
142 | */
143 |
144 | mark {
145 | background: #ff0;
146 | color: #000;
147 | }
148 |
149 | /**
150 | * Address inconsistent and variable font size in all browsers.
151 | */
152 |
153 | small {
154 | font-size: 80%;
155 | }
156 |
157 | /**
158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
159 | */
160 |
161 | sub,
162 | sup {
163 | font-size: 75%;
164 | line-height: 0;
165 | position: relative;
166 | vertical-align: baseline;
167 | }
168 |
169 | sup {
170 | top: -0.5em;
171 | }
172 |
173 | sub {
174 | bottom: -0.25em;
175 | }
176 |
177 | /* Embedded content
178 | ========================================================================== */
179 |
180 | /**
181 | * Remove border when inside `a` element in IE 8/9/10.
182 | */
183 |
184 | img {
185 | border: 0;
186 | }
187 |
188 | /**
189 | * Correct overflow not hidden in IE 9/10/11.
190 | */
191 |
192 | svg:not(:root) {
193 | overflow: hidden;
194 | }
195 |
196 | /* Grouping content
197 | ========================================================================== */
198 |
199 | /**
200 | * Address margin not present in IE 8/9 and Safari.
201 | */
202 |
203 | figure {
204 | margin: 1em 40px;
205 | }
206 |
207 | /**
208 | * Address differences between Firefox and other browsers.
209 | */
210 |
211 | hr {
212 | -moz-box-sizing: content-box;
213 | box-sizing: content-box;
214 | height: 0;
215 | }
216 |
217 | /**
218 | * Contain overflow in all browsers.
219 | */
220 |
221 | pre {
222 | overflow: auto;
223 | }
224 |
225 | /**
226 | * Address odd `em`-unit font size rendering in all browsers.
227 | */
228 |
229 | code,
230 | kbd,
231 | pre,
232 | samp {
233 | font-family: monospace, monospace;
234 | font-size: 1em;
235 | }
236 |
237 | /* Forms
238 | ========================================================================== */
239 |
240 | /**
241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
242 | * styling of `select`, unless a `border` property is set.
243 | */
244 |
245 | /**
246 | * 1. Correct color not being inherited.
247 | * Known issue: affects color of disabled elements.
248 | * 2. Correct font properties not being inherited.
249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250 | */
251 |
252 | button,
253 | input,
254 | optgroup,
255 | select,
256 | textarea {
257 | color: inherit; /* 1 */
258 | font: inherit; /* 2 */
259 | margin: 0; /* 3 */
260 | }
261 |
262 | /**
263 | * Address `overflow` set to `hidden` in IE 8/9/10/11.
264 | */
265 |
266 | button {
267 | overflow: visible;
268 | }
269 |
270 | /**
271 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
272 | * All other form control elements do not inherit `text-transform` values.
273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
274 | * Correct `select` style inheritance in Firefox.
275 | */
276 |
277 | button,
278 | select {
279 | text-transform: none;
280 | }
281 |
282 | /**
283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
284 | * and `video` controls.
285 | * 2. Correct inability to style clickable `input` types in iOS.
286 | * 3. Improve usability and consistency of cursor style between image-type
287 | * `input` and others.
288 | */
289 |
290 | button,
291 | html input[type="button"], /* 1 */
292 | input[type="reset"],
293 | input[type="submit"] {
294 | -webkit-appearance: button; /* 2 */
295 | cursor: pointer; /* 3 */
296 | }
297 |
298 | /**
299 | * Re-set default cursor for disabled elements.
300 | */
301 |
302 | button[disabled],
303 | html input[disabled] {
304 | cursor: default;
305 | }
306 |
307 | /**
308 | * Remove inner padding and border in Firefox 4+.
309 | */
310 |
311 | button::-moz-focus-inner,
312 | input::-moz-focus-inner {
313 | border: 0;
314 | padding: 0;
315 | }
316 |
317 | /**
318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
319 | * the UA stylesheet.
320 | */
321 |
322 | input {
323 | line-height: normal;
324 | }
325 |
326 | /**
327 | * It's recommended that you don't attempt to style these elements.
328 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
329 | *
330 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
331 | * 2. Remove excess padding in IE 8/9/10.
332 | */
333 |
334 | input[type="checkbox"],
335 | input[type="radio"] {
336 | box-sizing: border-box; /* 1 */
337 | padding: 0; /* 2 */
338 | }
339 |
340 | /**
341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
342 | * `font-size` values of the `input`, it causes the cursor style of the
343 | * decrement button to change from `default` to `text`.
344 | */
345 |
346 | input[type="number"]::-webkit-inner-spin-button,
347 | input[type="number"]::-webkit-outer-spin-button {
348 | height: auto;
349 | }
350 |
351 | /**
352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
354 | * (include `-moz` to future-proof).
355 | */
356 |
357 | input[type="search"] {
358 | -webkit-appearance: textfield; /* 1 */
359 | -moz-box-sizing: content-box;
360 | -webkit-box-sizing: content-box; /* 2 */
361 | box-sizing: content-box;
362 | }
363 |
364 | /**
365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
366 | * Safari (but not Chrome) clips the cancel button when the search input has
367 | * padding (and `textfield` appearance).
368 | */
369 |
370 | input[type="search"]::-webkit-search-cancel-button,
371 | input[type="search"]::-webkit-search-decoration {
372 | -webkit-appearance: none;
373 | }
374 |
375 | /**
376 | * Define consistent border, margin, and padding.
377 | */
378 |
379 | fieldset {
380 | border: 1px solid #c0c0c0;
381 | margin: 0 2px;
382 | padding: 0.35em 0.625em 0.75em;
383 | }
384 |
385 | /**
386 | * 1. Correct `color` not being inherited in IE 8/9/10/11.
387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
388 | */
389 |
390 | legend {
391 | border: 0; /* 1 */
392 | padding: 0; /* 2 */
393 | }
394 |
395 | /**
396 | * Remove default vertical scrollbar in IE 8/9/10/11.
397 | */
398 |
399 | textarea {
400 | overflow: auto;
401 | }
402 |
403 | /**
404 | * Don't inherit the `font-weight` (applied by a rule above).
405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
406 | */
407 |
408 | optgroup {
409 | font-weight: bold;
410 | }
411 |
412 | /* Tables
413 | ========================================================================== */
414 |
415 | /**
416 | * Remove most spacing between table cells.
417 | */
418 |
419 | table {
420 | border-collapse: collapse;
421 | border-spacing: 0;
422 | }
423 |
424 | td,
425 | th {
426 | padding: 0;
427 | }
428 |
--------------------------------------------------------------------------------
/source/stylesheets/_normalize.scss:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11
29 | * and Firefox.
30 | * Correct `block` display not defined for `main` in IE 11.
31 | */
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | main,
42 | menu,
43 | nav,
44 | section,
45 | summary {
46 | display: block;
47 | }
48 |
49 | /**
50 | * 1. Correct `inline-block` display not defined in IE 8/9.
51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52 | */
53 |
54 | audio,
55 | canvas,
56 | progress,
57 | video {
58 | display: inline-block; /* 1 */
59 | vertical-align: baseline; /* 2 */
60 | }
61 |
62 | /**
63 | * Prevent modern browsers from displaying `audio` without controls.
64 | * Remove excess height in iOS 5 devices.
65 | */
66 |
67 | audio:not([controls]) {
68 | display: none;
69 | height: 0;
70 | }
71 |
72 | /**
73 | * Address `[hidden]` styling not present in IE 8/9/10.
74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
75 | */
76 |
77 | [hidden],
78 | template {
79 | display: none;
80 | }
81 |
82 | /* Links
83 | ========================================================================== */
84 |
85 | /**
86 | * Remove the gray background color from active links in IE 10.
87 | */
88 |
89 | a {
90 | background-color: transparent;
91 | }
92 |
93 | /**
94 | * Improve readability when focused and also mouse hovered in all browsers.
95 | */
96 |
97 | a:active,
98 | a:hover {
99 | outline: 0;
100 | }
101 |
102 | /* Text-level semantics
103 | ========================================================================== */
104 |
105 | /**
106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
107 | */
108 |
109 | abbr[title] {
110 | border-bottom: 1px dotted;
111 | }
112 |
113 | /**
114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
115 | */
116 |
117 | b,
118 | strong {
119 | font-weight: bold;
120 | }
121 |
122 | /**
123 | * Address styling not present in Safari and Chrome.
124 | */
125 |
126 | dfn {
127 | font-style: italic;
128 | }
129 |
130 | /**
131 | * Address variable `h1` font-size and margin within `section` and `article`
132 | * contexts in Firefox 4+, Safari, and Chrome.
133 | */
134 |
135 | h1 {
136 | font-size: 2em;
137 | margin: 0.67em 0;
138 | }
139 |
140 | /**
141 | * Address styling not present in IE 8/9.
142 | */
143 |
144 | mark {
145 | background: #ff0;
146 | color: #000;
147 | }
148 |
149 | /**
150 | * Address inconsistent and variable font size in all browsers.
151 | */
152 |
153 | small {
154 | font-size: 80%;
155 | }
156 |
157 | /**
158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
159 | */
160 |
161 | sub,
162 | sup {
163 | font-size: 75%;
164 | line-height: 0;
165 | position: relative;
166 | vertical-align: baseline;
167 | }
168 |
169 | sup {
170 | top: -0.5em;
171 | }
172 |
173 | sub {
174 | bottom: -0.25em;
175 | }
176 |
177 | /* Embedded content
178 | ========================================================================== */
179 |
180 | /**
181 | * Remove border when inside `a` element in IE 8/9/10.
182 | */
183 |
184 | img {
185 | border: 0;
186 | }
187 |
188 | /**
189 | * Correct overflow not hidden in IE 9/10/11.
190 | */
191 |
192 | svg:not(:root) {
193 | overflow: hidden;
194 | }
195 |
196 | /* Grouping content
197 | ========================================================================== */
198 |
199 | /**
200 | * Address margin not present in IE 8/9 and Safari.
201 | */
202 |
203 | figure {
204 | margin: 1em 40px;
205 | }
206 |
207 | /**
208 | * Address differences between Firefox and other browsers.
209 | */
210 |
211 | hr {
212 | -moz-box-sizing: content-box;
213 | box-sizing: content-box;
214 | height: 0;
215 | }
216 |
217 | /**
218 | * Contain overflow in all browsers.
219 | */
220 |
221 | pre {
222 | overflow: auto;
223 | }
224 |
225 | /**
226 | * Address odd `em`-unit font size rendering in all browsers.
227 | */
228 |
229 | code,
230 | kbd,
231 | pre,
232 | samp {
233 | font-family: monospace, monospace;
234 | font-size: 1em;
235 | }
236 |
237 | /* Forms
238 | ========================================================================== */
239 |
240 | /**
241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
242 | * styling of `select`, unless a `border` property is set.
243 | */
244 |
245 | /**
246 | * 1. Correct color not being inherited.
247 | * Known issue: affects color of disabled elements.
248 | * 2. Correct font properties not being inherited.
249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250 | */
251 |
252 | button,
253 | input,
254 | optgroup,
255 | select,
256 | textarea {
257 | color: inherit; /* 1 */
258 | font: inherit; /* 2 */
259 | margin: 0; /* 3 */
260 | }
261 |
262 | /**
263 | * Address `overflow` set to `hidden` in IE 8/9/10/11.
264 | */
265 |
266 | button {
267 | overflow: visible;
268 | }
269 |
270 | /**
271 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
272 | * All other form control elements do not inherit `text-transform` values.
273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
274 | * Correct `select` style inheritance in Firefox.
275 | */
276 |
277 | button,
278 | select {
279 | text-transform: none;
280 | }
281 |
282 | /**
283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
284 | * and `video` controls.
285 | * 2. Correct inability to style clickable `input` types in iOS.
286 | * 3. Improve usability and consistency of cursor style between image-type
287 | * `input` and others.
288 | */
289 |
290 | button,
291 | html input[type="button"], /* 1 */
292 | input[type="reset"],
293 | input[type="submit"] {
294 | -webkit-appearance: button; /* 2 */
295 | cursor: pointer; /* 3 */
296 | }
297 |
298 | /**
299 | * Re-set default cursor for disabled elements.
300 | */
301 |
302 | button[disabled],
303 | html input[disabled] {
304 | cursor: default;
305 | }
306 |
307 | /**
308 | * Remove inner padding and border in Firefox 4+.
309 | */
310 |
311 | button::-moz-focus-inner,
312 | input::-moz-focus-inner {
313 | border: 0;
314 | padding: 0;
315 | }
316 |
317 | /**
318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
319 | * the UA stylesheet.
320 | */
321 |
322 | input {
323 | line-height: normal;
324 | }
325 |
326 | /**
327 | * It's recommended that you don't attempt to style these elements.
328 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
329 | *
330 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
331 | * 2. Remove excess padding in IE 8/9/10.
332 | */
333 |
334 | input[type="checkbox"],
335 | input[type="radio"] {
336 | box-sizing: border-box; /* 1 */
337 | padding: 0; /* 2 */
338 | }
339 |
340 | /**
341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
342 | * `font-size` values of the `input`, it causes the cursor style of the
343 | * decrement button to change from `default` to `text`.
344 | */
345 |
346 | input[type="number"]::-webkit-inner-spin-button,
347 | input[type="number"]::-webkit-outer-spin-button {
348 | height: auto;
349 | }
350 |
351 | /**
352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
354 | * (include `-moz` to future-proof).
355 | */
356 |
357 | input[type="search"] {
358 | -webkit-appearance: textfield; /* 1 */
359 | -moz-box-sizing: content-box;
360 | -webkit-box-sizing: content-box; /* 2 */
361 | box-sizing: content-box;
362 | }
363 |
364 | /**
365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
366 | * Safari (but not Chrome) clips the cancel button when the search input has
367 | * padding (and `textfield` appearance).
368 | */
369 |
370 | input[type="search"]::-webkit-search-cancel-button,
371 | input[type="search"]::-webkit-search-decoration {
372 | -webkit-appearance: none;
373 | }
374 |
375 | /**
376 | * Define consistent border, margin, and padding.
377 | */
378 |
379 | fieldset {
380 | border: 1px solid #c0c0c0;
381 | margin: 0 2px;
382 | padding: 0.35em 0.625em 0.75em;
383 | }
384 |
385 | /**
386 | * 1. Correct `color` not being inherited in IE 8/9/10/11.
387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
388 | */
389 |
390 | legend {
391 | border: 0; /* 1 */
392 | padding: 0; /* 2 */
393 | }
394 |
395 | /**
396 | * Remove default vertical scrollbar in IE 8/9/10/11.
397 | */
398 |
399 | textarea {
400 | overflow: auto;
401 | }
402 |
403 | /**
404 | * Don't inherit the `font-weight` (applied by a rule above).
405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
406 | */
407 |
408 | optgroup {
409 | font-weight: bold;
410 | }
411 |
412 | /* Tables
413 | ========================================================================== */
414 |
415 | /**
416 | * Remove most spacing between table cells.
417 | */
418 |
419 | table {
420 | border-collapse: collapse;
421 | border-spacing: 0;
422 | }
423 |
424 | td,
425 | th {
426 | padding: 0;
427 | }
428 |
--------------------------------------------------------------------------------
/source/includes/attack.md:
--------------------------------------------------------------------------------
1 | # Attacking the App
2 |
3 | The application should be explored before starting to scan for security vulnerabilities.
4 | If you haven't done that look at the [explore](#exploring-the-app) section on how to explore the web application.
5 | The following section provides examples on how to use the Passive and Active Scanner to find security vulnerabilities in
6 | the application.
7 |
8 |
12 |
13 | ## Using Passive Scan
14 |
15 | ```java
16 | public class PassiveScan {
17 |
18 | private static final int ZAP_PORT = 8080;
19 | private static final String ZAP_API_KEY = null;
20 | private static final String ZAP_ADDRESS = "localhost";
21 |
22 | public static void main(String[] args) {
23 | ClientApi api = new ClientApi(ZAP_ADDRESS, ZAP_PORT, ZAP_API_KEY);
24 | int numberOfRecords;
25 |
26 | try {
27 | // TODO : explore the app (Spider, etc) before using the Passive Scan API, Refer the explore section for details
28 | // Loop until the passive scan has finished
29 | while (true) {
30 | Thread.sleep(2000);
31 | api.pscan.recordsToScan();
32 | numberOfRecords = Integer.parseInt(((ApiResponseElement) api.pscan.recordsToScan()).getValue());
33 | System.out.println("Number of records left for scanning : " + numberOfRecords);
34 | if (numberOfRecords == 0) {
35 | break;
36 | }
37 | }
38 | System.out.println("Passive Scan completed");
39 |
40 | // Print Passive scan results/alerts
41 | System.out.println("Alerts:");
42 | System.out.println(new String(api.core.xmlreport(), StandardCharsets.UTF_8));
43 |
44 | } catch (Exception e) {
45 | System.out.println("Exception : " + e.getMessage());
46 | e.printStackTrace();
47 | }
48 | }
49 | }
50 | ```
51 |
52 | ```python
53 | #!/usr/bin/env python
54 | import time
55 | from pprint import pprint
56 | from zapv2 import ZAPv2
57 |
58 | apiKey = 'changeme'
59 | target = 'https://public-firing-range.appspot.com'
60 | zap = ZAPv2(apikey=apiKey, proxies={'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'})
61 |
62 | # TODO : explore the app (Spider, etc) before using the Passive Scan API, Refer the explore section for details
63 | while int(zap.pscan.records_to_scan) > 0:
64 | # Loop until the passive scan has finished
65 | print('Records to passive scan : ' + zap.pscan.records_to_scan)
66 | time.sleep(2)
67 |
68 | print('Passive Scan completed')
69 |
70 | # Print Passive scan results/alerts
71 | print('Hosts: {}'.format(', '.join(zap.core.hosts)))
72 | print('Alerts: ')
73 | pprint(zap.core.alerts())
74 | ```
75 |
76 | ``` shell
77 | # To view the number of records left to be scanned
78 | $ curl "http://localhost:8080/JSON/pscan/view/recordsToScan/?apikey="
79 |
80 | # To view the alerts of passive scan
81 | $ curl "http://localhost:8080/JSON/core/view/alerts/?apikey=&baseurl=&start=0&count=10"
82 | ```
83 |
84 | All requests that are proxied through ZAP or initialised by tools like the Spider are passively scanned. You do not have
85 | to manually start the passive scan process, ZAP by default passively scans all HTTP and WebSocket messages (requests and responses)
86 | which are sent to the application.
87 |
88 | Passive scanning does not change the requests nor the responses in any way and is therefore safe to use.
89 | This is good for finding problems like missing security headers or missing anti CSRF tokens but is no good for finding
90 | vulnerabilities like XSS which require malicious requests to be sent - that's the job of the [active scanner](#using-active-scan).
91 |
92 | ### View the Status
93 |
94 | As the records are passively scanned it will take additional time to complete the full scan. After the crawling is completed
95 | use the [recordsToScan](#pscanviewrecordstoscan) API to obtain the number of records left to be scanned. After the scanning
96 | has completed the alerts can be obtained via the alerts endpoint(s).
97 |
98 | View the [advanced section](#passive-scan-settings) to know how to configure additional parameters of Passive Scan.
99 |
100 | ## Using Active Scan
101 |
102 | Active scanning attempts to find potential vulnerabilities by using known attacks against the selected targets. Active scanning
103 | is an attack on those targets. You should **NOT** use it on applications that you do not have permission to.
104 |
105 | ### Start Active Scanner
106 |
107 | ```java
108 | public class ActiveScan {
109 |
110 | private static final int ZAP_PORT = 8080;
111 | private static final String ZAP_API_KEY = null;
112 | private static final String ZAP_ADDRESS = "localhost";
113 | private static final String TARGET = "https://public-firing-range.appspot.com";
114 |
115 | public static void main(String[] args) {
116 |
117 | ClientApi api = new ClientApi(ZAP_ADDRESS, ZAP_PORT, ZAP_API_KEY);
118 |
119 | try {
120 | // TODO : explore the app (Spider, etc) before using the Active Scan API, Refer the explore section
121 | System.out.println("Active Scanning target : " + TARGET);
122 | ApiResponse resp = api.ascan.scan(TARGET, "True", "False", null, null, null);
123 | String scanid;
124 | int progress;
125 |
126 | // The scan now returns a scan id to support concurrent scanning
127 | scanid = ((ApiResponseElement) resp).getValue();
128 | // Poll the status until it completes
129 | while (true) {
130 | Thread.sleep(5000);
131 | progress =
132 | Integer.parseInt(
133 | ((ApiResponseElement) api.ascan.status(scanid)).getValue());
134 | System.out.println("Active Scan progress : " + progress + "%");
135 | if (progress >= 100) {
136 | break;
137 | }
138 | }
139 |
140 | System.out.println("Active Scan complete");
141 | // Print vulnerabilities found by the scanning
142 | System.out.println("Alerts:");
143 | System.out.println(new String(api.core.xmlreport(), StandardCharsets.UTF_8));
144 |
145 | } catch (Exception e) {
146 | System.out.println("Exception : " + e.getMessage());
147 | e.printStackTrace();
148 | }
149 | }
150 | }
151 | ```
152 |
153 | ```python
154 | #!/usr/bin/env python
155 | import time
156 | from pprint import pprint
157 | from zapv2 import ZAPv2
158 |
159 | apiKey = 'changeme'
160 | target = 'https://public-firing-range.appspot.com'
161 | zap = ZAPv2(apikey=apiKey, proxies={'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'})
162 |
163 | # TODO : explore the app (Spider, etc) before using the Active Scan API, Refer the explore section
164 | print('Active Scanning target {}'.format(target))
165 | scanID = zap.ascan.scan(target)
166 | while int(zap.ascan.status(scanID)) < 100:
167 | # Loop until the scanner has finished
168 | print('Scan progress %: {}'.format(zap.ascan.status(scanID)))
169 | time.sleep(5)
170 |
171 | print('Active Scan completed')
172 | # Print vulnerabilities found by the scanning
173 | print('Hosts: {}'.format(', '.join(zap.core.hosts)))
174 | print('Alerts: ')
175 | pprint(zap.core.alerts(baseurl=target))
176 | ```
177 |
178 | ``` shell
179 | # To start the the active scan
180 | $ curl "http://localhost:8080/JSON/ascan/action/scan/?apikey=&url=&recurse=true&inScopeOnly=&scanPolicyName=&method=&postData=&contextId="
181 |
182 | # To view the the status of active scan
183 | $ curl "http://localhost:8080/JSON/ascan/view/status/?apikey=&scanId="
184 |
185 | # To view the alerts of active scan
186 | $ curl "http://localhost:8080/JSON/core/view/alerts/?apikey=&baseurl=&start=0&count=10"
187 |
188 | # To stop the active scan
189 | $ curl "http://localhost:8080/JSON/ascan/action/stop/?apikey=&scanId="
190 | ```
191 |
192 | The [scan](#ascanactionscan) endpoint runs the active scanner against the given URL or Context. Optionally, the 'recurse' parameter can be used to scan URLs
193 | under the given URL, the parameter 'inScopeOnly' can be used to constrain the scan to URLs that are in scope (ignored if a Context is specified).
194 | The parameter 'scanPolicyName' allows to specify the scan policy (if none is given it uses the default scan policy).
195 | The parameters 'method' and 'postData' allow to select a given request in conjunction with the given URL.
196 |
197 | View advanced settings to learn, how to configure the [context](#context-advanced), [scope](#scope-advanced), and
198 | scan policy with ZAP APIs.
199 |
200 | ### View Status
201 |
202 | The [status](#ascanviewstatus) API provides the percentage of scanning done by the active scanner. The scan ID returned
203 | via starting the Active Scan should be used to query the status of the scanner.
204 |
205 | ### View Results
206 |
207 | Similar to the passive scan results, the active scan results can be viewed using the same alerts endpoint(s).
208 | The alerts endpoint(s) will show the consolidated results of Passive and Active Scan.
209 |
210 | ### Stop Active Scanning
211 |
212 | Use the [stop](#ascanactionstop) API to stop a long running active scan. Optionally you can use the [stopAllScans](#ascanactionstopallscans)
213 | endpoints or [pause](#ascanactionpause) endpoint to stop and pause the active scanning.
214 |
215 | It should be noted that active scanning can only find certain types of vulnerabilities. Logical vulnerabilities, such as
216 | broken access control, will not be found by any active or automated vulnerability scanning. Manual penetration testing should
217 | always be performed in addition to active scanning to find all types of vulnerabilities.
218 |
--------------------------------------------------------------------------------
/source/includes/welcome.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | ## Overview
4 |
5 | Welcome to ZAP API Documentation! The [Zed Attack Proxy](https://www.zaproxy.org/) (**ZAP**)
6 | is one of the world's most popular free security tools which lets you automatically find security vulnerabilities in your
7 | applications. ZAP also has an extremely powerful API that allows you to do nearly everything that is possible via the desktop interface.
8 | This allows the developers to automate pentesting and security regression testing of the application in the CI/CD pipeline.
9 |
10 | This document provides example guides & API definitions for ZAP APIs. You can view code examples in the dark area to
11 | the right; switch the programming language of the examples with the tabs on the top right.
12 | If anything is missing or seems incorrect, please check the [FAQs](https://www.zaproxy.org/faq/) or the
13 | [GitHub issues](https://github.com/zaproxy/zaproxy/issues) for existing known issues.
14 | Also, if you are new to ZAP, then check out the [getting started guide](https://www.zaproxy.org/getting-started/)
15 | to learn the basic concepts behind ZAP.
16 |
17 | An [OpenAPI definition](https://swagger.io/) for the ZAP API is [available in the main repository](https://raw.githubusercontent.com/zaproxy/zap-api-docs/main/openapi.yaml), which can be used to generate custom API clients.
18 | This definition is planned to be kept up to date for the latest core and add-on releases.
19 | Note that currently the definition does not declare the most appropriate types for the parameters and does not contain the responses.
20 |
21 | The following are some of the features provided by ZAP:
22 |
23 | * Intercepting Proxy
24 | * Active and Passive Scanners
25 | * Traditional and Ajax Spiders
26 | * Brute Force Scanner
27 | * Port Scanner
28 | * Web Sockets
29 |
30 | Have a look at the examples below to learn how to use each of these features via ZAP API.
31 |
32 | ## Documentation Structure
33 |
34 | The API documentation is divided into nine main sections.
35 |
36 | * [**Introduction**](#introduction) section contains introductory information of ZAP and installation guide to set up ZAP for testing.
37 | * [**Exploring the App**](#exploring-the-app) section contains examples on how to explore the web application.
38 | * [**Attacking the App**](#attacking-the-app) section contains examples on how to scan or attack a web application.
39 | * [**Getting the Results**](#getting-the-results) section contains examples on how to retrieve alerts and generate Reports from ZAP.
40 | * [**Getting Authenticated**](#getting-authenticated) section contains examples on how to authenticate the web application with ZAP.
41 | * [**Advanced Settings**](#advanced-settings) section contains advanced configurations on how to fine tune ZAP results.
42 | * [**Contributions**](#contributions-welcome) section contains guidelines and instructions on how to contribute to ZAP's documentation.
43 | * [**API Catalogue**](#api-catalogue) section contains OpenAPI definitions and auto generated code for ZAP APIs.
44 | * [**Troubleshooting**](#troubleshooting) section contains solutions for trouble shooting ZAP API related issues.
45 |
46 |
50 |
51 | ## Basics on the API Request
52 |
53 | ZAP APIs provide access to most of the core features of ZAP such as the active scanner and spider. ZAP API is enabled by default
54 | in the daemon mode and the desktop mode. If you are using ZAP desktop, then the API can be configured by visiting the following screen:
55 |
56 | `Tools -> Options -> API`.
57 |
58 | 
59 |
60 |
65 |
66 |
70 |
71 | Please note that not all the operations which are available in the desktop interface are available via the APIs.
72 | Future versions of ZAP will increase the functionality/scope available via the APIs.
73 |
74 | ### API URL Format
75 |
76 | The API is available via `GET` and `POST` endpoints and the response is available in `JSON`, `XML`, `HTML`, and `OTHER` (custom formats, e.g. HAR) formats.
77 | All the response formats return the same information, just in a different format. Based on the use case, choose the appropriate format.
78 | For example, to generate easily readable reports use the HTML format and use XML/JSON based response to parse the results quickly.
79 |
80 | The following example shows the API URL format of ZAP:
81 |
82 | `http://zap////[/?]`
83 |
84 | The format can be either `JSON`, `XML` or `HTML`. The operation can be either `view` or `action` or `other`. The `view` operation is used to return
85 | information and the `action` is used to control ZAP. For example, `views` can be used to generated reports or retrieve results and
86 | `action` can be used to start or stop the Spider. The components, operation names and parameters can all be discovered by
87 | browsing the [API Catalogue](#api-catalogue).
88 |
89 | ### Access the API
90 |
91 | The REST API can be accessed directly or via one of the [client implementations](#client_sdk) detailed below.
92 | A simple web UI is also available to explore and use the APIs via the browser. This web UI can be accessed via [http://zap/](http://zap/)
93 | when you are proxying through ZAP, or via the host and port ZAP is listening on, e.g. [http://localhost:8080/](http://localhost:8080/).
94 |
95 | 
96 |
97 | By default only the machine ZAP is running on is able to access the APIs. You can [allow other machines](https://www.zaproxy.org/faq/how-can-i-connect-to-zap-remotely/),
98 | that are able to use ZAP as a proxy, access to the API.
99 |
100 | ### Client SDKs
101 |
102 | API clients are available for the following languages:
103 |
104 | | **Language** | **Download links** | **Notes** |
105 | |:-------------|:-------------------|:----------|
106 | | .NET | [NuGet](https://www.nuget.org/packages/OWASPZAPDotNetAPI) | Official API |
107 | | Java | [GitHub](https://github.com/zaproxy/zap-api-java/releases) [Maven Central](https://search.maven.org/search?q=g:org.zaproxy%20AND%20a:zap-clientapi&core=gav) | Official API |
108 | | Node.js | [NPM](https://www.npmjs.org/package/zaproxy) | Official API |
109 | | PHP | [GitHub](https://github.com/yukisov/php-owasp-zap-v2) [Packagist](https://packagist.org/packages/zaproxy/php-owasp-zap-v2) | In process of becoming an official API |
110 | | Python | [PyPI](https://pypi.python.org/pypi/zaproxy) | Official API |
111 | | Ruby | [GitHub](https://github.com/vpereira/owasp_zap) | |
112 |
113 | ## Quick Setup Guide
114 |
115 | The quick setup guide focuses on setting up _ZAP_ and a testing application. If you have already setup ZAP then Jump to
116 | specific [example](#exploring-the-app) to experiment with specific features.
117 |
118 | ### Start ZAP
119 |
120 | ``` python
121 | # For Linux, Option: 1, using "headless/daemon" mode
122 | ./zap.sh -daemon -config api.key=change-me-9203935709
123 | # For Linux, Option: 2, using ZAP desktop App
124 | ./zap.sh
125 |
126 | # For Windows, Run the exe file or zap.bat script to start ZAP
127 | ```
128 |
129 | ``` java
130 | // For Linux, Option: 1, using "headless/daemon" mode
131 | ./zap.sh -daemon -config api.key=change-me-9203935709
132 | // For Linux, Option: 2, using ZAP desktop App
133 | ./zap.sh
134 |
135 | // For Windows, Run the exe file or zap.bat script to start ZAP
136 | ```
137 |
138 | ``` shell
139 | # For Linux, Option: 1, using "headless/daemon" mode
140 | $ ./zap.sh -daemon -config api.key=change-me-9203935709
141 | # For Linux, Option: 2, using ZAP desktop App
142 | $ ./zap.sh
143 |
144 | # For Windows, Run the exe file or zap.bat script to start ZAP
145 | ```
146 |
147 | To install ZAP, go to ZAP's [home page](https://www.zaproxy.org/download/) and download the installer specific to the
148 | operating system. After extracting the bundle you can start ZAP by issuing the following command shown in the right column.
149 |
150 | The API key must be specified on all API `actions` and some `other` operations. The API key is used to prevent malicious
151 | sites from accessing ZAP API.
152 |
153 | ### Setup a Testing Application
154 |
155 | If you already have a website to scan or to perform security testing, then obtain the URL/IP of the application to begin the scanning.
156 | The example guide uses [Google's Firing Range](https://github.com/google/firing-range) and
157 | [OWASP Juice Shop](https://github.com/bkimminich/juice-shop) to perform the security testing.
158 | The Spidering and Attacking examples use the [public instance](https://public-firing-range.appspot.com) of the
159 | Firing Range, and OWASP Juice Shop are used to showcase the Authentication examples of ZAP.
160 |
161 | The following is a [list](https://www.owasp.org/index.php/OWASP_Vulnerable_Web_Applications_Directory_Project#tab=On-Line_apps)
162 | of publicly available vulnerable applications that you can also used in conjunction with ZAP.
163 |
164 |
168 |
169 | ##Getting Help
170 |
171 | All available APIs are documented in the [API Catalogue](#api-catalogue). If you are new to ZAP, then it's highly
172 | recommended that you experiment with the desktop UI before trying out the APIs. Because ZAP's APIs strongly resemble
173 | the desktop UI. Therefore by working with the UI, you will get a good understanding on how to orchestrate ZAP's APIs.
174 | Also, use the export config functionality from the desktop UI to export complex configurations such as contexts, scan policies, etc.
175 | Then use the exported configurations when creating the automation scripts.
176 |
177 | ZAP has a very friendly and active developer community. Always feel free to raise a question in the
178 | [ZAP users forum](https://groups.google.com/d/forum/zaproxy-users) or [Stack Overflow](https://stackoverflow.com/questions/tagged/zap)
179 | for issues related to ZAP. Also, use the [ZAP's GitHub repository](https://github.com/zaproxy/zaproxy/issues)
180 | to raise a bug report or to make any feature requests.
181 |
182 | Stay tuned on twitter [@zaproxy](https://twitter.com/zaproxy).
183 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/.github/actions/update-website/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "update-website",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "update-website",
9 | "version": "1.0.0",
10 | "license": "Apache-2.0",
11 | "dependencies": {
12 | "@actions/core": "^1.11.1",
13 | "@actions/exec": "^1.1.1",
14 | "@actions/github": "^6.0.1",
15 | "@actions/io": "^1.1.3"
16 | },
17 | "devDependencies": {
18 | "@vercel/ncc": "^0.38.1"
19 | }
20 | },
21 | "node_modules/@actions/core": {
22 | "version": "1.11.1",
23 | "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
24 | "integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
25 | "license": "MIT",
26 | "dependencies": {
27 | "@actions/exec": "^1.1.1",
28 | "@actions/http-client": "^2.0.1"
29 | }
30 | },
31 | "node_modules/@actions/exec": {
32 | "version": "1.1.1",
33 | "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
34 | "integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
35 | "dependencies": {
36 | "@actions/io": "^1.0.1"
37 | }
38 | },
39 | "node_modules/@actions/github": {
40 | "version": "6.0.1",
41 | "resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.1.tgz",
42 | "integrity": "sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==",
43 | "license": "MIT",
44 | "dependencies": {
45 | "@actions/http-client": "^2.2.0",
46 | "@octokit/core": "^5.0.1",
47 | "@octokit/plugin-paginate-rest": "^9.2.2",
48 | "@octokit/plugin-rest-endpoint-methods": "^10.4.0",
49 | "@octokit/request": "^8.4.1",
50 | "@octokit/request-error": "^5.1.1",
51 | "undici": "^5.28.5"
52 | }
53 | },
54 | "node_modules/@actions/http-client": {
55 | "version": "2.2.0",
56 | "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.0.tgz",
57 | "integrity": "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==",
58 | "dependencies": {
59 | "tunnel": "^0.0.6",
60 | "undici": "^5.25.4"
61 | }
62 | },
63 | "node_modules/@actions/io": {
64 | "version": "1.1.3",
65 | "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
66 | "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="
67 | },
68 | "node_modules/@fastify/busboy": {
69 | "version": "2.1.0",
70 | "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz",
71 | "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==",
72 | "engines": {
73 | "node": ">=14"
74 | }
75 | },
76 | "node_modules/@octokit/auth-token": {
77 | "version": "4.0.0",
78 | "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
79 | "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
80 | "engines": {
81 | "node": ">= 18"
82 | }
83 | },
84 | "node_modules/@octokit/core": {
85 | "version": "5.1.0",
86 | "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.1.0.tgz",
87 | "integrity": "sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==",
88 | "dependencies": {
89 | "@octokit/auth-token": "^4.0.0",
90 | "@octokit/graphql": "^7.0.0",
91 | "@octokit/request": "^8.0.2",
92 | "@octokit/request-error": "^5.0.0",
93 | "@octokit/types": "^12.0.0",
94 | "before-after-hook": "^2.2.0",
95 | "universal-user-agent": "^6.0.0"
96 | },
97 | "engines": {
98 | "node": ">= 18"
99 | }
100 | },
101 | "node_modules/@octokit/endpoint": {
102 | "version": "9.0.6",
103 | "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
104 | "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
105 | "license": "MIT",
106 | "dependencies": {
107 | "@octokit/types": "^13.1.0",
108 | "universal-user-agent": "^6.0.0"
109 | },
110 | "engines": {
111 | "node": ">= 18"
112 | }
113 | },
114 | "node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
115 | "version": "23.0.1",
116 | "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
117 | "integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
118 | "license": "MIT"
119 | },
120 | "node_modules/@octokit/endpoint/node_modules/@octokit/types": {
121 | "version": "13.8.0",
122 | "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
123 | "integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
124 | "license": "MIT",
125 | "dependencies": {
126 | "@octokit/openapi-types": "^23.0.1"
127 | }
128 | },
129 | "node_modules/@octokit/graphql": {
130 | "version": "7.0.2",
131 | "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz",
132 | "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==",
133 | "dependencies": {
134 | "@octokit/request": "^8.0.1",
135 | "@octokit/types": "^12.0.0",
136 | "universal-user-agent": "^6.0.0"
137 | },
138 | "engines": {
139 | "node": ">= 18"
140 | }
141 | },
142 | "node_modules/@octokit/openapi-types": {
143 | "version": "20.0.0",
144 | "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
145 | "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="
146 | },
147 | "node_modules/@octokit/plugin-paginate-rest": {
148 | "version": "9.2.2",
149 | "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
150 | "integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
151 | "license": "MIT",
152 | "dependencies": {
153 | "@octokit/types": "^12.6.0"
154 | },
155 | "engines": {
156 | "node": ">= 18"
157 | },
158 | "peerDependencies": {
159 | "@octokit/core": "5"
160 | }
161 | },
162 | "node_modules/@octokit/plugin-rest-endpoint-methods": {
163 | "version": "10.4.0",
164 | "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.0.tgz",
165 | "integrity": "sha512-INw5rGXWlbv/p/VvQL63dhlXr38qYTHkQ5bANi9xofrF9OraqmjHsIGyenmjmul1JVRHpUlw5heFOj1UZLEolA==",
166 | "dependencies": {
167 | "@octokit/types": "^12.6.0"
168 | },
169 | "engines": {
170 | "node": ">= 18"
171 | },
172 | "peerDependencies": {
173 | "@octokit/core": ">=5"
174 | }
175 | },
176 | "node_modules/@octokit/request": {
177 | "version": "8.4.1",
178 | "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
179 | "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
180 | "license": "MIT",
181 | "dependencies": {
182 | "@octokit/endpoint": "^9.0.6",
183 | "@octokit/request-error": "^5.1.1",
184 | "@octokit/types": "^13.1.0",
185 | "universal-user-agent": "^6.0.0"
186 | },
187 | "engines": {
188 | "node": ">= 18"
189 | }
190 | },
191 | "node_modules/@octokit/request-error": {
192 | "version": "5.1.1",
193 | "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
194 | "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
195 | "license": "MIT",
196 | "dependencies": {
197 | "@octokit/types": "^13.1.0",
198 | "deprecation": "^2.0.0",
199 | "once": "^1.4.0"
200 | },
201 | "engines": {
202 | "node": ">= 18"
203 | }
204 | },
205 | "node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
206 | "version": "23.0.1",
207 | "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
208 | "integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
209 | "license": "MIT"
210 | },
211 | "node_modules/@octokit/request-error/node_modules/@octokit/types": {
212 | "version": "13.8.0",
213 | "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
214 | "integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
215 | "license": "MIT",
216 | "dependencies": {
217 | "@octokit/openapi-types": "^23.0.1"
218 | }
219 | },
220 | "node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
221 | "version": "23.0.1",
222 | "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
223 | "integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
224 | "license": "MIT"
225 | },
226 | "node_modules/@octokit/request/node_modules/@octokit/types": {
227 | "version": "13.8.0",
228 | "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
229 | "integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
230 | "license": "MIT",
231 | "dependencies": {
232 | "@octokit/openapi-types": "^23.0.1"
233 | }
234 | },
235 | "node_modules/@octokit/types": {
236 | "version": "12.6.0",
237 | "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
238 | "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
239 | "dependencies": {
240 | "@octokit/openapi-types": "^20.0.0"
241 | }
242 | },
243 | "node_modules/@vercel/ncc": {
244 | "version": "0.38.1",
245 | "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.1.tgz",
246 | "integrity": "sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw==",
247 | "dev": true,
248 | "bin": {
249 | "ncc": "dist/ncc/cli.js"
250 | }
251 | },
252 | "node_modules/before-after-hook": {
253 | "version": "2.2.3",
254 | "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
255 | "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
256 | },
257 | "node_modules/deprecation": {
258 | "version": "2.3.1",
259 | "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
260 | "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
261 | },
262 | "node_modules/once": {
263 | "version": "1.4.0",
264 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
265 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
266 | "dependencies": {
267 | "wrappy": "1"
268 | }
269 | },
270 | "node_modules/tunnel": {
271 | "version": "0.0.6",
272 | "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
273 | "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
274 | "engines": {
275 | "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
276 | }
277 | },
278 | "node_modules/undici": {
279 | "version": "5.29.0",
280 | "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
281 | "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
282 | "license": "MIT",
283 | "dependencies": {
284 | "@fastify/busboy": "^2.0.0"
285 | },
286 | "engines": {
287 | "node": ">=14.0"
288 | }
289 | },
290 | "node_modules/universal-user-agent": {
291 | "version": "6.0.1",
292 | "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
293 | "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ=="
294 | },
295 | "node_modules/wrappy": {
296 | "version": "1.0.2",
297 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
298 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
299 | }
300 | }
301 | }
302 |
--------------------------------------------------------------------------------
/source/includes/explore.md:
--------------------------------------------------------------------------------
1 | # Exploring the App
2 |
3 | In order to expose content and functionality for ZAP to test the target the application should be explored before performing
4 | any scan or attack. The more you explore your App the more accurate the results will be. If the application is not explored
5 | very well then it will impact or reduce the vulnerabilities ZAP can find.
6 |
7 | The following are some of the options to explore the site by using ZAP. You can use multiple approaches in a combination to
8 | get more complete coverage of the application.
9 |
10 | * **Traditional Spider (Crawler):** Use this approach to crawl the HTML resources (hyperlinks etc) in the web application.
11 |
12 | * **Ajax Spider:** Use this feature if the application heavily relies with Ajax calls.
13 |
14 | * **Proxy Regression / Unit Tests** This is the recommended approach for security regression testing. Use this approach
15 | to explore the application, if you already have a test suite or unit tests in place.
16 |
17 | * **OpenAPI/SOAP Definition**: Use this approach if you have a well defined OpenAPI definition. The OpenAPI plugin can be downloaded
18 | via the marketplace.
19 |
20 | ## Using Spider
21 |
22 | ```python
23 | #!/usr/bin/env python
24 | import time
25 | from zapv2 import ZAPv2
26 |
27 | # The URL of the application to be tested
28 | target = 'https://public-firing-range.appspot.com'
29 | # Change to match the API key set in ZAP, or use None if the API key is disabled
30 | apiKey = 'changeMe'
31 |
32 | # By default ZAP API client will connect to port 8080
33 | zap = ZAPv2(apikey=apiKey)
34 | # Use the line below if ZAP is not listening on port 8080, for example, if listening on port 8090
35 | # zap = ZAPv2(apikey=apiKey, proxies={'http': 'http://127.0.0.1:8090', 'https': 'http://127.0.0.1:8090'})
36 |
37 | print('Spidering target {}'.format(target))
38 | # The scan returns a scan id to support concurrent scanning
39 | scanID = zap.spider.scan(target)
40 | while int(zap.spider.status(scanID)) < 100:
41 | # Poll the status until it completes
42 | print('Spider progress %: {}'.format(zap.spider.status(scanID)))
43 | time.sleep(1)
44 |
45 | print('Spider has completed!')
46 | # Prints the URLs the spider has crawled
47 | print('\n'.join(map(str, zap.spider.results(scanID))))
48 | # If required post process the spider results
49 |
50 | # TODO: Explore the Application more with Ajax Spider or Start scanning the application for vulnerabilities
51 | ```
52 |
53 | ```java
54 | public class Spider {
55 |
56 | private static final String ZAP_ADDRESS = "localhost";
57 | private static final int ZAP_PORT = 8080;
58 | // Change to match the API key set in ZAP, or use NULL if the API key is disabled
59 | private static final String ZAP_API_KEY = "change me";
60 | // The URL of the application to be tested
61 | private static final String TARGET = "https://public-firing-range.appspot.com";
62 |
63 | public static void main(String[] args) {
64 | ClientApi api = new ClientApi(ZAP_ADDRESS, ZAP_PORT, ZAP_API_KEY);
65 |
66 | try {
67 | // Start spidering the target
68 | System.out.println("Spidering target : " + TARGET);
69 | ApiResponse resp = api.spider.scan(TARGET, null, null, null, null);
70 | String scanID;
71 | int progress;
72 |
73 | // The scan returns a scan id to support concurrent scanning
74 | scanID = ((ApiResponseElement) resp).getValue();
75 | // Poll the status until it completes
76 | while (true) {
77 | Thread.sleep(1000);
78 | progress = Integer.parseInt(((ApiResponseElement) api.spider.status(scanID)).getValue());
79 | System.out.println("Spider progress : " + progress + "%");
80 | if (progress >= 100) {
81 | break;
82 | }
83 | }
84 | System.out.println("Spider completed");
85 | // If required post process the spider results
86 | List spiderResults = ((ApiResponseList) api.spider.results(scanID)).getItems();
87 |
88 | // TODO: Explore the Application more with Ajax Spider or Start scanning the application for vulnerabilities
89 |
90 | } catch (Exception e) {
91 | System.out.println("Exception : " + e.getMessage());
92 | e.printStackTrace();
93 | }
94 | }
95 | }
96 | ```
97 |
98 | ``` shell
99 | # To start the Spider scan (Response: Scan ID). Modify the API Key and URL to suite the target
100 | $ curl "http://localhost:8080/JSON/spider/action/scan/?apikey=&url=https://public-firing-range.appspot.com&contextName=&recurse="
101 |
102 | # To view the scan status/ percentage of work done
103 | $ curl "http://localhost:8080/JSON/spider/view/status/?apikey=&scanId="
104 |
105 | # To view the scan results
106 | $ curl "http://localhost:8080/JSON/spider/view/results/?apikey=&scanId="
107 |
108 | # To stop the scanning
109 | $ curl "http://localhost:8080/JSON/spider/action/stop/?apikey=&scanId="
110 | # To pause the scanning
111 | $ curl "http://localhost:8080/JSON/spider/action/pause/?apikey=&scanId="
112 | # To resume the scanning
113 | $ curl "http://localhost:8080/JSON/spider/action/resume/?apikey=&scanId="
114 |
115 | ```
116 |
117 | The Spider is a tool that is used to automatically discover new resources (URLs) on a particular site. It begins with a
118 | list of URLs to visit, called the seeds, which depends on how the Spider is started. The Spider then visits these URLs,
119 | it identifies all the hyperlinks in the page and adds them to the list of URLs to visit, and the process continues
120 | recursively as long as new resources are found. Each response type is processed differently in ZAP. All the available
121 | endpoints for the spider can be found in [spider](#zap-api-spider) section.
122 |
123 | ### Start the Spider
124 |
125 | The Spiders explore the site and they don't actually do any scanning. The resources crawled by the Spider(s) are passively scanned
126 | in the background via the [Passive Scanner](#using-passive-scan). The [scan](#spideractionscan) API runs the spider against the given URL.
127 | Optionally, the 'maxChildren' parameter can be set to limit the number of children scanned and the 'recurse' parameter can
128 | be used to prevent the spider from seeding recursively. The parameter 'subtreeOnly' allows to restrict the spider under a
129 | site's subtree (using the specified 'URL'). The parameter 'contextName' can be used to constrain the scan to
130 | a Context. View the [context example](#context-advanced) to understand how to create a context with ZAP API.
131 |
132 | The code sample on the right recursively scans the application with the provided URL. The scan ID is returned as a
133 | response when starting the Spider. Use this scan ID to perform any additional actions or to retrieve any views from the Spider API.
134 |
135 | ### View Status
136 |
137 | The spider scan is a async request and the time to complete the task will vary depending on the complexity of the web application.
138 | The scan ID returned via starting the spider should be used to obtain the results of the crawling. Execute the [status](#spiderviewstatus)
139 | API to get the status/percentage of work done by the Spider.
140 |
141 | ### View Spider Results
142 |
143 | The results of the crawling can be obtained via the [results](#spiderviewresults) API. The following image shows the JSON sample
144 | response provided by the results API, listing all the resources crawled by Spider.
145 |
146 | 
147 |
148 | ### Stop or Pause the Spider
149 |
150 | If the scanning takes more time than expected you can stop or pause the scanning via using the [stop](#spideractionstop)
151 | or [pause](#spideractionpause) APIs. Additional APIs are available in the API Catalogue to pause or resume or to
152 | [stop All](#spideractionstopallscans) the scanning processes.
153 |
154 | The [advanced section on Spider](#spider-settings) contains more examples on how to tweak/improve the Spider results.
155 |
156 | ##Using Ajax Spider
157 |
158 | ```python
159 | #!/usr/bin/env python
160 | import time
161 | from zapv2 import ZAPv2
162 |
163 | # The URL of the application to be tested
164 | target = 'https://public-firing-range.appspot.com'
165 | # Change to match the API key set in ZAP, or use None if the API key is disabled
166 | apiKey = 'changeme'
167 |
168 | # By default ZAP API client will connect to port 8080
169 | zap = ZAPv2(apikey=apiKey)
170 | # Use the line below if ZAP is not listening on port 8080, for example, if listening on port 8090
171 | # zap = ZAPv2(apikey=apiKey, proxies={'http': 'http://127.0.0.1:8090', 'https': 'http://127.0.0.1:8090'})
172 |
173 | print('Ajax Spider target {}'.format(target))
174 | scanID = zap.ajaxSpider.scan(target)
175 |
176 | timeout = time.time() + 60*2 # 2 minutes from now
177 | # Loop until the ajax spider has finished or the timeout has exceeded
178 | while zap.ajaxSpider.status == 'running':
179 | if time.time() > timeout:
180 | break
181 | print('Ajax Spider status' + zap.ajaxSpider.status)
182 | time.sleep(2)
183 |
184 | print('Ajax Spider completed')
185 | ajaxResults = zap.ajaxSpider.results(start=0, count=10)
186 | # If required perform additional operations with the Ajax Spider results
187 |
188 | # TODO: Start scanning the application to find vulnerabilities
189 | ```
190 |
191 | ```java
192 | public class AjaxSpider {
193 |
194 | private static final int ZAP_PORT = 8080;
195 | private static final String ZAP_API_KEY = null;
196 | private static final String ZAP_ADDRESS = "localhost";
197 | private static final String TARGET = "https://public-firing-range.appspot.com";
198 |
199 | public static void main(String[] args) {
200 | // Create the ZAP Client
201 | ClientApi api = new ClientApi(ZAP_ADDRESS, ZAP_PORT, ZAP_API_KEY);
202 |
203 | try {
204 | // Start spidering the target
205 | System.out.println("Ajax Spider target : " + TARGET);
206 | ApiResponse resp = api.ajaxSpider.scan(TARGET, null, null, null);
207 | String status;
208 |
209 | long startTime = System.currentTimeMillis();
210 | long timeout = TimeUnit.MINUTES.toMillis(2); // Two minutes in milli seconds
211 | // Loop until the ajax spider has finished or the timeout has exceeded
212 | while (true) {
213 | Thread.sleep(2000);
214 | status = (((ApiResponseElement) api.ajaxSpider.status()).getValue());
215 | System.out.println("Spider status : " + status);
216 | if (!("stopped".equals(status)) || (System.currentTimeMillis() - startTime) < timeout) {
217 | break;
218 | }
219 | }
220 | System.out.println("Ajax Spider completed");
221 | // Perform additional operations with the Ajax Spider results
222 | List ajaxSpiderResponse = ((ApiResponseList) api.ajaxSpider.results("0", "10")).getItems();
223 |
224 | // TODO: Start scanning(passive/active scan) the application to find vulnerabilities
225 |
226 | } catch (Exception e) {
227 | System.out.println("Exception : " + e.getMessage());
228 | e.printStackTrace();
229 | }
230 | }
231 | }
232 | ```
233 |
234 | ```shell
235 | # To start the Ajax Spider
236 | $ curl "http://localhost:8080/JSON/ajaxSpider/action/scan/?apikey=&url=&inScope=&contextName=&subtreeOnly="
237 |
238 | # To view the status
239 | $ curl "http://localhost:8080/JSON/ajaxSpider/view/status/?apikey="
240 |
241 | # To view the number of results
242 | $ curl "http://localhost:8080/JSON/ajaxSpider/view/numberOfResults/?apikey="
243 |
244 | # To view the results
245 | $ curl "http://localhost:8080/JSON/ajaxSpider/view/fullResults/?apikey="
246 |
247 | # To stop the Ajax Spider
248 | $ curl "http://localhost:8080/JSON/ajaxSpider/action/stop/?apikey="
249 | ```
250 |
251 | Use the Ajax Spider if you have applications which heavily depend on Ajax or JavaScript. The Ajax Spider allows you to crawl web applications
252 | written in Ajax in far more depth than the traditional Spider.You should also use the traditional Spider as well for complete coverage
253 | of a application (e.g. to cover HTML comments).
254 |
255 | ### Start Ajax Spider
256 |
257 | The scan API starts the Ajax Spider based on a given URL. Similar to the Traditional Spider, Ajax Spider can be also limited to a
258 | context or scope. The parameter 'contextName' can be used to constrain the scan to a Context, the option 'inScope' is
259 | ignored if a context was also specified. The parameter 'subtreeOnly' allows to restrict the spider under a site's subtree (using the specified 'URL').
260 |
261 | ### View Status
262 |
263 | Unlike the traditional Spider, Ajax Spider does not provide a percentage for the work to be done. Use the [status](#ajaxspiderviewstatus)
264 | endpoint to identify whether the Ajax Spider is still active or finished.
265 |
266 | ### View Results
267 |
268 | Similar to the Traditional Spider, the Ajax Spider's [results](#aspider_results_api) API can be used to view the resources
269 | which are crawled by the Ajax Spider. The following image shows a sample response given by the API.
270 |
271 | 
272 |
273 | ### Stop the Ajax Spider
274 |
275 | Ajax spider does not have an indication on how much resources are left to be crawled. Therefore if the Ajax spider takes too much time
276 | than expected, then it can be stopped by using the [stop](#aspider_stop_api) API.
277 |
278 | View the [advanced section on Ajax Spider](#ajax-spider-settings) to learn more about how to further fine-tune the results of the
279 | Ajax Spider.
280 |
281 |
285 |
--------------------------------------------------------------------------------
/source/stylesheets/screen.css.scss:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 | @import 'normalize';
3 | @import 'variables';
4 | @import 'icon-font';
5 | // @import 'rtl'; // uncomment to switch to RTL format
6 |
7 | /*
8 | Copyright 2008-2013 Concur Technologies, Inc.
9 |
10 | Licensed under the Apache License, Version 2.0 (the "License"); you may
11 | not use this file except in compliance with the License. You may obtain
12 | a copy of the License at
13 |
14 | http://www.apache.org/licenses/LICENSE-2.0
15 |
16 | Unless required by applicable law or agreed to in writing, software
17 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19 | License for the specific language governing permissions and limitations
20 | under the License.
21 | */
22 |
23 | ////////////////////////////////////////////////////////////////////////////////
24 | // GENERAL STUFF
25 | ////////////////////////////////////////////////////////////////////////////////
26 |
27 | html, body {
28 | color: $main-text;
29 | padding: 0;
30 | margin: 0;
31 | -webkit-font-smoothing: antialiased;
32 | -moz-osx-font-smoothing: grayscale;
33 | @extend %default-font;
34 | background-color: $main-bg;
35 | height: 100%;
36 | -webkit-text-size-adjust: none; /* Never autoresize text */
37 | }
38 |
39 | ////////////////////////////////////////////////////////////////////////////////
40 | // TABLE OF CONTENTS
41 | ////////////////////////////////////////////////////////////////////////////////
42 |
43 | #toc > ul > li > a > span {
44 | float: right;
45 | background-color: #2484FF;
46 | border-radius: 40px;
47 | width: 20px;
48 | }
49 |
50 | .toc-wrapper {
51 | transition: left 0.3s ease-in-out;
52 |
53 | overflow-y: auto;
54 | overflow-x: hidden;
55 | position: fixed;
56 | z-index: 30;
57 | top: 0;
58 | left: 0;
59 | bottom: 0;
60 | width: $nav-width;
61 | background-color: $nav-bg;
62 | font-size: 13px;
63 | font-weight: bold;
64 |
65 | // language selector for mobile devices
66 | .lang-selector {
67 | display: none;
68 | a {
69 | padding-top: 0.5em;
70 | padding-bottom: 0.5em;
71 | }
72 | }
73 |
74 | // This is the logo at the top of the ToC
75 | .logo {
76 | display: block;
77 | max-width: 100%;
78 | margin-bottom: $logo-margin;
79 | }
80 |
81 | &>.search {
82 | position: relative;
83 |
84 | input {
85 | background: $nav-bg;
86 | border-width: 0 0 1px 0;
87 | border-color: $search-box-border-color;
88 | padding: 6px 0 6px 20px;
89 | box-sizing: border-box;
90 | margin: $nav-v-padding $nav-padding;
91 | width: $nav-width - ($nav-padding*2);
92 | outline: none;
93 | color: $nav-text;
94 | border-radius: 0; /* ios has a default border radius */
95 | }
96 |
97 | &:before {
98 | position: absolute;
99 | top: 17px;
100 | left: $nav-padding;
101 | color: $nav-text;
102 | @extend %icon-search;
103 | }
104 | }
105 |
106 | .search-results {
107 | margin-top: 0;
108 | box-sizing: border-box;
109 | height: 0;
110 | overflow-y: auto;
111 | overflow-x: hidden;
112 | transition-property: height, margin;
113 | transition-duration: 180ms;
114 | transition-timing-function: ease-in-out;
115 | background: $nav-subitem-bg;
116 | &.visible {
117 | height: 30%;
118 | margin-bottom: 1em;
119 | }
120 | background:
121 | linear-gradient(to top, rgba(#000, 0.2), rgba(#000, 0) 5px),
122 | linear-gradient(to bottom, rgba(#000, 0.2), rgba(#000, 0) 5px);
123 | li {
124 | margin: 1em $nav-padding;
125 | line-height: 1;
126 | }
127 |
128 | a {
129 | color: $nav-text;
130 | text-decoration: none;
131 |
132 | &:hover {
133 | text-decoration: underline;
134 | }
135 | }
136 | }
137 |
138 |
139 | // The Table of Contents is composed of multiple nested
140 | // unordered lists. These styles remove the default
141 | // styling of an unordered list because it is ugly.
142 | ul, li {
143 | list-style: none;
144 | margin: 0;
145 | padding: 0;
146 | line-height: 28px;
147 | }
148 |
149 | li {
150 | color: $nav-text;
151 | transition-property: background;
152 | transition-timing-function: linear;
153 | transition-duration: 200ms;
154 | }
155 |
156 | // This is the currently selected ToC entry
157 | .toc-link.active {
158 | background-color: $nav-active-bg;
159 | color: $nav-active-text;
160 | border-left: solid 5px $nav-active-text;
161 | }
162 |
163 | // this is parent links of the currently selected ToC entry
164 | .toc-link.active-parent {
165 | background-color: $nav-active-parent-bg;
166 | color: $nav-active-parent-text;
167 | }
168 |
169 | .toc-list-h2 {
170 | display: none;
171 | background-color: $nav-subitem-bg;
172 | font-weight: 500;
173 | background:
174 | linear-gradient(to top, rgba(#000, 0.3), rgba(#000, 0) 5px),
175 | linear-gradient(to bottom, rgba(#000, 0.3), rgba(#000, 0) 5px)
176 | }
177 |
178 | .toc-h2 {
179 | padding-left: $nav-padding + $nav-indent;
180 | font-size: 12px;
181 | }
182 |
183 | .toc-footer {
184 | padding: 1em 0;
185 | margin-top: 1em;
186 | border-top: 1px dashed $nav-footer-border-color;
187 |
188 | li,a {
189 | color: $nav-text;
190 | text-decoration: none;
191 | }
192 |
193 | a:hover {
194 | text-decoration: underline;
195 | }
196 |
197 | li {
198 | font-size: 0.8em;
199 | line-height: 1.7;
200 | text-decoration: none;
201 | }
202 | }
203 | }
204 |
205 | .toc-link, .toc-footer li {
206 | padding: 0 $nav-padding 0 $nav-padding;
207 | display: block;
208 | overflow-x: hidden;
209 | white-space: nowrap;
210 | text-overflow: ellipsis;
211 | text-decoration: none;
212 | color: $nav-text;
213 | transition-property: background;
214 | transition-timing-function: linear;
215 | transition-duration: 130ms;
216 | }
217 |
218 | // button to show navigation on mobile devices
219 | #nav-button {
220 | span {
221 | display: block;
222 | $side-pad: $main-padding / 2 - 8px;
223 | padding: $side-pad $side-pad $side-pad;
224 | background-color: rgba($main-bg, 0.7);
225 | transform-origin: 0 0;
226 | transform: rotate(-90deg) translate(-100%, 0);
227 | border-radius: 0 0 0 5px;
228 | }
229 | padding: 0 1.5em 5em 0; // increase touch size area
230 | display: none;
231 | position: fixed;
232 | top: 0;
233 | left: 0;
234 | z-index: 100;
235 | color: #000;
236 | text-decoration: none;
237 | font-weight: bold;
238 | opacity: 0.7;
239 | line-height: 16px;
240 | img {
241 | height: 16px;
242 | vertical-align: bottom;
243 | }
244 |
245 | transition: left 0.3s ease-in-out;
246 |
247 | &:hover { opacity: 1; }
248 | &.open {left: $nav-width}
249 | }
250 |
251 |
252 | ////////////////////////////////////////////////////////////////////////////////
253 | // PAGE LAYOUT AND CODE SAMPLE BACKGROUND
254 | ////////////////////////////////////////////////////////////////////////////////
255 |
256 | .page-wrapper {
257 | margin-left: $nav-width;
258 | position: relative;
259 | z-index: 10;
260 | background-color: $main-bg;
261 | min-height: 100%;
262 |
263 | padding-bottom: 1px; // prevent margin overflow
264 |
265 | // The dark box is what gives the code samples their dark background.
266 | // It sits essentially under the actual content block, which has a
267 | // transparent background.
268 | // I know, it's hackish, but it's the simplist way to make the left
269 | // half of the content always this background color.
270 | .dark-box {
271 | width: $examples-width;
272 | background-color: $examples-bg;
273 | position: absolute;
274 | right: 0;
275 | top: 0;
276 | bottom: 0;
277 | }
278 |
279 | .lang-selector {
280 | position: fixed;
281 | z-index: 50;
282 | border-bottom: 5px solid $lang-select-active-bg;
283 | }
284 | }
285 |
286 | .lang-selector {
287 | background-color: $lang-select-bg;
288 | width: 100%;
289 | font-weight: bold;
290 | a {
291 | display: block;
292 | float:left;
293 | color: $lang-select-text;
294 | text-decoration: none;
295 | padding: 0 10px;
296 | line-height: 30px;
297 | outline: 0;
298 |
299 | &:active, &:focus {
300 | background-color: $lang-select-pressed-bg;
301 | color: $lang-select-pressed-text;
302 | }
303 |
304 | &.active {
305 | background-color: $lang-select-active-bg;
306 | color: $lang-select-active-text;
307 | }
308 | }
309 |
310 | &:after {
311 | content: '';
312 | clear: both;
313 | display: block;
314 | }
315 | }
316 |
317 | ////////////////////////////////////////////////////////////////////////////////
318 | // CONTENT STYLES
319 | ////////////////////////////////////////////////////////////////////////////////
320 | // This is all the stuff with the light background in the left half of the page
321 |
322 | .content {
323 | // fixes webkit rendering bug for some: see #538
324 | -webkit-transform: translateZ(0);
325 | // to place content above the dark box
326 | position: relative;
327 | z-index: 30;
328 |
329 | &:after {
330 | content: '';
331 | display: block;
332 | clear: both;
333 | }
334 |
335 | &>h1, &>h2, &>h3, &>h4, &>h5, &>h6, &>p, &>table, &>ul, &>ol, &>aside, &>dl {
336 | margin-right: $examples-width;
337 | padding: 0 $main-padding;
338 | box-sizing: border-box;
339 | display: block;
340 |
341 | @extend %left-col;
342 | }
343 |
344 | &>ul, &>ol {
345 | padding-left: $main-padding + 15px;
346 | }
347 |
348 | // the div is the tocify hidden div for placeholding stuff
349 | &>h1, &>h2, &>div {
350 | clear:both;
351 | }
352 |
353 | h1 {
354 | @extend %header-font;
355 | font-size: 36px;
356 | font-weight: normal;
357 | padding-top: 0.5em;
358 | padding-bottom: 0.5em;
359 | border-top: 1px solid #ccc;
360 | background-color: #fdfdfd;
361 | //border-bottom: 1px solid #ccc;
362 | }
363 |
364 | h1:first-child, div:first-child + h1 {
365 | border-top-width: 0;
366 | margin-top: 0;
367 | }
368 |
369 | h2 {
370 | @extend %header-font;
371 | font-size: 27px;
372 | font-weight: normal;
373 | margin-bottom: 0;
374 | padding-top: 1.2em;
375 | padding-bottom: 1.2em
376 | }
377 |
378 | // h2s right after h1s should bump right up
379 | // against the h1s.
380 | h1 + h2, h1 + div + h2 {
381 | margin-top: $h1-margin-bottom * -1;
382 | border-top: none;
383 | }
384 |
385 | h3, h4, h5, h6 {
386 | @extend %header-font;
387 | font-weight: normal;
388 | font-size: 17px;
389 | margin-top: 1.5em;
390 | margin-bottom: 0.8em;
391 | }
392 |
393 |
394 | h4, h5, h6 {
395 | font-size: 15px;
396 | }
397 |
398 | hr {
399 | margin: 2em 0;
400 | border-top: 2px solid $examples-bg;
401 | border-bottom: 2px solid $main-bg;
402 | }
403 |
404 | table {
405 | margin-bottom: 1em;
406 | overflow: auto;
407 | th,td {
408 | text-align: left;
409 | vertical-align: top;
410 | line-height: 1.6;
411 | code {
412 | white-space: nowrap;
413 | }
414 | }
415 |
416 | th {
417 | padding: 5px 10px;
418 | border-bottom: 1px solid #ccc;
419 | vertical-align: bottom;
420 | }
421 |
422 | td {
423 | padding: 10px;
424 | }
425 |
426 | tr:last-child {
427 | border-bottom: 1px solid #ccc;
428 | }
429 |
430 | tr:nth-child(odd)>td {
431 | background-color: lighten($main-bg,4.2%);
432 | }
433 |
434 | tr:nth-child(even)>td {
435 | background-color: lighten($main-bg,2.4%);
436 | }
437 | }
438 |
439 | dt {
440 | font-weight: bold;
441 | }
442 |
443 | dd {
444 | margin-left: 15px;
445 | }
446 |
447 | p, li, dt, dd {
448 | line-height: 1.6;
449 | margin-top: 0;
450 | }
451 |
452 | img {
453 | max-width: 100%;
454 | }
455 |
456 | code {
457 | background-color: rgba(0,0,0,0.05);
458 | padding: 3px;
459 | border-radius: 3px;
460 | @extend %break-words;
461 | @extend %code-font;
462 | }
463 |
464 | pre>code {
465 | background-color: transparent;
466 | padding: 0;
467 | }
468 |
469 | aside {
470 | padding-top: 1em;
471 | padding-bottom: 1em;
472 | margin-top: 1.5em;
473 | margin-bottom: 1.5em;
474 | background: $aside-notice-bg;
475 | line-height: 1.6;
476 |
477 | &.warning {
478 | background-color: $aside-warning-bg;
479 | }
480 |
481 | &.success {
482 | background-color: $aside-success-bg;
483 | }
484 | }
485 |
486 | aside:before {
487 | vertical-align: middle;
488 | padding-right: 0.5em;
489 | font-size: 14px;
490 | }
491 |
492 | aside.notice:before {
493 | @extend %icon-info-sign;
494 | }
495 |
496 | aside.warning:before {
497 | @extend %icon-exclamation-sign;
498 | }
499 |
500 | aside.success:before {
501 | @extend %icon-ok-sign;
502 | }
503 |
504 | .search-highlight {
505 | padding: 2px;
506 | margin: -3px;
507 | border-radius: 4px;
508 | border: 1px solid #F7E633;
509 | background: linear-gradient(to top left, #F7E633 0%, #F1D32F 100%);
510 | }
511 | }
512 |
513 | ////////////////////////////////////////////////////////////////////////////////
514 | // CODE SAMPLE STYLES
515 | ////////////////////////////////////////////////////////////////////////////////
516 | // This is all the stuff that appears in the right half of the page
517 |
518 | .content {
519 | pre, blockquote {
520 | background-color: $code-bg;
521 | color: #fff;
522 |
523 | margin: 0;
524 | width: $examples-width;
525 |
526 | float:right;
527 | clear:right;
528 |
529 | box-sizing: border-box;
530 |
531 | @extend %right-col;
532 |
533 | &>p { margin: 0; }
534 |
535 | a {
536 | color: #fff;
537 | text-decoration: none;
538 | border-bottom: dashed 1px #ccc;
539 | }
540 | }
541 |
542 | pre {
543 | @extend %code-font;
544 | padding-top: 2em;
545 | padding-bottom: 2em;
546 | padding: 2em $main-padding;
547 | }
548 |
549 | blockquote {
550 | &>p {
551 | background-color: $code-annotation-bg;
552 | padding: $code-annotation-padding 2em;
553 | color: #eee;
554 | }
555 | }
556 | }
557 |
558 | ////////////////////////////////////////////////////////////////////////////////
559 | // RESPONSIVE DESIGN
560 | ////////////////////////////////////////////////////////////////////////////////
561 | // These are the styles for phones and tablets
562 | // There are also a couple styles disperesed
563 |
564 | @media (max-width: $tablet-width) {
565 | .toc-wrapper {
566 | left: -$nav-width;
567 |
568 | &.open {
569 | left: 0;
570 | }
571 | }
572 |
573 | .page-wrapper {
574 | margin-left: 0;
575 | }
576 |
577 | #nav-button {
578 | display: block;
579 | }
580 |
581 | .toc-link {
582 | padding-top: 0.3em;
583 | padding-bottom: 0.3em;
584 | }
585 | }
586 |
587 | @media (max-width: $phone-width) {
588 | .dark-box {
589 | display: none;
590 | }
591 |
592 | %left-col {
593 | margin-right: 0;
594 | }
595 |
596 | .toc-wrapper .lang-selector {
597 | display: block;
598 | }
599 |
600 | .page-wrapper .lang-selector {
601 | display: none;
602 | }
603 |
604 | %right-col {
605 | width: auto;
606 | float: none;
607 | }
608 |
609 | %right-col + %left-col {
610 | margin-top: $main-padding;
611 | }
612 | }
613 |
614 | .highlight .c, .highlight .cm, .highlight .c1, .highlight .cs {
615 | color: #909090;
616 | }
617 |
618 | .highlight, .highlight .w {
619 | background-color: $code-bg;
620 | }
621 |
622 | div.highlight {
623 | clear: none;
624 | }
625 |
--------------------------------------------------------------------------------