Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ZAP Go Package, Fix Generation Issues, and Autogenerate Interface #21

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
30 changes: 5 additions & 25 deletions .github/workflows/golangci-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,17 @@ on:
branches:
- master
pull_request:

permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
# pull-requests: read

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
- uses: actions/checkout@v4
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v6
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest

# Optional: working directory, useful for monorepos
# working-directory: somedir

# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0

# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

# Optional: if set to true then the action will use pre-installed Go.
# skip-go-installation: true

# Optional: if set to true then the action don't cache or restore ~/go/pkg.
# skip-pkg-cache: true

# Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
# skip-build-cache: true
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ _testmain.go
*.exe
*.test
*.prof

zaproxy/
zap-extensions/
Comment on lines +25 to +27
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be removed, the repos should live at the same level as the zap-api-go not under it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we link these two projects as submodules instead? This way, users won't need to clone them manually into the correct location. I added them to the .gitignore file to ensure they are not committed accidentally.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repos are already cloned, per dev guide.

19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,36 @@ Most of the API code is generated from the ZAP java source code.

To regenerate the API code you will need the repos [zaproxy](https://github.com/zaproxy/zaproxy) and [zap-extensions](https://github.com/zaproxy/zap-extensions) checked out at the same level as this one.

You should typically generate the core API calls from the latest release tag e.g.:
Cloning the Repositories:
```
git clone --recursive -j8 https://github.com/zaproxy/zaproxy.git
git clone --recursive -j8 https://github.com/zaproxy/zap-extensions.git
```

Typically, you should generate the core API calls from the latest release tag. For example:

```
cd zaproxy
git fetch upstream -t
git checkout tags/v2.13.0
git checkout tags/v2.15.0
./gradlew generateGoApiEndpoints
cd ..
```

The add-on APIs can be generated from the zap-extensions `main` branch:
The add-on APIs can be generated from the zap-extensions main branch:

```
cd zap-extensions
git pull upstream main
./gradlew generateGoZapApiClientFiles --continue
cd ..
```

Finally, run the command to update the `interface.go`:

```
/bin/bash zap-api-go/zap/generate_interface.sh
```

The above commands will update the files in `zap-api-go/zap`.

If any new files are created then they should be manually added to `zap-api-go/zap/interface.go` as per the existing files.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/zaproxy/zap-api-go

go 1.17
go 1.22
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems wrong, why are they prefixed with zap-api-go now? Was that because of the clone under the repo?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There might have been some changes in the generation script. I followed the instructions in the README and executed the commands using Gradle.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case the instructions were not followed correctly.

File renamed without changes.
7 changes: 4 additions & 3 deletions zap/acsrf_generated.go → zap-api-go/zap/acsrf_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// ZAP is an HTTP/HTTPS proxy for assessing web application security.
//
// Copyright 2022 the ZAP development team
// Copyright 2017 the ZAP development team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -62,9 +62,10 @@ func (a Acsrf) SetOptionPartialMatchingEnabled(boolean bool) (map[string]interfa
}

// Generate a form for testing lack of anti-CSRF tokens - typically invoked via ZAP
func (a Acsrf) GenForm(hrefid string) ([]byte, error) {
func (a Acsrf) GenForm(hrefid string, actionurl string) ([]byte, error) {
m := map[string]string{
"hrefId": hrefid,
"hrefId": hrefid,
"actionUrl": actionurl,
}
return a.c.RequestOther("acsrf/other/genForm/", m)
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ func (a AjaxSpider) AllowedResources() (map[string]interface{}, error) {
return a.c.Request("ajaxSpider/view/allowedResources/", nil)
}

// Gets the excluded elements. The excluded elements are not clicked during crawling, for example, to prevent logging out.
//
// This component is optional and therefore the API will only work if it is installed
func (a AjaxSpider) ExcludedElements(contextname string) (map[string]interface{}, error) {
m := map[string]string{
"contextName": contextname,
}
return a.c.Request("ajaxSpider/view/excludedElements/", m)
}

// Gets the current status of the crawler. Actual values are Stopped and Running.
//
// This component is optional and therefore the API will only work if it is installed
Expand Down Expand Up @@ -180,6 +190,52 @@ func (a AjaxSpider) AddAllowedResource(regex string, enabled string) (map[string
return a.c.Request("ajaxSpider/action/addAllowedResource/", m)
}

// Adds an excluded element to a context.
//
// This component is optional and therefore the API will only work if it is installed
func (a AjaxSpider) AddExcludedElement(contextname string, description string, element string, xpath string, text string, attributename string, attributevalue string, enabled string) (map[string]interface{}, error) {
m := map[string]string{
"contextName": contextname,
"description": description,
"element": element,
"xpath": xpath,
"text": text,
"attributeName": attributename,
"attributeValue": attributevalue,
"enabled": enabled,
}
return a.c.Request("ajaxSpider/action/addExcludedElement/", m)
}

// Modifies an excluded element of a context.
//
// This component is optional and therefore the API will only work if it is installed
func (a AjaxSpider) ModifyExcludedElement(contextname string, description string, element string, descriptionnew string, xpath string, text string, attributename string, attributevalue string, enabled string) (map[string]interface{}, error) {
m := map[string]string{
"contextName": contextname,
"description": description,
"element": element,
"descriptionNew": descriptionnew,
"xpath": xpath,
"text": text,
"attributeName": attributename,
"attributeValue": attributevalue,
"enabled": enabled,
}
return a.c.Request("ajaxSpider/action/modifyExcludedElement/", m)
}

// Removes an excluded element from a context.
//
// This component is optional and therefore the API will only work if it is installed
func (a AjaxSpider) RemoveExcludedElement(contextname string, description string) (map[string]interface{}, error) {
m := map[string]string{
"contextName": contextname,
"description": description,
}
return a.c.Request("ajaxSpider/action/removeExcludedElement/", m)
}

// Removes an allowed resource.
//
// This component is optional and therefore the API will only work if it is installed
Expand Down Expand Up @@ -211,7 +267,7 @@ func (a AjaxSpider) SetOptionBrowserId(str string) (map[string]interface{}, erro
return a.c.Request("ajaxSpider/action/setOptionBrowserId/", m)
}

// Sets whether or not the the AJAX Spider will only click on the default HTML elements.
// Sets whether or not the AJAX Spider will only click on the default HTML elements.
//
// This component is optional and therefore the API will only work if it is installed
func (a AjaxSpider) SetOptionClickDefaultElems(boolean bool) (map[string]interface{}, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (a AlertFilter) GlobalAlertFilterList() (map[string]interface{}, error) {
// Adds a new alert filter for the context with the given ID.
//
// This component is optional and therefore the API will only work if it is installed
func (a AlertFilter) AddAlertFilter(contextid string, ruleid string, newlevel string, url string, urlisregex string, parameter string, enabled string, parameterisregex string, attack string, attackisregex string, evidence string, evidenceisregex string) (map[string]interface{}, error) {
func (a AlertFilter) AddAlertFilter(contextid string, ruleid string, newlevel string, url string, urlisregex string, parameter string, enabled string, parameterisregex string, attack string, attackisregex string, evidence string, evidenceisregex string, methods string) (map[string]interface{}, error) {
m := map[string]string{
"contextId": contextid,
"ruleId": ruleid,
Expand All @@ -59,14 +59,15 @@ func (a AlertFilter) AddAlertFilter(contextid string, ruleid string, newlevel st
"attackIsRegex": attackisregex,
"evidence": evidence,
"evidenceIsRegex": evidenceisregex,
"methods": methods,
}
return a.c.Request("alertFilter/action/addAlertFilter/", m)
}

// Removes an alert filter from the context with the given ID.
//
// This component is optional and therefore the API will only work if it is installed
func (a AlertFilter) RemoveAlertFilter(contextid string, ruleid string, newlevel string, url string, urlisregex string, parameter string, enabled string, parameterisregex string, attack string, attackisregex string, evidence string, evidenceisregex string) (map[string]interface{}, error) {
func (a AlertFilter) RemoveAlertFilter(contextid string, ruleid string, newlevel string, url string, urlisregex string, parameter string, enabled string, parameterisregex string, attack string, attackisregex string, evidence string, evidenceisregex string, methods string) (map[string]interface{}, error) {
m := map[string]string{
"contextId": contextid,
"ruleId": ruleid,
Expand All @@ -80,14 +81,15 @@ func (a AlertFilter) RemoveAlertFilter(contextid string, ruleid string, newlevel
"attackIsRegex": attackisregex,
"evidence": evidence,
"evidenceIsRegex": evidenceisregex,
"methods": methods,
}
return a.c.Request("alertFilter/action/removeAlertFilter/", m)
}

// Adds a new global alert filter.
//
// This component is optional and therefore the API will only work if it is installed
func (a AlertFilter) AddGlobalAlertFilter(ruleid string, newlevel string, url string, urlisregex string, parameter string, enabled string, parameterisregex string, attack string, attackisregex string, evidence string, evidenceisregex string) (map[string]interface{}, error) {
func (a AlertFilter) AddGlobalAlertFilter(ruleid string, newlevel string, url string, urlisregex string, parameter string, enabled string, parameterisregex string, attack string, attackisregex string, evidence string, evidenceisregex string, methods string) (map[string]interface{}, error) {
m := map[string]string{
"ruleId": ruleid,
"newLevel": newlevel,
Expand All @@ -100,14 +102,15 @@ func (a AlertFilter) AddGlobalAlertFilter(ruleid string, newlevel string, url st
"attackIsRegex": attackisregex,
"evidence": evidence,
"evidenceIsRegex": evidenceisregex,
"methods": methods,
}
return a.c.Request("alertFilter/action/addGlobalAlertFilter/", m)
}

// Removes a global alert filter.
//
// This component is optional and therefore the API will only work if it is installed
func (a AlertFilter) RemoveGlobalAlertFilter(ruleid string, newlevel string, url string, urlisregex string, parameter string, enabled string, parameterisregex string, attack string, attackisregex string, evidence string, evidenceisregex string) (map[string]interface{}, error) {
func (a AlertFilter) RemoveGlobalAlertFilter(ruleid string, newlevel string, url string, urlisregex string, parameter string, enabled string, parameterisregex string, attack string, attackisregex string, evidence string, evidenceisregex string, methods string) (map[string]interface{}, error) {
m := map[string]string{
"ruleId": ruleid,
"newLevel": newlevel,
Expand All @@ -120,6 +123,7 @@ func (a AlertFilter) RemoveGlobalAlertFilter(ruleid string, newlevel string, url
"attackIsRegex": attackisregex,
"evidence": evidence,
"evidenceIsRegex": evidenceisregex,
"methods": methods,
}
return a.c.Request("alertFilter/action/removeGlobalAlertFilter/", m)
}
Expand Down
23 changes: 17 additions & 6 deletions zap/alert_generated.go → zap-api-go/zap/alert_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// ZAP is an HTTP/HTTPS proxy for assessing web application security.
//
// Copyright 2022 the ZAP development team
// Copyright 2017 the ZAP development team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -34,12 +34,13 @@ func (a Alert) Alert(id string) (map[string]interface{}, error) {
}

// Gets the alerts raised by ZAP, optionally filtering by URL or riskId, and paginating with 'start' position and 'count' of alerts
func (a Alert) Alerts(baseurl string, start string, count string, riskid string) (map[string]interface{}, error) {
func (a Alert) Alerts(baseurl string, start string, count string, riskid string, contextname string) (map[string]interface{}, error) {
m := map[string]string{
"baseurl": baseurl,
"start": start,
"count": count,
"riskId": riskid,
"baseurl": baseurl,
"start": start,
"count": count,
"riskId": riskid,
"contextName": contextname,
}
return a.c.Request("alert/view/alerts/", m)
}
Expand Down Expand Up @@ -84,6 +85,16 @@ func (a Alert) DeleteAllAlerts() (map[string]interface{}, error) {
return a.c.Request("alert/action/deleteAllAlerts/", nil)
}

// Deletes all the alerts optionally filtered by URL which fall within the Context with the provided name, risk, or base URL.
func (a Alert) DeleteAlerts(contextname string, baseurl string, riskid string) (map[string]interface{}, error) {
m := map[string]string{
"contextName": contextname,
"baseurl": baseurl,
"riskId": riskid,
}
return a.c.Request("alert/action/deleteAlerts/", m)
}

// Deletes the alert with the given ID.
func (a Alert) DeleteAlert(id string) (map[string]interface{}, error) {
m := map[string]string{
Expand Down
Loading