mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2026-11-08 02:08:33 -10:00
Compare commits
45
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
659b7cac81 | ||
|
|
c9beb400ec | ||
|
|
c9f52e4df9 | ||
|
|
56af26a502 | ||
|
|
8e1072e2b0 | ||
|
|
b53b530b6a | ||
|
|
bfdc507c6c | ||
|
|
ddf9b2fbec | ||
|
|
5e102b782b | ||
|
|
d1f4c98cd7 | ||
|
|
87c8cd8e01 | ||
|
|
35a0d673ad | ||
|
|
46782ff90c | ||
|
|
b1152efd42 | ||
|
|
d84aea93cc | ||
|
|
50023428d0 | ||
|
|
7af08e2b04 | ||
|
|
3064788d35 | ||
|
|
0da993afe6 | ||
|
|
4d5eb9c484 | ||
|
|
8a3818230d | ||
|
|
943a6f6643 | ||
|
|
091ca32b1c | ||
|
|
326f8774fd | ||
|
|
c94d226a49 | ||
|
|
c9fe07557c | ||
|
|
e16350cde6 | ||
|
|
0f79044dae | ||
|
|
c6bafd88eb | ||
|
|
80b3cc0627 | ||
|
|
02fadbcf77 | ||
|
|
f2f250738c | ||
|
|
1c76398aea | ||
|
|
0675aa48a3 | ||
|
|
f29b94521e | ||
|
|
d20ec34f63 | ||
|
|
1af29f97a9 | ||
|
|
1293a34707 | ||
|
|
c6e5bdd857 | ||
|
|
2f7eea410d | ||
|
|
2609d2d135 | ||
|
|
e0466e102c | ||
|
|
1e49cd9800 | ||
|
|
a5c7fe6094 | ||
|
|
f363b307d4 |
No files matched your search
@@ -0,0 +1,72 @@
|
||||
name: Bug Report
|
||||
description: Create a report to help us to improve the Nuclei.
|
||||
title: "[BUG] ..."
|
||||
labels: ["Type: Bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
For support requests, FAQs or "How to" questions, please use the [GitHub Discussions](https://github.com/projectdiscovery/nuclei/discussions) section instead or join our [Discord server](https://discord.gg/projectdiscovery) to discuss the idea on the **#nuclei** channel.
|
||||
|
||||
:warning: **Issues missing important information may be closed without further investigation.**
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues.
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Current Behavior
|
||||
description: A concise description of what you're experiencing.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps To Reproduce
|
||||
description: |
|
||||
Steps to reproduce the behavior, for example, commands to run Nuclei.
|
||||
|
||||
:warning: **Please redact any literal target hosts/URLs or other sensitive information.**
|
||||
placeholder: |
|
||||
1. Run `nuclei -t ...`
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Environment
|
||||
description: |
|
||||
Examples:
|
||||
- **OS**: Ubuntu 20.04
|
||||
- **Nuclei** (`nuclei -version`): v3.3.1
|
||||
- **Go** (`go version`): go1.22.0 _(only if you've installed it via the `go install` command)_
|
||||
value: |
|
||||
- OS:
|
||||
- Nuclei:
|
||||
- Go:
|
||||
render: markdown
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: |
|
||||
Links? References? Templates? Anything that will give us more context about the issue you are encountering!
|
||||
|
||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||
validations:
|
||||
required: false
|
||||
@@ -0,0 +1,37 @@
|
||||
name: Feature Request
|
||||
description: Request feature to implement in the Nuclei.
|
||||
title: "[FEATURE] ..."
|
||||
labels: ["Type: Enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this feature request!
|
||||
|
||||
Please make sure to provide a detailed description with all the relevant information that might be required to start working on this feature. In case you are not sure about your request or whether the particular feature is already supported or not, please [start a discussion](https://github.com/projectdiscovery/nuclei/discussions/categories/ideas) instead.
|
||||
|
||||
Join our [Discord server](https://discord.gg/projectdiscovery) to discuss the idea on the **#nuclei** channel.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe your feature request
|
||||
description: A clear and concise description of feature to implement.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the use case of the feature
|
||||
description: A clear and concise description of the feature request's motivation and the use-cases in which it could be useful.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the feature request here.
|
||||
validations:
|
||||
required: false
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Request feature to implement in this project
|
||||
title: ""
|
||||
labels: 'Type: Enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
1. Please make sure to provide a detailed description with all the relevant information that might be required to start working on this feature.
|
||||
2. In case you are not sure about your request or whether the particular feature is already supported or not, please start a discussion instead.
|
||||
3. GitHub Discussion: https://github.com/projectdiscovery/nuclei/discussions/categories/ideas
|
||||
4. Join our discord server at https://discord.gg/projectdiscovery to discuss the idea on the #nuclei channel.
|
||||
-->
|
||||
|
||||
### Please describe your feature request:
|
||||
<!-- A clear and concise description of feature to implement -->
|
||||
|
||||
### Describe the use case of this feature:
|
||||
<!-- A clear and concise description of the feature request's motivation and the use-cases in which it could be useful. -->
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
name: Issue report
|
||||
about: Create a report to help us to improve the project
|
||||
labels: 'Type: Bug'
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
1. Please search to see if an issue already exists for the bug you encountered.
|
||||
2. For support requests, FAQs or "How to" questions, please use the GitHub Discussions section instead - https://github.com/projectdiscovery/nuclei/discussions or
|
||||
3. Join our discord server at https://discord.gg/projectdiscovery and post the question on the #nuclei channel.
|
||||
-->
|
||||
|
||||
<!-- ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION. -->
|
||||
|
||||
### Nuclei version:
|
||||
<!-- You can find current version of nuclei with "nuclei -version" -->
|
||||
<!-- We only accept issues that are reproducible on the latest version of nuclei. -->
|
||||
<!-- You can find the latest version of project at https://github.com/projectdiscovery/nuclei/releases/ -->
|
||||
|
||||
## Nuclei command:
|
||||
|
||||
<!-- Provide the exact command you used to run Nuclei. -->
|
||||
<!-- Please redact any literal target hosts/URLs or other sensitive information. -->
|
||||
|
||||
### Current Behavior:
|
||||
<!-- A concise description of what you're experiencing. -->
|
||||
|
||||
### Expected Behavior:
|
||||
<!-- A concise description of what you expected to happen. -->
|
||||
|
||||
### Steps To Reproduce:
|
||||
<!--
|
||||
Example: steps to reproduce the behavior:
|
||||
1. Run 'nuclei -t ... -u ..'
|
||||
2. See error...
|
||||
-->
|
||||
|
||||
|
||||
### Anything else:
|
||||
<!-- Links? References? Screenshots? Anything that will give us more context about the issue that you are encountering! -->
|
||||
@@ -0,0 +1,8 @@
|
||||
addReviewers: true
|
||||
reviewers:
|
||||
- dogancanbakir
|
||||
|
||||
numberOfReviewers: 1
|
||||
# A list of keywords to be skipped the process that add reviewers if pull requests include it
|
||||
# skipKeywords:
|
||||
# - wip
|
||||
@@ -27,10 +27,8 @@ jobs:
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Go Mod hygiene
|
||||
run: |
|
||||
go clean -modcache
|
||||
go mod tidy
|
||||
- name: Verify Go modules
|
||||
run: make verify
|
||||
|
||||
- name: Build
|
||||
run: go build .
|
||||
|
||||
@@ -22,10 +22,8 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: projectdiscovery/actions/setup/go@v1
|
||||
|
||||
- name: Go Mod hygine
|
||||
run: |
|
||||
go clean -modcache
|
||||
go mod tidy
|
||||
- name: Verify Go modules
|
||||
run: make verify
|
||||
|
||||
# Max GH exection time 6H => timeout after that
|
||||
- name: Running performance with big list
|
||||
|
||||
+36
-37
@@ -1,43 +1,42 @@
|
||||
# Misc
|
||||
**/*-cache
|
||||
**/*-config
|
||||
**/.cache
|
||||
*.DS_Store
|
||||
*.exe
|
||||
.devcontainer
|
||||
.gitignore
|
||||
.idea
|
||||
.vscode
|
||||
.devcontainer
|
||||
vendor
|
||||
|
||||
# Binaries
|
||||
**/bindgen
|
||||
**/debug-*
|
||||
**/docgen
|
||||
**/functional-test
|
||||
**/fuzzplayground
|
||||
**/integration-test
|
||||
**/jsdocgen
|
||||
**/main
|
||||
**/memogen
|
||||
**/nuclei
|
||||
**/nuclei-stats*
|
||||
**/nuclei_dev
|
||||
**/nuclei_main
|
||||
**/scan-charts
|
||||
**/scrapefunc
|
||||
**/scrapefuncs
|
||||
**/tsgen
|
||||
|
||||
# Templates
|
||||
/*.yaml
|
||||
|
||||
# Generated docs
|
||||
/dsl.md
|
||||
|
||||
# Junk
|
||||
dist
|
||||
integration_tests/nuclei
|
||||
integration_tests/.cache
|
||||
integration_tests/integration-test
|
||||
cmd/nuclei/main
|
||||
cmd/nuclei/nuclei
|
||||
cmd/integration-test/nuclei
|
||||
cmd/functional-test/nuclei_dev
|
||||
cmd/functional-test/nuclei_main
|
||||
cmd/functional-test/functional-test
|
||||
cmd/docgen/docgen
|
||||
pkg/protocols/common/helpers/deserialization/testdata/Deserialize.class
|
||||
pkg/protocols/common/helpers/deserialization/testdata/ValueObject.class
|
||||
pkg/protocols/common/helpers/deserialization/testdata/ValueObject2.ser
|
||||
*.exe
|
||||
.gitignore
|
||||
pkg/js/devtools/bindgen/cmd/bindgen/bindgen
|
||||
pkg/js/devtools/jsdocgen/jsdocgen
|
||||
pkg/js/devtools/tsgen/tsgen
|
||||
pkg/js/devtools/tsgen/cmd/tsgen/tsgen
|
||||
*.DS_Store
|
||||
pkg/protocols/headless/engine/.cache
|
||||
/nuclei
|
||||
/bindgen
|
||||
/jsdocgen
|
||||
/tsgen
|
||||
/scrapefuncs
|
||||
/integration_tests/.cache/
|
||||
/*.yaml
|
||||
**/*-config
|
||||
**/*-cache
|
||||
/fuzzplayground
|
||||
integration_tests/fuzzplayground
|
||||
/dsl.md
|
||||
/nuclei-stats
|
||||
/nuclei-stats-*
|
||||
/scan-charts
|
||||
/**/debug-*
|
||||
|
||||
vendor
|
||||
@@ -1,62 +1,127 @@
|
||||
# Go parameters
|
||||
GOCMD=go
|
||||
GOBUILD=$(GOCMD) build
|
||||
GOMOD=$(GOCMD) mod
|
||||
GOTEST=$(GOCMD) test
|
||||
GOCMD := go
|
||||
GOBUILD := $(GOCMD) build
|
||||
GOBUILD_OUTPUT :=
|
||||
GOBUILD_PACKAGES :=
|
||||
GOBUILD_ADDITIONAL_ARGS :=
|
||||
GOMOD := $(GOCMD) mod
|
||||
GOTEST := $(GOCMD) test
|
||||
GOFLAGS := -v
|
||||
# This should be disabled if the binary uses pprof
|
||||
LDFLAGS := -s -w
|
||||
|
||||
ifneq ($(shell go env GOOS),darwin)
|
||||
LDFLAGS := -extldflags "-static"
|
||||
LDFLAGS = -extldflags "-static"
|
||||
endif
|
||||
|
||||
.PHONY: all build build-stats scan-charts docs test integration functional tidy devtools jsupdate ts fuzzplayground memogen dsl-docs
|
||||
.PHONY: all build build-stats clean devtools-all devtools-bindgen devtools-scrapefuncs
|
||||
.PHONY: devtools-tsgen docs dsl-docs functional fuzzplayground go-build integration
|
||||
.PHONY: jsupdate-all jsupdate-bindgen jsupdate-tsgen memogen scan-charts test tidy ts verify
|
||||
|
||||
all: build
|
||||
build:
|
||||
rm -f nuclei 2>/dev/null
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "nuclei" cmd/nuclei/main.go
|
||||
build-stats:
|
||||
rm -f nuclei-stats 2>/dev/null
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -tags=stats -o "nuclei-stats" cmd/nuclei/main.go
|
||||
scan-charts:
|
||||
rm -f scan-charts 2>/dev/null
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "scan-charts" cmd/scan-charts/main.go
|
||||
|
||||
clean:
|
||||
rm -f '${GOBUILD_OUTPUT}' 2>/dev/null
|
||||
|
||||
go-build: clean
|
||||
go-build:
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '${LDFLAGS}' $(GOBUILD_ADDITIONAL_ARGS) \
|
||||
-o '${GOBUILD_OUTPUT}' $(GOBUILD_PACKAGES)
|
||||
|
||||
build: GOBUILD_OUTPUT = nuclei
|
||||
build: GOBUILD_PACKAGES = cmd/nuclei/main.go
|
||||
build: go-build
|
||||
|
||||
build-stats: GOBUILD_OUTPUT = nuclei-stats
|
||||
build-stats: GOBUILD_PACKAGES = cmd/nuclei/main.go
|
||||
build-stats: GOBUILD_ADDITIONAL_ARGS = -tags=stats
|
||||
build-stats: go-build
|
||||
|
||||
scan-charts: GOBUILD_OUTPUT = scan-charts
|
||||
scan-charts: GOBUILD_PACKAGES = cmd/scan-charts/main.go
|
||||
scan-charts: go-build
|
||||
|
||||
docs: GOBUILD_OUTPUT = cmd/docgen/docgen
|
||||
docs: GOBUILD_PACKAGES = cmd/docgen/docgen.go
|
||||
docs: bin = dstdocgen
|
||||
docs:
|
||||
if ! which dstdocgen > /dev/null; then
|
||||
echo -e "Command not found! Install? (y/n) \c"
|
||||
go get -v github.com/projectdiscovery/yamldoc-go/cmd/docgen/dstdocgen
|
||||
@if ! which $(bin) >/dev/null; then \
|
||||
read -p "${bin} not found. Do you want to install it? (y/n) " answer; \
|
||||
if [ "$$answer" = "y" ]; then \
|
||||
echo "Installing ${bin}..."; \
|
||||
go get -v github.com/projectdiscovery/yamldoc-go/cmd/docgen/$(bin); \
|
||||
go install -v github.com/projectdiscovery/yamldoc-go/cmd/docgen/$(bin); \
|
||||
else \
|
||||
echo "Please install ${bin} manually."; \
|
||||
exit 1; \
|
||||
fi \
|
||||
fi
|
||||
|
||||
# TODO: Handle the panic, so that we just need to run `go install $(bin)@latest` (line 51-52)
|
||||
$(GOCMD) generate pkg/templates/templates.go
|
||||
$(GOBUILD) -o "cmd/docgen/docgen" cmd/docgen/docgen.go
|
||||
./cmd/docgen/docgen docs.md nuclei-jsonschema.json
|
||||
|
||||
$(GOBUILD) -o "${GOBUILD_OUTPUT}" $(GOBUILD_PACKAGES)
|
||||
./$(GOBUILD_OUTPUT) docs.md nuclei-jsonschema.json
|
||||
|
||||
git reset --hard # line 59
|
||||
|
||||
test:
|
||||
$(GOTEST) $(GOFLAGS) ./...
|
||||
|
||||
integration:
|
||||
cd integration_tests; bash run.sh
|
||||
|
||||
functional:
|
||||
cd cmd/functional-test; bash run.sh
|
||||
|
||||
tidy:
|
||||
$(GOMOD) tidy
|
||||
devtools:
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "bindgen" pkg/js/devtools/bindgen/cmd/bindgen/main.go
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "tsgen" pkg/js/devtools/tsgen/cmd/tsgen/main.go
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "scrapefuncs" pkg/js/devtools/scrapefuncs/main.go
|
||||
jsupdate:
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "bindgen" pkg/js/devtools/bindgen/cmd/bindgen/main.go
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "tsgen" pkg/js/devtools/tsgen/cmd/tsgen/main.go
|
||||
./bindgen -dir pkg/js/libs -out pkg/js/generated
|
||||
./tsgen -dir pkg/js/libs -out pkg/js/generated/ts
|
||||
ts:
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "tsgen" pkg/js/devtools/tsgen/cmd/tsgen/main.go
|
||||
./tsgen -dir pkg/js/libs -out pkg/js/generated/ts
|
||||
fuzzplayground:
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "fuzzplayground" cmd/tools/fuzzplayground/main.go
|
||||
|
||||
verify: tidy
|
||||
$(GOMOD) verify
|
||||
|
||||
devtools-bindgen: GOBUILD_OUTPUT = bindgen
|
||||
devtools-bindgen: GOBUILD_PACKAGES = pkg/js/devtools/bindgen/cmd/bindgen/main.go
|
||||
devtools-bindgen: go-build
|
||||
|
||||
devtools-tsgen: GOBUILD_OUTPUT = tsgen
|
||||
devtools-tsgen: GOBUILD_PACKAGES = pkg/js/devtools/tsgen/cmd/tsgen/main.go
|
||||
devtools-tsgen: go-build
|
||||
|
||||
devtools-scrapefuncs: GOBUILD_OUTPUT = scrapefuncs
|
||||
devtools-scrapefuncs: GOBUILD_PACKAGES = pkg/js/devtools/scrapefuncs/main.go
|
||||
devtools-scrapefuncs: go-build
|
||||
|
||||
devtools-all: devtools-bindgen devtools-tsgen devtools-scrapefuncs
|
||||
|
||||
jsupdate-bindgen: GOBUILD_OUTPUT = bindgen
|
||||
jsupdate-bindgen: GOBUILD_PACKAGES = pkg/js/devtools/bindgen/cmd/bindgen/main.go
|
||||
jsupdate-bindgen: go-build
|
||||
jsupdate-bindgen:
|
||||
./$(GOBUILD_OUTPUT) -dir pkg/js/libs -out pkg/js/generated
|
||||
|
||||
jsupdate-tsgen: GOBUILD_OUTPUT = tsgen
|
||||
jsupdate-tsgen: GOBUILD_PACKAGES = pkg/js/devtools/tsgen/cmd/tsgen/main.go
|
||||
jsupdate-tsgen: go-build
|
||||
jsupdate-tsgen:
|
||||
./$(GOBUILD_OUTPUT) -dir pkg/js/libs -out pkg/js/generated/ts
|
||||
|
||||
jsupdate-all: jsupdate-bindgen jsupdate-tsgen
|
||||
|
||||
ts: jsupdate-tsgen
|
||||
|
||||
fuzzplayground: GOBUILD_OUTPUT = fuzzplayground
|
||||
fuzzplayground: GOBUILD_PACKAGES = cmd/tools/fuzzplayground/main.go
|
||||
fuzzplayground: LDFLAGS = -s -w
|
||||
fuzzplayground: go-build
|
||||
|
||||
memogen: GOBUILD_OUTPUT = memogen
|
||||
memogen: GOBUILD_PACKAGES = cmd/memogen/memogen.go
|
||||
memogen: go-build
|
||||
memogen:
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "memogen" cmd/memogen/memogen.go
|
||||
./memogen -src pkg/js/libs -tpl cmd/memogen/function.tpl
|
||||
./$(GOBUILD_OUTPUT) -src pkg/js/libs -tpl cmd/memogen/function.tpl
|
||||
|
||||
dsl-docs: GOBUILD_OUTPUT = scrapefuncs
|
||||
dsl-docs: GOBUILD_PACKAGES = pkg/js/devtools/scrapefuncs/main.go
|
||||
dsl-docs:
|
||||
rm -f dsl.md scrapefuncs 2>/dev/null
|
||||
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "scrapefuncs" pkg/js/devtools/scrapefuncs/main.go
|
||||
./scrapefuncs -out dsl.md
|
||||
./$(GOBUILD_OUTPUT) -out dsl.md
|
||||
@@ -179,6 +179,7 @@ OUTPUT:
|
||||
-se, -sarif-export string file to export results in SARIF format
|
||||
-je, -json-export string file to export results in JSON format
|
||||
-jle, -jsonl-export string file to export results in JSONL(ine) format
|
||||
-rd, -redact string[] redact given list of keys from query parameter, request header and body
|
||||
|
||||
CONFIGURATIONS:
|
||||
-config string path to the nuclei configuration file
|
||||
@@ -310,6 +311,7 @@ STATISTICS:
|
||||
|
||||
CLOUD:
|
||||
-auth configure projectdiscovery cloud (pdcp) api key (default true)
|
||||
-tid, -team-id string upload scan results to given team id (optional) (default "none")
|
||||
-cup, -cloud-upload upload scan results to pdcp dashboard
|
||||
-sid, -scan-id string upload scan results to existing scan id (optional)
|
||||
-sname, -scan-name string scan name to set (optional)
|
||||
|
||||
@@ -1404,6 +1404,19 @@ Valid values:
|
||||
|
||||
<div class="dd">
|
||||
|
||||
<code>skip-secret-file</code> <i>bool</i>
|
||||
|
||||
</div>
|
||||
<div class="dt">
|
||||
|
||||
SkipSecretFile skips the authentication or authorization configured in the secret file.
|
||||
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="dd">
|
||||
|
||||
<code>cookie-reuse</code> <i>bool</i>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_pdcp "github.com/projectdiscovery/nuclei/v3/internal/pdcp"
|
||||
"github.com/projectdiscovery/utils/auth/pdcp"
|
||||
"github.com/projectdiscovery/utils/env"
|
||||
_ "github.com/projectdiscovery/utils/pprof"
|
||||
@@ -272,6 +273,7 @@ on extensive configurability, massive extensibility and ease of use.`)
|
||||
flagSet.StringVarP(&options.SarifExport, "sarif-export", "se", "", "file to export results in SARIF format"),
|
||||
flagSet.StringVarP(&options.JSONExport, "json-export", "je", "", "file to export results in JSON format"),
|
||||
flagSet.StringVarP(&options.JSONLExport, "jsonl-export", "jle", "", "file to export results in JSONL(ine) format"),
|
||||
flagSet.StringSliceVarP(&options.Redact, "redact", "rd", nil, "redact given list of keys from query parameter, request header and body", goflags.CommaSeparatedStringSliceOptions),
|
||||
)
|
||||
|
||||
flagSet.CreateGroup("configs", "Configurations",
|
||||
@@ -417,6 +419,7 @@ on extensive configurability, massive extensibility and ease of use.`)
|
||||
|
||||
flagSet.CreateGroup("cloud", "Cloud",
|
||||
flagSet.DynamicVar(&pdcpauth, "auth", "true", "configure projectdiscovery cloud (pdcp) api key"),
|
||||
flagSet.StringVarP(&options.TeamID, "team-id", "tid", _pdcp.TeamIDEnv, "upload scan results to given team id (optional)"),
|
||||
flagSet.BoolVarP(&options.EnableCloudUpload, "cloud-upload", "cup", false, "upload scan results to pdcp dashboard"),
|
||||
flagSet.StringVarP(&options.ScanID, "scan-id", "sid", "", "upload scan results to existing scan id (optional)"),
|
||||
flagSet.StringVarP(&options.ScanName, "scan-name", "sname", "", "scan name to set (optional)"),
|
||||
|
||||
+4
-4
@@ -162,7 +162,7 @@ func process(opts options) error {
|
||||
var updated bool // if max-requests is updated
|
||||
dataString, updated, err = parseAndAddMaxRequests(templateCatalog, path, dataString)
|
||||
if err != nil {
|
||||
gologger.Info().Label("max-request").Msgf(logErrMsg(path, err, opts.debug, errFile))
|
||||
gologger.Info().Label("max-request").Msg(logErrMsg(path, err, opts.debug, errFile))
|
||||
} else {
|
||||
if updated {
|
||||
gologger.Info().Label("max-request").Msgf("✅ updated template: %s\n", path)
|
||||
@@ -255,7 +255,7 @@ func enhanceTemplate(data string) (string, bool, error) {
|
||||
return data, false, errorutil.New("validation failed").WithTag("validate")
|
||||
}
|
||||
if templateResp.Error.Name != "" {
|
||||
return data, false, errorutil.New(templateResp.Error.Name)
|
||||
return data, false, errorutil.New("%s", templateResp.Error.Name)
|
||||
}
|
||||
if strings.TrimSpace(templateResp.Enhanced) == "" && !templateResp.Lint {
|
||||
if templateResp.LintError.Reason != "" {
|
||||
@@ -289,7 +289,7 @@ func formatTemplate(data string) (string, bool, error) {
|
||||
return data, false, errorutil.New("validation failed").WithTag("validate")
|
||||
}
|
||||
if templateResp.Error.Name != "" {
|
||||
return data, false, errorutil.New(templateResp.Error.Name)
|
||||
return data, false, errorutil.New("%s", templateResp.Error.Name)
|
||||
}
|
||||
if strings.TrimSpace(templateResp.Updated) == "" && !templateResp.Lint {
|
||||
if templateResp.LintError.Reason != "" {
|
||||
@@ -345,7 +345,7 @@ func validateTemplate(data string) (bool, error) {
|
||||
return false, errorutil.New("validation failed").WithTag("validate")
|
||||
}
|
||||
if validateResp.Error.Name != "" {
|
||||
return false, errorutil.New(validateResp.Error.Name)
|
||||
return false, errorutil.New("%s", validateResp.Error.Name)
|
||||
}
|
||||
return false, errorutil.New("template validation failed")
|
||||
}
|
||||
|
||||
@@ -16,16 +16,16 @@ require (
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
github.com/miekg/dns v1.1.59
|
||||
github.com/miekg/dns v1.1.62
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/projectdiscovery/clistats v0.0.20
|
||||
github.com/projectdiscovery/fastdialer v0.2.3
|
||||
github.com/projectdiscovery/hmap v0.0.54
|
||||
github.com/projectdiscovery/clistats v0.1.0
|
||||
github.com/projectdiscovery/fastdialer v0.2.5
|
||||
github.com/projectdiscovery/hmap v0.0.55
|
||||
github.com/projectdiscovery/interactsh v1.2.0
|
||||
github.com/projectdiscovery/rawhttp v0.1.60
|
||||
github.com/projectdiscovery/retryabledns v1.0.69
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.71
|
||||
github.com/projectdiscovery/retryabledns v1.0.72
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.74
|
||||
github.com/projectdiscovery/yamldoc-go v1.0.4
|
||||
github.com/remeh/sizedwaitgroup v1.0.0
|
||||
github.com/rs/xid v1.5.0
|
||||
@@ -36,11 +36,11 @@ require (
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/valyala/fasttemplate v1.2.2
|
||||
github.com/weppos/publicsuffix-go v0.30.2
|
||||
github.com/xanzy/go-gitlab v0.84.0
|
||||
github.com/xanzy/go-gitlab v0.107.0
|
||||
go.uber.org/multierr v1.11.0
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/oauth2 v0.18.0
|
||||
golang.org/x/text v0.16.0
|
||||
golang.org/x/net v0.28.0
|
||||
golang.org/x/oauth2 v0.22.0
|
||||
golang.org/x/text v0.17.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
@@ -65,12 +65,13 @@ require (
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/dop251/goja v0.0.0-20240220182346-e401ed450204
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/getkin/kin-openapi v0.123.0
|
||||
github.com/getkin/kin-openapi v0.126.0
|
||||
github.com/go-git/go-git/v5 v5.11.0
|
||||
github.com/go-ldap/ldap/v3 v3.4.5
|
||||
github.com/go-pg/pg v8.0.7+incompatible
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/h2non/filetype v1.1.3
|
||||
github.com/invopop/yaml v0.3.1
|
||||
github.com/labstack/echo/v4 v4.10.2
|
||||
github.com/leslie-qiwa/flat v0.0.0-20230424180412-f9d1cf014baa
|
||||
github.com/lib/pq v1.10.9
|
||||
@@ -82,8 +83,8 @@ require (
|
||||
github.com/projectdiscovery/dsl v0.1.8
|
||||
github.com/projectdiscovery/fasttemplate v0.0.2
|
||||
github.com/projectdiscovery/go-smb2 v0.0.0-20240129202741-052cc450c6cb
|
||||
github.com/projectdiscovery/goflags v0.1.62
|
||||
github.com/projectdiscovery/gologger v1.1.18
|
||||
github.com/projectdiscovery/goflags v0.1.65-0.20240824151034-33df02005a23
|
||||
github.com/projectdiscovery/gologger v1.1.19
|
||||
github.com/projectdiscovery/gostruct v0.0.2
|
||||
github.com/projectdiscovery/gozero v0.0.2
|
||||
github.com/projectdiscovery/httpx v1.6.7
|
||||
@@ -95,14 +96,14 @@ require (
|
||||
github.com/projectdiscovery/tlsx v1.1.6
|
||||
github.com/projectdiscovery/uncover v1.0.9
|
||||
github.com/projectdiscovery/useragent v0.0.65
|
||||
github.com/projectdiscovery/utils v0.2.4
|
||||
github.com/projectdiscovery/utils v0.2.6
|
||||
github.com/projectdiscovery/wappalyzergo v0.1.14
|
||||
github.com/redis/go-redis/v9 v9.1.0
|
||||
github.com/seh-msft/burpxml v1.0.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/tarunKoyalwar/goleak v0.0.0-20240429141123-0efa90dbdcf9
|
||||
github.com/zmap/zgrab2 v0.1.8-0.20230806160807-97ba87c0e706
|
||||
golang.org/x/term v0.21.0
|
||||
golang.org/x/term v0.23.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
moul.io/http2curl v1.0.0
|
||||
)
|
||||
@@ -152,8 +153,8 @@ require (
|
||||
github.com/gin-gonic/gin v1.9.1 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.9 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
@@ -168,7 +169,6 @@ require (
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.6 // indirect
|
||||
github.com/hbakhtiyor/strsim v0.0.0-20190107154042-4d2bbb273edf // indirect
|
||||
github.com/invopop/yaml v0.2.0 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/gofork v1.7.6 // indirect
|
||||
@@ -213,7 +213,7 @@ require (
|
||||
github.com/skeema/knownhosts v1.2.1 // indirect
|
||||
github.com/tidwall/btree v1.7.0 // indirect
|
||||
github.com/tidwall/buntdb v1.3.1 // indirect
|
||||
github.com/tidwall/gjson v1.17.1 // indirect
|
||||
github.com/tidwall/gjson v1.17.3 // indirect
|
||||
github.com/tidwall/grect v0.1.4 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
@@ -234,7 +234,7 @@ require (
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
go.uber.org/goleak v1.3.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
gopkg.in/djherbis/times.v1 v1.3.0 // indirect
|
||||
mellium.im/sasl v0.3.1 // indirect
|
||||
)
|
||||
@@ -262,7 +262,6 @@ require (
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
@@ -279,7 +278,7 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/mholt/acmez v1.2.0 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.26 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
@@ -302,14 +301,13 @@ require (
|
||||
go.etcd.io/bbolt v1.3.10 // indirect
|
||||
go.uber.org/zap v1.25.0 // indirect
|
||||
goftp.io/server/v2 v2.0.1 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
golang.org/x/tools v0.24.0
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
|
||||
gopkg.in/corvus-ch/zbase32.v1 v1.0.0 // indirect
|
||||
)
|
||||
|
||||
@@ -329,8 +329,8 @@ github.com/gaissmai/bart v0.9.5 h1:vy+r4Px6bjZ+v2QYXAsg63vpz9IfzdW146A8Cn4GPIo=
|
||||
github.com/gaissmai/bart v0.9.5/go.mod h1:KHeYECXQiBjTzQz/om2tqn3sZF1J7hw9m6z41ftj3fg=
|
||||
github.com/geoffgarside/ber v1.1.0 h1:qTmFG4jJbwiSzSXoNJeHcOprVzZ8Ulde2Rrrifu5U9w=
|
||||
github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc=
|
||||
github.com/getkin/kin-openapi v0.123.0 h1:zIik0mRwFNLyvtXK274Q6ut+dPh6nlxBp0x7mNrPhs8=
|
||||
github.com/getkin/kin-openapi v0.123.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
|
||||
github.com/getkin/kin-openapi v0.126.0 h1:c2cSgLnAsS0xYfKsgt5oBV6MYRM/giU8/RtwUY4wyfY=
|
||||
github.com/getkin/kin-openapi v0.126.0/go.mod h1:7mONz8IwmSRg6RttPu6v8U/OJ+gr+J99qSFNjPGSQqw=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
@@ -369,10 +369,10 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
|
||||
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
|
||||
github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE=
|
||||
github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-pg/pg v8.0.7+incompatible h1:ty/sXL1OZLo+47KK9N8llRcmbA9tZasqbQ/OO4ld53g=
|
||||
github.com/go-pg/pg v8.0.7+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
@@ -453,8 +453,6 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
@@ -572,8 +570,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI=
|
||||
github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
|
||||
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
|
||||
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
|
||||
github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso=
|
||||
github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
|
||||
github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU=
|
||||
github.com/itchyny/gojq v0.12.13/go.mod h1:JzwzAqenfhrPUuwbmEz3nu3JQmFLlQTQMUcOdnu/Sf4=
|
||||
github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
|
||||
@@ -709,14 +707,14 @@ github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1
|
||||
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM=
|
||||
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
|
||||
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
|
||||
github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc=
|
||||
github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
|
||||
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||
github.com/minio/minio-go/v6 v6.0.46/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg=
|
||||
github.com/minio/selfupdate v0.6.1-0.20230907112617-f11e74f84ca7 h1:yRZGarbxsRytL6EGgbqK2mCY+Lk5MWKQYKJT2gEglhc=
|
||||
github.com/minio/selfupdate v0.6.1-0.20230907112617-f11e74f84ca7/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
|
||||
@@ -830,28 +828,28 @@ github.com/projectdiscovery/blackrock v0.0.1 h1:lHQqhaaEFjgf5WkuItbpeCZv2DUIE45k
|
||||
github.com/projectdiscovery/blackrock v0.0.1/go.mod h1:ANUtjDfaVrqB453bzToU+YB4cUbvBRpLvEwoWIwlTss=
|
||||
github.com/projectdiscovery/cdncheck v1.1.0 h1:qDITidmJsejzpk3rMkauCh6sjI2GH9hW/snk0cQ3kXE=
|
||||
github.com/projectdiscovery/cdncheck v1.1.0/go.mod h1:sZ8U4MjHSsyaTVjBbYWHT1cwUVvUYwDX1W+WvWRicIc=
|
||||
github.com/projectdiscovery/clistats v0.0.20 h1:5jO5SLiRJ7f0nDV0ndBNmBeesbROouPooH+DGMgoWq4=
|
||||
github.com/projectdiscovery/clistats v0.0.20/go.mod h1:GJ2av0KnOvK0AISQnP8hyDclYIji1LVkx2l0pwnzAu4=
|
||||
github.com/projectdiscovery/clistats v0.1.0 h1:b+LF1w0xhNd7cneKWMXb+/yUmF1n5szawxP4XGpmbxs=
|
||||
github.com/projectdiscovery/clistats v0.1.0/go.mod h1:GJ2av0KnOvK0AISQnP8hyDclYIji1LVkx2l0pwnzAu4=
|
||||
github.com/projectdiscovery/dsl v0.1.8 h1:ulz+o097XsYgqP4QXaAQhVSkoeD2ZPWd29wX3CTodUA=
|
||||
github.com/projectdiscovery/dsl v0.1.8/go.mod h1:AYJS2WQ/q0smr2v4pEJTg4DPe6k56KFKR7UFXvzNz/4=
|
||||
github.com/projectdiscovery/fastdialer v0.2.3 h1:K03x5XEXGyVWxS2rtSR104E9kHF0aphN7kOCzbh8zv0=
|
||||
github.com/projectdiscovery/fastdialer v0.2.3/go.mod h1:a0BKvETrO1EAohUYp9gwtbbce0hKD1qGrTegyAUqyRo=
|
||||
github.com/projectdiscovery/fastdialer v0.2.5 h1:OZg31LFIBBHbXVnOEcFNtD0gBM80zpY68QvYI0xbw80=
|
||||
github.com/projectdiscovery/fastdialer v0.2.5/go.mod h1:E1vmos7AeD/KZ7rsDeImjLp5H3jjas+2utVdUxGulvY=
|
||||
github.com/projectdiscovery/fasttemplate v0.0.2 h1:h2cISk5xDhlJEinlBQS6RRx0vOlOirB2y3Yu4PJzpiA=
|
||||
github.com/projectdiscovery/fasttemplate v0.0.2/go.mod h1:XYWWVMxnItd+r0GbjA1GCsUopMw1/XusuQxdyAIHMCw=
|
||||
github.com/projectdiscovery/freeport v0.0.5 h1:jnd3Oqsl4S8n0KuFkE5Hm8WGDP24ITBvmyw5pFTHS8Q=
|
||||
github.com/projectdiscovery/freeport v0.0.5/go.mod h1:PY0bxSJ34HVy67LHIeF3uIutiCSDwOqKD8ruBkdiCwE=
|
||||
github.com/projectdiscovery/go-smb2 v0.0.0-20240129202741-052cc450c6cb h1:rutG906Drtbpz4DwU5mhGIeOhRcktDH4cGQitGUMAsg=
|
||||
github.com/projectdiscovery/go-smb2 v0.0.0-20240129202741-052cc450c6cb/go.mod h1:FLjF1DmZ+POoGEiIQdWuYVwS++C/GwpX8YaCsTSm1RY=
|
||||
github.com/projectdiscovery/goflags v0.1.62 h1:UmzKJQT+1UyqT1cZDmb3vZ8/IGhQ7LTsWfdqVcAGoJc=
|
||||
github.com/projectdiscovery/goflags v0.1.62/go.mod h1:d1/D8GaTDoV332ABwceUcY1ffKODaYFlGP0Oriq3wfk=
|
||||
github.com/projectdiscovery/gologger v1.1.18 h1:fux2S/LXYe18/w4PylAFpEFg+EApNCuyS85x25nDE98=
|
||||
github.com/projectdiscovery/gologger v1.1.18/go.mod h1:IgjKgVLfVGUovxlC6WJcXK0qvo/tNZ1P0+r6miQqyRk=
|
||||
github.com/projectdiscovery/goflags v0.1.65-0.20240824151034-33df02005a23 h1:6RTUy0fybNvQDZqJFz1RRFdQds4+ZhCpN299+ApOxyQ=
|
||||
github.com/projectdiscovery/goflags v0.1.65-0.20240824151034-33df02005a23/go.mod h1:3FyHIVQtnycNOc1LE3O1jj/XR5XuMdF9QfHd0ujhnX4=
|
||||
github.com/projectdiscovery/gologger v1.1.19 h1:b7cU32XuDrDiwhr7hlDeE6mfj/nENBtHEohe51txJCE=
|
||||
github.com/projectdiscovery/gologger v1.1.19/go.mod h1:DbeKwx9IEfcvnclImX5gBlhIKUuOZwOM5itdpYXl+54=
|
||||
github.com/projectdiscovery/gostruct v0.0.2 h1:s8gP8ApugGM4go1pA+sVlPDXaWqNP5BBDDSv7VEdG1M=
|
||||
github.com/projectdiscovery/gostruct v0.0.2/go.mod h1:H86peL4HKwMXcQQtEa6lmC8FuD9XFt6gkNR0B/Mu5PE=
|
||||
github.com/projectdiscovery/gozero v0.0.2 h1:8fJeaCjxL9tpm33uG/RsCQs6HGM/NE6eA3cjkilRQ+E=
|
||||
github.com/projectdiscovery/gozero v0.0.2/go.mod h1:d8bZvDWW07LWNYWrwjZ4OO1I0cpkfqaysyDfSs9ibK8=
|
||||
github.com/projectdiscovery/hmap v0.0.54 h1:b3pdQZwCw4is3xiL2jBx7SJZcYaf/7vtozY7bjUzO/s=
|
||||
github.com/projectdiscovery/hmap v0.0.54/go.mod h1:j0oakxYOWEfk29wRq5gQgrCv1JnfAfzGaMsRWwEas80=
|
||||
github.com/projectdiscovery/hmap v0.0.55 h1:By0qSeQRE/ybeITUEL6oURN+j7qX7FVjCq92duwsqcA=
|
||||
github.com/projectdiscovery/hmap v0.0.55/go.mod h1:uZOF/W8yOGDb/t9omqATirhVwiboa5F/c00OVhDeE0E=
|
||||
github.com/projectdiscovery/httpx v1.6.7 h1:luJAtQ+iKpiyKKDpcWw1/fF1MaRX6JZ4R3P+ol5Uikk=
|
||||
github.com/projectdiscovery/httpx v1.6.7/go.mod h1:rqcuexBrb4v36ZyX0BHcHaovTurOJn2P65Tdt9cYdfE=
|
||||
github.com/projectdiscovery/interactsh v1.2.0 h1:Al6jHiR+Usl9egYJDLJaWNHOcH8Rugk8gWMasc8Cmw8=
|
||||
@@ -872,10 +870,10 @@ github.com/projectdiscovery/rawhttp v0.1.60 h1:L57kAATGRuCfOp8Fs0ly3j2wlip7R5pco
|
||||
github.com/projectdiscovery/rawhttp v0.1.60/go.mod h1:M97w6lsphTHKeqLSio4Lw9K4KLO2riJMYAOqVMIZ3ck=
|
||||
github.com/projectdiscovery/rdap v0.9.1-0.20221108103045-9865884d1917 h1:m03X4gBVSorSzvmm0bFa7gDV4QNSOWPL/fgZ4kTXBxk=
|
||||
github.com/projectdiscovery/rdap v0.9.1-0.20221108103045-9865884d1917/go.mod h1:JxXtZC9e195awe7EynrcnBJmFoad/BNDzW9mzFkK8Sg=
|
||||
github.com/projectdiscovery/retryabledns v1.0.69 h1:6vhhlfxPQoJI0j1enYSzyagyAZJNfGSg9TNloVsxEBQ=
|
||||
github.com/projectdiscovery/retryabledns v1.0.69/go.mod h1:5SDuGtXgL4W1z/9V+xnmHFYg03Fi1Ud/F2kqlPlAgfE=
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.71 h1:yXPNShCOwoTz7dBSJsBhBh4g4ujX62XS/BrH/fL1VyE=
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.71/go.mod h1:wY3T89EwcCKAw6iyMDvwzGPyL3d8TaBU80hnDErEKgM=
|
||||
github.com/projectdiscovery/retryabledns v1.0.72 h1:+k9JRYBMpZIyEQZJWVHoCHx1TEdpiuAS7iEru2bhs3A=
|
||||
github.com/projectdiscovery/retryabledns v1.0.72/go.mod h1:BDhYnqSH0Os2G37eb4L4vnKrUcik6Q6pR02Cq5PbT+0=
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.74 h1:jXZsg3nNDuDjGNeL0+hiEx/dqUqPyZW1zsotWW1y70c=
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.74/go.mod h1:fVRxa2fVMbomaPiOFA05kM2WrjV8wPFHW7J84eenVmQ=
|
||||
github.com/projectdiscovery/sarif v0.0.1 h1:C2Tyj0SGOKbCLgHrx83vaE6YkzXEVrMXYRGLkKCr/us=
|
||||
github.com/projectdiscovery/sarif v0.0.1/go.mod h1:cEYlDu8amcPf6b9dSakcz2nNnJsoz4aR6peERwV+wuQ=
|
||||
github.com/projectdiscovery/stringsutil v0.0.2 h1:uzmw3IVLJSMW1kEg8eCStG/cGbYYZAja8BH3LqqJXMA=
|
||||
@@ -886,8 +884,8 @@ github.com/projectdiscovery/uncover v1.0.9 h1:s5RbkD/V4r8QcPkys4gTTqMuRSgXq0Jpre
|
||||
github.com/projectdiscovery/uncover v1.0.9/go.mod h1:2PUF3SpB5QNIJ8epaB2xbRzkPaxEAWRDm3Ir2ijt81U=
|
||||
github.com/projectdiscovery/useragent v0.0.65 h1:x78ZwWdqpzokOHxLITUXvq+ljkTKc19z3ILGtoV1N70=
|
||||
github.com/projectdiscovery/useragent v0.0.65/go.mod h1:deOP8YLJU6SCzM8k+K8PjkcOF4Ux0spqyO4ODZGIT4A=
|
||||
github.com/projectdiscovery/utils v0.2.4 h1:CHnlt2la4jr8TeL7ZK7UhQItHY7DDXqIuLnnxyAJLDY=
|
||||
github.com/projectdiscovery/utils v0.2.4/go.mod h1:2Vx7geSrBfCPqknZywqbChQm8SE30mcyrlB5YsxEnhA=
|
||||
github.com/projectdiscovery/utils v0.2.6 h1:7ZZ+tK8u3vO/X7i0HXwybNusFBtYnM363bxDxJkVnso=
|
||||
github.com/projectdiscovery/utils v0.2.6/go.mod h1:XFy8Ldt537TGkj3snH0zXfF9LigRfmHPGCNfDolSdEQ=
|
||||
github.com/projectdiscovery/wappalyzergo v0.1.14 h1:nt1IM4RUmqeymsXk4h6BsZbKDoS2hjFvPkT2GaI1rz4=
|
||||
github.com/projectdiscovery/wappalyzergo v0.1.14/go.mod h1:/hzgxkBFTMe2wDbA93nFfoMjULw7/vIZ9QPSAnCgUa8=
|
||||
github.com/projectdiscovery/yamldoc-go v1.0.4 h1:eZoESapnMw6WAHiVgRwNqvbJEfNHEH148uthhFbG5jE=
|
||||
@@ -1019,8 +1017,8 @@ github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EU
|
||||
github.com/tidwall/buntdb v1.3.1 h1:HKoDF01/aBhl9RjYtbaLnvX9/OuenwvQiC3OP1CcL4o=
|
||||
github.com/tidwall/buntdb v1.3.1/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU=
|
||||
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
|
||||
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94=
|
||||
github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/grect v0.1.4 h1:dA3oIgNgWdSspFzn1kS4S/RDpZFLrIxAZOdJKjYapOg=
|
||||
github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q=
|
||||
github.com/tidwall/lotsa v1.0.2 h1:dNVBH5MErdaQ/xd9s769R31/n2dXavsQ0Yf4TMEHHw8=
|
||||
@@ -1068,8 +1066,8 @@ github.com/weppos/publicsuffix-go v0.30.2/go.mod h1:/hGscit36Yt+wammfBBwdMdxBT8b
|
||||
github.com/weppos/publicsuffix-go/publicsuffix/generator v0.0.0-20220927085643-dc0d00c92642/go.mod h1:GHfoeIdZLdZmLjMlzBftbTDntahTttUMWjxZwQJhULE=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||
github.com/xanzy/go-gitlab v0.84.0 h1:PdpCaskQSgcVDsx21c6ikf8Rfyo7SNtFAJwP9PrbCFE=
|
||||
github.com/xanzy/go-gitlab v0.84.0/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
|
||||
github.com/xanzy/go-gitlab v0.107.0 h1:P2CT9Uy9yN9lJo3FLxpMZ4xj6uWcpnigXsjvqJ6nd2Y=
|
||||
github.com/xanzy/go-gitlab v0.107.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@@ -1185,8 +1183,8 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -1197,8 +1195,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA=
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -1221,8 +1219,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -1280,8 +1278,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1291,8 +1289,8 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
|
||||
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
|
||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -1306,8 +1304,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1383,8 +1381,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@@ -1397,8 +1395,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
|
||||
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -1415,14 +1413,14 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -1474,8 +1472,8 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -1505,8 +1503,6 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
@@ -1569,8 +1565,9 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -1604,7 +1601,6 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
||||
|
||||
@@ -5,9 +5,17 @@ import (
|
||||
urlutil "github.com/projectdiscovery/utils/url"
|
||||
)
|
||||
|
||||
func getScanDashBoardURL(id string) string {
|
||||
func getScanDashBoardURL(id string, teamID string) string {
|
||||
ux, _ := urlutil.Parse(pdcpauth.DashBoardURL)
|
||||
ux.Path = "/scans/" + id
|
||||
if ux.Params == nil {
|
||||
ux.Params = urlutil.NewOrderedParams()
|
||||
}
|
||||
if teamID != "" {
|
||||
ux.Params.Add("team_id", teamID)
|
||||
} else {
|
||||
ux.Params.Add("team_id", NoneTeamID)
|
||||
}
|
||||
ux.Update()
|
||||
return ux.String()
|
||||
}
|
||||
|
||||
+18
-7
@@ -32,13 +32,14 @@ const (
|
||||
MaxChunkSize = 4 * unitutils.Mega // 4 MB
|
||||
xidRe = `^[a-z0-9]{20}$`
|
||||
teamIDHeader = "X-Team-Id"
|
||||
NoneTeamID = "none"
|
||||
)
|
||||
|
||||
var (
|
||||
xidRegex = regexp.MustCompile(xidRe)
|
||||
_ output.Writer = &UploadWriter{}
|
||||
// teamID if given
|
||||
teamID = env.GetEnvOrDefault("PDCP_TEAM_ID", "")
|
||||
TeamIDEnv = env.GetEnvOrDefault("PDCP_TEAM_ID", NoneTeamID)
|
||||
)
|
||||
|
||||
// UploadWriter is a writer that uploads its output to pdcp
|
||||
@@ -53,6 +54,7 @@ type UploadWriter struct {
|
||||
scanID string
|
||||
scanName string
|
||||
counter atomic.Int32
|
||||
TeamID string
|
||||
}
|
||||
|
||||
// NewUploadWriter creates a new upload writer
|
||||
@@ -61,8 +63,9 @@ func NewUploadWriter(ctx context.Context, creds *pdcpauth.PDCPCredentials) (*Upl
|
||||
return nil, fmt.Errorf("no credentials provided")
|
||||
}
|
||||
u := &UploadWriter{
|
||||
creds: creds,
|
||||
done: make(chan struct{}, 1),
|
||||
creds: creds,
|
||||
done: make(chan struct{}, 1),
|
||||
TeamID: NoneTeamID,
|
||||
}
|
||||
var err error
|
||||
reader, writer := io.Pipe()
|
||||
@@ -110,6 +113,14 @@ func (u *UploadWriter) SetScanName(name string) {
|
||||
u.scanName = name
|
||||
}
|
||||
|
||||
func (u *UploadWriter) SetTeamID(id string) {
|
||||
if id == "" {
|
||||
u.TeamID = NoneTeamID
|
||||
} else {
|
||||
u.TeamID = id
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UploadWriter) autoCommit(ctx context.Context, r *io.PipeReader) {
|
||||
reader := bufio.NewReader(r)
|
||||
ch := make(chan string, 4)
|
||||
@@ -136,7 +147,7 @@ func (u *UploadWriter) autoCommit(ctx context.Context, r *io.PipeReader) {
|
||||
if u.scanID == "" {
|
||||
gologger.Verbose().Msgf("Scan results upload to cloud skipped, no results found to upload")
|
||||
} else {
|
||||
gologger.Info().Msgf("%v Scan results uploaded to cloud, you can view scan results at %v", u.counter.Load(), getScanDashBoardURL(u.scanID))
|
||||
gologger.Info().Msgf("%v Scan results uploaded to cloud, you can view scan results at %v", u.counter.Load(), getScanDashBoardURL(u.scanID, u.TeamID))
|
||||
}
|
||||
}()
|
||||
// temporary buffer to store the results
|
||||
@@ -189,7 +200,7 @@ func (u *UploadWriter) uploadChunk(buff *bytes.Buffer) error {
|
||||
// if successful, reset the buffer
|
||||
buff.Reset()
|
||||
// log in verbose mode
|
||||
gologger.Warning().Msgf("Uploaded results chunk, you can view scan results at %v", getScanDashBoardURL(u.scanID))
|
||||
gologger.Warning().Msgf("Uploaded results chunk, you can view scan results at %v", getScanDashBoardURL(u.scanID, u.TeamID))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -248,8 +259,8 @@ func (u *UploadWriter) getRequest(bin []byte) (*retryablehttp.Request, error) {
|
||||
req.URL.Update()
|
||||
|
||||
req.Header.Set(pdcpauth.ApiKeyHeaderName, u.creds.APIKey)
|
||||
if teamID != "" {
|
||||
req.Header.Set(teamIDHeader, teamID)
|
||||
if u.TeamID != NoneTeamID && u.TeamID != "" {
|
||||
req.Header.Set(teamIDHeader, u.TeamID)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/octet-stream")
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
@@ -426,6 +426,9 @@ func (r *Runner) setupPDCPUpload(writer output.Writer) output.Writer {
|
||||
if r.options.ScanName != "" {
|
||||
uploadWriter.SetScanName(r.options.ScanName)
|
||||
}
|
||||
if r.options.TeamID != "" {
|
||||
uploadWriter.SetTeamID(r.options.TeamID)
|
||||
}
|
||||
return output.NewMultiWriter(writer, uploadWriter)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -82,5 +82,5 @@ func TestMain(m *testing.M) {
|
||||
// no need to run this test on github actions
|
||||
return
|
||||
}
|
||||
m.Run()
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
+2
-1
@@ -178,7 +178,8 @@ func (e *NucleiEngine) SignTemplate(tmplSigner *signer.TemplateSigner, data []by
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
buff := bytes.NewBuffer(signer.RemoveSignatureFromData(data))
|
||||
_, content := signer.ExtractSignatureAndContent(data)
|
||||
buff := bytes.NewBuffer(content)
|
||||
buff.WriteString("\n" + signatureData)
|
||||
return buff.Bytes(), err
|
||||
}
|
||||
|
||||
@@ -787,6 +787,11 @@
|
||||
"title": "signature is the http request signature method",
|
||||
"description": "Signature is the HTTP Request signature Method"
|
||||
},
|
||||
"skip-secret-file": {
|
||||
"type": "boolean",
|
||||
"title": "bypass secret file",
|
||||
"description": "Skips the authentication or authorization configured in the secret file"
|
||||
},
|
||||
"cookie-reuse": {
|
||||
"type": "boolean",
|
||||
"title": "optional cookie reuse enable",
|
||||
|
||||
+47
-31
@@ -16,8 +16,8 @@ import (
|
||||
type FileAuthProvider struct {
|
||||
Path string
|
||||
store *authx.Authx
|
||||
compiled map[*regexp.Regexp]authx.AuthStrategy
|
||||
domains map[string]authx.AuthStrategy
|
||||
compiled map[*regexp.Regexp][]authx.AuthStrategy
|
||||
domains map[string][]authx.AuthStrategy
|
||||
}
|
||||
|
||||
// NewFileAuthProvider creates a new file based auth provider
|
||||
@@ -56,25 +56,31 @@ func (f *FileAuthProvider) init() {
|
||||
if len(secret.DomainsRegex) > 0 {
|
||||
for _, domain := range secret.DomainsRegex {
|
||||
if f.compiled == nil {
|
||||
f.compiled = make(map[*regexp.Regexp]authx.AuthStrategy)
|
||||
f.compiled = make(map[*regexp.Regexp][]authx.AuthStrategy)
|
||||
}
|
||||
compiled, err := regexp.Compile(domain)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
f.compiled[compiled] = secret.GetStrategy()
|
||||
|
||||
if ss, ok := f.compiled[compiled]; ok {
|
||||
f.compiled[compiled] = append(ss, secret.GetStrategy())
|
||||
} else {
|
||||
f.compiled[compiled] = []authx.AuthStrategy{secret.GetStrategy()}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, domain := range secret.Domains {
|
||||
if f.domains == nil {
|
||||
f.domains = make(map[string]authx.AuthStrategy)
|
||||
f.domains = make(map[string][]authx.AuthStrategy)
|
||||
}
|
||||
f.domains[strings.TrimSpace(domain)] = secret.GetStrategy()
|
||||
if strings.HasSuffix(domain, ":80") {
|
||||
f.domains[strings.TrimSuffix(domain, ":80")] = secret.GetStrategy()
|
||||
}
|
||||
if strings.HasSuffix(domain, ":443") {
|
||||
f.domains[strings.TrimSuffix(domain, ":443")] = secret.GetStrategy()
|
||||
domain = strings.TrimSpace(domain)
|
||||
domain = strings.TrimSuffix(domain, ":80")
|
||||
domain = strings.TrimSuffix(domain, ":443")
|
||||
if ss, ok := f.domains[domain]; ok {
|
||||
f.domains[domain] = append(ss, secret.GetStrategy())
|
||||
} else {
|
||||
f.domains[domain] = []authx.AuthStrategy{secret.GetStrategy()}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,32 +88,38 @@ func (f *FileAuthProvider) init() {
|
||||
if len(dynamic.DomainsRegex) > 0 {
|
||||
for _, domain := range dynamic.DomainsRegex {
|
||||
if f.compiled == nil {
|
||||
f.compiled = make(map[*regexp.Regexp]authx.AuthStrategy)
|
||||
f.compiled = make(map[*regexp.Regexp][]authx.AuthStrategy)
|
||||
}
|
||||
compiled, err := regexp.Compile(domain)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
f.compiled[compiled] = &authx.DynamicAuthStrategy{Dynamic: dynamic}
|
||||
if ss, ok := f.compiled[compiled]; !ok {
|
||||
f.compiled[compiled] = []authx.AuthStrategy{&authx.DynamicAuthStrategy{Dynamic: dynamic}}
|
||||
} else {
|
||||
f.compiled[compiled] = append(ss, &authx.DynamicAuthStrategy{Dynamic: dynamic})
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, domain := range dynamic.Domains {
|
||||
if f.domains == nil {
|
||||
f.domains = make(map[string]authx.AuthStrategy)
|
||||
f.domains = make(map[string][]authx.AuthStrategy)
|
||||
}
|
||||
f.domains[strings.TrimSpace(domain)] = &authx.DynamicAuthStrategy{Dynamic: dynamic}
|
||||
if strings.HasSuffix(domain, ":80") {
|
||||
f.domains[strings.TrimSuffix(domain, ":80")] = &authx.DynamicAuthStrategy{Dynamic: dynamic}
|
||||
}
|
||||
if strings.HasSuffix(domain, ":443") {
|
||||
f.domains[strings.TrimSuffix(domain, ":443")] = &authx.DynamicAuthStrategy{Dynamic: dynamic}
|
||||
domain = strings.TrimSpace(domain)
|
||||
domain = strings.TrimSuffix(domain, ":80")
|
||||
domain = strings.TrimSuffix(domain, ":443")
|
||||
|
||||
if ss, ok := f.domains[domain]; !ok {
|
||||
f.domains[domain] = []authx.AuthStrategy{&authx.DynamicAuthStrategy{Dynamic: dynamic}}
|
||||
} else {
|
||||
f.domains[domain] = append(ss, &authx.DynamicAuthStrategy{Dynamic: dynamic})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LookupAddr looks up a given domain/address and returns appropriate auth strategy
|
||||
func (f *FileAuthProvider) LookupAddr(addr string) authx.AuthStrategy {
|
||||
func (f *FileAuthProvider) LookupAddr(addr string) []authx.AuthStrategy {
|
||||
if strings.Contains(addr, ":") {
|
||||
// default normalization for host:port
|
||||
host, port, err := net.SplitHostPort(addr)
|
||||
@@ -129,12 +141,12 @@ func (f *FileAuthProvider) LookupAddr(addr string) authx.AuthStrategy {
|
||||
}
|
||||
|
||||
// LookupURL looks up a given URL and returns appropriate auth strategy
|
||||
func (f *FileAuthProvider) LookupURL(u *url.URL) authx.AuthStrategy {
|
||||
func (f *FileAuthProvider) LookupURL(u *url.URL) []authx.AuthStrategy {
|
||||
return f.LookupAddr(u.Host)
|
||||
}
|
||||
|
||||
// LookupURLX looks up a given URL and returns appropriate auth strategy
|
||||
func (f *FileAuthProvider) LookupURLX(u *urlutil.URL) authx.AuthStrategy {
|
||||
func (f *FileAuthProvider) LookupURLX(u *urlutil.URL) []authx.AuthStrategy {
|
||||
return f.LookupAddr(u.Host)
|
||||
}
|
||||
|
||||
@@ -151,17 +163,21 @@ func (f *FileAuthProvider) GetTemplatePaths() []string {
|
||||
|
||||
// PreFetchSecrets pre-fetches the secrets from the auth provider
|
||||
func (f *FileAuthProvider) PreFetchSecrets() error {
|
||||
for _, s := range f.domains {
|
||||
if val, ok := s.(*authx.DynamicAuthStrategy); ok {
|
||||
if err := val.Dynamic.Fetch(false); err != nil {
|
||||
return err
|
||||
for _, ss := range f.domains {
|
||||
for _, s := range ss {
|
||||
if val, ok := s.(*authx.DynamicAuthStrategy); ok {
|
||||
if err := val.Dynamic.Fetch(false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, s := range f.compiled {
|
||||
if val, ok := s.(*authx.DynamicAuthStrategy); ok {
|
||||
if err := val.Dynamic.Fetch(false); err != nil {
|
||||
return err
|
||||
for _, ss := range f.compiled {
|
||||
for _, s := range ss {
|
||||
if val, ok := s.(*authx.DynamicAuthStrategy); ok {
|
||||
if err := val.Dynamic.Fetch(false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@ var (
|
||||
type AuthProvider interface {
|
||||
// LookupAddr looks up a given domain/address and returns appropriate auth strategy
|
||||
// for it (accepted inputs are scanme.sh or scanme.sh:443)
|
||||
LookupAddr(string) authx.AuthStrategy
|
||||
LookupAddr(string) []authx.AuthStrategy
|
||||
// LookupURL looks up a given URL and returns appropriate auth strategy
|
||||
// it accepts a valid url struct and returns the auth strategy
|
||||
LookupURL(*url.URL) authx.AuthStrategy
|
||||
LookupURL(*url.URL) []authx.AuthStrategy
|
||||
// LookupURLX looks up a given URL and returns appropriate auth strategy
|
||||
// it accepts pd url struct (i.e urlutil.URL) and returns the auth strategy
|
||||
LookupURLX(*urlutil.URL) authx.AuthStrategy
|
||||
LookupURLX(*urlutil.URL) []authx.AuthStrategy
|
||||
// GetTemplatePaths returns the template path for the auth provider
|
||||
// that will be used for dynamic secret fetching
|
||||
GetTemplatePaths() []string
|
||||
|
||||
@@ -19,7 +19,7 @@ func NewMultiAuthProvider(providers ...AuthProvider) AuthProvider {
|
||||
return &MultiAuthProvider{Providers: providers}
|
||||
}
|
||||
|
||||
func (m *MultiAuthProvider) LookupAddr(host string) authx.AuthStrategy {
|
||||
func (m *MultiAuthProvider) LookupAddr(host string) []authx.AuthStrategy {
|
||||
for _, provider := range m.Providers {
|
||||
strategy := provider.LookupAddr(host)
|
||||
if strategy != nil {
|
||||
@@ -29,7 +29,7 @@ func (m *MultiAuthProvider) LookupAddr(host string) authx.AuthStrategy {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MultiAuthProvider) LookupURL(u *url.URL) authx.AuthStrategy {
|
||||
func (m *MultiAuthProvider) LookupURL(u *url.URL) []authx.AuthStrategy {
|
||||
for _, provider := range m.Providers {
|
||||
strategy := provider.LookupURL(u)
|
||||
if strategy != nil {
|
||||
@@ -39,7 +39,7 @@ func (m *MultiAuthProvider) LookupURL(u *url.URL) authx.AuthStrategy {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MultiAuthProvider) LookupURLX(u *urlutil.URL) authx.AuthStrategy {
|
||||
func (m *MultiAuthProvider) LookupURLX(u *urlutil.URL) []authx.AuthStrategy {
|
||||
for _, provider := range m.Providers {
|
||||
strategy := provider.LookupURLX(u)
|
||||
if strategy != nil {
|
||||
|
||||
@@ -31,7 +31,7 @@ const (
|
||||
CLIConfigFileName = "config.yaml"
|
||||
ReportingConfigFilename = "reporting-config.yaml"
|
||||
// Version is the current version of nuclei
|
||||
Version = `v3.3.0`
|
||||
Version = `v3.3.1`
|
||||
// Directory Names of custom templates
|
||||
CustomS3TemplatesDirName = "s3"
|
||||
CustomGitHubTemplatesDirName = "github"
|
||||
|
||||
+3
-3
@@ -83,8 +83,8 @@ func (bk *customTemplateGitLabRepo) Download(_ context.Context) {
|
||||
|
||||
// Get the directory listing for the files in the project
|
||||
tree, _, err := bk.gitLabClient.Repositories.ListTree(projectID, &gitlab.ListTreeOptions{
|
||||
Ref: gitlab.String(project.DefaultBranch),
|
||||
Recursive: gitlab.Bool(true),
|
||||
Ref: gitlab.Ptr(project.DefaultBranch),
|
||||
Recursive: gitlab.Ptr(true),
|
||||
})
|
||||
if err != nil {
|
||||
gologger.Error().Msgf("error retrieving files from GitLab project: %s (%d) %s", project.Name, projectID, err)
|
||||
@@ -95,7 +95,7 @@ func (bk *customTemplateGitLabRepo) Download(_ context.Context) {
|
||||
// If the object is not a file or file extension is not .yaml, skip it
|
||||
if file.Type == "blob" && filepath.Ext(file.Path) == ".yaml" {
|
||||
gf := &gitlab.GetFileOptions{
|
||||
Ref: gitlab.String(project.DefaultBranch),
|
||||
Ref: gitlab.Ptr(project.DefaultBranch),
|
||||
}
|
||||
f, _, err := bk.gitLabClient.RepositoryFiles.GetFile(projectID, file.Path, gf)
|
||||
if err != nil {
|
||||
|
||||
+12
-1
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
|
||||
"github.com/projectdiscovery/retryablehttp-go"
|
||||
errorutil "github.com/projectdiscovery/utils/errors"
|
||||
mapsutil "github.com/projectdiscovery/utils/maps"
|
||||
sliceutil "github.com/projectdiscovery/utils/slice"
|
||||
urlutil "github.com/projectdiscovery/utils/url"
|
||||
)
|
||||
@@ -165,6 +166,11 @@ mainLoop:
|
||||
func (rule *Rule) evaluateVarsWithInteractsh(data map[string]interface{}, interactshUrls []string) (map[string]interface{}, []string) {
|
||||
// Check if Interactsh options are configured
|
||||
if rule.options.Interactsh != nil {
|
||||
interactshUrlsMap := make(map[string]struct{})
|
||||
for _, url := range interactshUrls {
|
||||
interactshUrlsMap[url] = struct{}{}
|
||||
}
|
||||
interactshUrls = mapsutil.GetKeys(interactshUrlsMap)
|
||||
// Iterate through the data to replace and evaluate variables with Interactsh URLs
|
||||
for k, v := range data {
|
||||
value := fmt.Sprint(v)
|
||||
@@ -175,7 +181,12 @@ func (rule *Rule) evaluateVarsWithInteractsh(data map[string]interface{}, intera
|
||||
}
|
||||
// Append new OAST URLs if any
|
||||
if len(oastUrls) > 0 {
|
||||
interactshUrls = append(interactshUrls, oastUrls...)
|
||||
for _, url := range oastUrls {
|
||||
if _, ok := interactshUrlsMap[url]; !ok {
|
||||
interactshUrlsMap[url] = struct{}{}
|
||||
interactshUrls = append(interactshUrls, url)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Evaluate the replaced data
|
||||
evaluatedData, err := expressions.Evaluate(got, data)
|
||||
|
||||
@@ -2,12 +2,13 @@ package formats
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/input/types"
|
||||
fileutil "github.com/projectdiscovery/utils/file"
|
||||
"gopkg.in/yaml.v3"
|
||||
mapsutil "github.com/projectdiscovery/utils/maps"
|
||||
)
|
||||
|
||||
// ParseReqRespCallback is a callback function for discovered raw requests
|
||||
@@ -41,8 +42,7 @@ type Format interface {
|
||||
}
|
||||
|
||||
var (
|
||||
DefaultVarDumpFileName = "required_openapi_params.yaml"
|
||||
ErrNoVarsDumpFile = errors.New("no required params file found")
|
||||
ErrNoVarsDumpFile = errors.New("no required params file found")
|
||||
)
|
||||
|
||||
// == OpenAPIParamsCfgFile ==
|
||||
@@ -52,52 +52,51 @@ var (
|
||||
|
||||
// OpenAPIParamsCfgFile is the structure of the required vars dump file
|
||||
type OpenAPIParamsCfgFile struct {
|
||||
FileName string `yaml:"-"`
|
||||
Var []string `yaml:"var"`
|
||||
OptionalVars []string `yaml:"-"` // this will be written to the file as comments
|
||||
}
|
||||
|
||||
// ReadOpenAPIVarDumpFile reads the required vars dump file
|
||||
func ReadOpenAPIVarDumpFile() (*OpenAPIParamsCfgFile, error) {
|
||||
var vars OpenAPIParamsCfgFile
|
||||
if !fileutil.FileExists(DefaultVarDumpFileName) {
|
||||
return nil, ErrNoVarsDumpFile
|
||||
}
|
||||
bin, err := os.ReadFile(DefaultVarDumpFileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = yaml.Unmarshal(bin, &vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filtered := []string{}
|
||||
for _, v := range vars.Var {
|
||||
v = strings.TrimSpace(v)
|
||||
if !strings.HasSuffix(v, "=") {
|
||||
filtered = append(filtered, v)
|
||||
// UpdateMissingVarsFile writes the required vars dump file
|
||||
func UpdateMissingVarsFile(vars *OpenAPIParamsCfgFile) error {
|
||||
existing := make(map[string]string)
|
||||
if fileutil.FileExists(vars.FileName) {
|
||||
bin, err := os.ReadFile(vars.FileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range strings.Split(string(bin), "\n") {
|
||||
v = strings.TrimSpace(v)
|
||||
parts := strings.Split(v, "=")
|
||||
if len(parts) == 1 {
|
||||
existing[parts[0]] = ""
|
||||
} else if len(parts) == 2 {
|
||||
existing[parts[0]] = parts[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
vars.Var = filtered
|
||||
return &vars, nil
|
||||
}
|
||||
|
||||
// WriteOpenAPIVarDumpFile writes the required vars dump file
|
||||
func WriteOpenAPIVarDumpFile(vars *OpenAPIParamsCfgFile) error {
|
||||
f, err := os.OpenFile(DefaultVarDumpFileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
// add missing vars to existing
|
||||
for _, v := range vars.Var {
|
||||
if _, ok := existing[v]; !ok {
|
||||
existing[v] = ""
|
||||
}
|
||||
}
|
||||
// add optional vars to existing
|
||||
for _, v := range vars.OptionalVars {
|
||||
if _, ok := existing[v]; !ok {
|
||||
existing[v] = ""
|
||||
}
|
||||
}
|
||||
f, err := os.OpenFile(vars.FileName, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
bin, err := yaml.Marshal(vars)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = f.Write(bin)
|
||||
if len(vars.OptionalVars) > 0 {
|
||||
_, _ = f.WriteString("\n # Optional parameters\n")
|
||||
for _, v := range vars.OptionalVars {
|
||||
_, _ = f.WriteString(" # - " + v + "=\n")
|
||||
for _, v := range mapsutil.GetSortedKeys(existing) {
|
||||
if strings.TrimSpace(v) == "" {
|
||||
continue
|
||||
}
|
||||
f.WriteString(fmt.Sprintf("%s=%s\n", v, existing[v]))
|
||||
}
|
||||
return f.Sync()
|
||||
return nil
|
||||
}
|
||||
@@ -18,7 +18,7 @@ func getSchemaExample(schema *openapi3.Schema) (interface{}, bool) {
|
||||
return schema.Default, true
|
||||
}
|
||||
|
||||
if schema.Enum != nil && len(schema.Enum) > 0 {
|
||||
if len(schema.Enum) > 0 {
|
||||
return schema.Enum[0], true
|
||||
}
|
||||
return nil, false
|
||||
@@ -175,9 +175,9 @@ func openAPIExample(schema *openapi3.Schema, cache map[*openapi3.Schema]*cachedS
|
||||
}
|
||||
|
||||
switch {
|
||||
case schema.Type == "boolean":
|
||||
case schema.Type.Is("boolean"):
|
||||
return true, nil
|
||||
case schema.Type == "number", schema.Type == "integer":
|
||||
case schema.Type.Is("number"), schema.Type.Is("integer"):
|
||||
value := 0.0
|
||||
|
||||
if schema.Min != nil && *schema.Min > value {
|
||||
@@ -208,11 +208,11 @@ func openAPIExample(schema *openapi3.Schema, cache map[*openapi3.Schema]*cachedS
|
||||
value += float64(int(*schema.MultipleOf) - (int(value) % int(*schema.MultipleOf)))
|
||||
}
|
||||
|
||||
if schema.Type == "integer" {
|
||||
if schema.Type.Is("integer") {
|
||||
return int(value), nil
|
||||
}
|
||||
return value, nil
|
||||
case schema.Type == "string":
|
||||
case schema.Type.Is("string"):
|
||||
if ex := stringFormatExample(schema.Format); ex != "" {
|
||||
return ex, nil
|
||||
}
|
||||
@@ -226,7 +226,7 @@ func openAPIExample(schema *openapi3.Schema, cache map[*openapi3.Schema]*cachedS
|
||||
example = example[:*schema.MaxLength]
|
||||
}
|
||||
return example, nil
|
||||
case schema.Type == "array", schema.Items != nil:
|
||||
case schema.Type.Is("array"), schema.Items != nil:
|
||||
example := []interface{}{}
|
||||
|
||||
if schema.Items != nil && schema.Items.Value != nil {
|
||||
@@ -242,7 +242,7 @@ func openAPIExample(schema *openapi3.Schema, cache map[*openapi3.Schema]*cachedS
|
||||
}
|
||||
}
|
||||
return example, nil
|
||||
case schema.Type == "object", len(schema.Properties) > 0:
|
||||
case schema.Type.Is("object"), len(schema.Properties) > 0:
|
||||
example := map[string]interface{}{}
|
||||
|
||||
for k, v := range schema.Properties {
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/input/formats"
|
||||
httpTypes "github.com/projectdiscovery/nuclei/v3/pkg/input/types"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/types"
|
||||
"github.com/projectdiscovery/utils/errkit"
|
||||
errorutil "github.com/projectdiscovery/utils/errors"
|
||||
"github.com/projectdiscovery/utils/generic"
|
||||
mapsutil "github.com/projectdiscovery/utils/maps"
|
||||
@@ -35,7 +36,6 @@ func GenerateRequestsFromSchema(schema *openapi3.T, opts formats.InputFormatOpti
|
||||
if len(schema.Servers) == 0 {
|
||||
return errors.New("no servers found in openapi schema")
|
||||
}
|
||||
|
||||
// new set of globalParams obtained from security schemes
|
||||
globalParams := openapi3.NewParameters()
|
||||
|
||||
@@ -47,22 +47,6 @@ func GenerateRequestsFromSchema(schema *openapi3.T, opts formats.InputFormatOpti
|
||||
globalParams = append(globalParams, params...)
|
||||
}
|
||||
|
||||
// validate global param requirements
|
||||
for _, param := range globalParams {
|
||||
if val, ok := opts.Variables[param.Value.Name]; ok {
|
||||
param.Value.Example = val
|
||||
} else {
|
||||
// if missing check for validation
|
||||
if opts.SkipFormatValidation {
|
||||
gologger.Verbose().Msgf("openapi: skipping all requests due to missing global auth parameter: %s\n", param.Value.Name)
|
||||
return nil
|
||||
} else {
|
||||
// fatal error
|
||||
gologger.Fatal().Msgf("openapi: missing global auth parameter: %s\n", param.Value.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
missingVarMap := make(map[string]struct{})
|
||||
optionalVarMap := make(map[string]struct{})
|
||||
missingParamValueCallback := func(param *openapi3.Parameter, opts *generateReqOptions) {
|
||||
@@ -73,18 +57,45 @@ func GenerateRequestsFromSchema(schema *openapi3.T, opts formats.InputFormatOpti
|
||||
missingVarMap[param.Name] = struct{}{}
|
||||
}
|
||||
|
||||
// validate global param requirements
|
||||
for _, param := range globalParams {
|
||||
if val, ok := opts.Variables[param.Value.Name]; ok && val != "" {
|
||||
param.Value.Example = val
|
||||
delete(missingVarMap, param.Value.Name)
|
||||
} else {
|
||||
// if missing check for validation
|
||||
if opts.SkipFormatValidation {
|
||||
gologger.Verbose().Msgf("openapi: skipping all requests due to missing global auth parameter: %s\n", param.Value.Name)
|
||||
return nil
|
||||
} else {
|
||||
// put them in missingVarMap
|
||||
missingVarMap[param.Value.Name] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, serverURL := range schema.Servers {
|
||||
pathURL := serverURL.URL
|
||||
// Split the server URL into baseURL and serverPath
|
||||
u, err := url.Parse(pathURL)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not parse server url")
|
||||
}
|
||||
baseURL := fmt.Sprintf("%s://%s", u.Scheme, u.Host)
|
||||
serverPath := u.Path
|
||||
|
||||
for path, v := range schema.Paths.Map() {
|
||||
// a path item can have parameters
|
||||
ops := v.Operations()
|
||||
requestPath := path
|
||||
if serverPath != "" {
|
||||
requestPath = serverPath + path
|
||||
}
|
||||
for method, ov := range ops {
|
||||
if err := generateRequestsFromOp(&generateReqOptions{
|
||||
requiredOnly: opts.RequiredOnly,
|
||||
method: method,
|
||||
pathURL: pathURL,
|
||||
pathURL: baseURL,
|
||||
requestPath: requestPath,
|
||||
op: ov,
|
||||
schema: schema,
|
||||
@@ -99,18 +110,20 @@ func GenerateRequestsFromSchema(schema *openapi3.T, opts formats.InputFormatOpti
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(missingVarMap) > 0 && !opts.SkipFormatValidation {
|
||||
gologger.Error().Msgf("openapi: Found %d missing parameters, use -skip-format-validation flag to skip requests or update missing parameters generated in %s file,you can also specify these vars using -var flag in (key=value) format\n", len(missingVarMap), formats.DefaultVarDumpFileName)
|
||||
filename := fileNameFromTitle(schema.Info.Title)
|
||||
gologger.Error().Msgf("openapi: Found %d missing/empty parameters, use -skip-format-validation flag to skip requests or update missing parameters generated in %s file, add pass it to nuclei using '-var %s'\n", len(missingVarMap), filename, filename)
|
||||
gologger.Verbose().Msgf("openapi: missing params: %+v", mapsutil.GetSortedKeys(missingVarMap))
|
||||
if config.CurrentAppMode == config.AppModeCLI {
|
||||
// generate var dump file
|
||||
vars := &formats.OpenAPIParamsCfgFile{}
|
||||
vars := &formats.OpenAPIParamsCfgFile{
|
||||
FileName: filename,
|
||||
}
|
||||
for k := range missingVarMap {
|
||||
vars.Var = append(vars.Var, k+"=")
|
||||
vars.Var = append(vars.Var, k)
|
||||
}
|
||||
vars.OptionalVars = mapsutil.GetSortedKeys(optionalVarMap)
|
||||
if err := formats.WriteOpenAPIVarDumpFile(vars); err != nil {
|
||||
if err := formats.UpdateMissingVarsFile(vars); err != nil {
|
||||
gologger.Error().Msgf("openapi: could not write params file: %s\n", err)
|
||||
}
|
||||
// exit with status code 1
|
||||
@@ -193,7 +206,7 @@ func generateRequestsFromOp(opts *generateReqOptions) error {
|
||||
paramValue = value.Schema.Value.Default
|
||||
} else if value.Schema.Value.Example != nil {
|
||||
paramValue = value.Schema.Value.Example
|
||||
} else if value.Schema.Value.Enum != nil && len(value.Schema.Value.Enum) > 0 {
|
||||
} else if len(value.Schema.Value.Enum) > 0 {
|
||||
paramValue = value.Schema.Value.Enum[0]
|
||||
} else {
|
||||
if !opts.opts.SkipFormatValidation {
|
||||
@@ -257,6 +270,10 @@ func generateRequestsFromOp(opts *generateReqOptions) error {
|
||||
for content, value := range opts.op.RequestBody.Value.Content {
|
||||
cloned := req.Clone(req.Context())
|
||||
|
||||
if value.Schema == nil {
|
||||
// skip if schema is not present this is most likely a invalid content-type not recognized by openapi
|
||||
continue
|
||||
}
|
||||
example, err := generateExampleFromSchema(value.Schema.Value)
|
||||
if err != nil {
|
||||
continue
|
||||
@@ -378,31 +395,25 @@ func GetGlobalParamsForSecurityRequirement(schema *openapi3.T, requirement *open
|
||||
if len(schema.Components.SecuritySchemes) == 0 {
|
||||
return nil, errorutil.NewWithTag("openapi", "security requirements (%+v) without any security schemes found in openapi file", schema.Security)
|
||||
}
|
||||
found := false
|
||||
missing := []string{}
|
||||
// this api is protected for each security scheme pull its corresponding scheme
|
||||
schemaLabel:
|
||||
for _, security := range *requirement {
|
||||
for name := range security {
|
||||
if scheme, ok := schema.Components.SecuritySchemes[name]; ok {
|
||||
found = true
|
||||
param, err := GenerateParameterFromSecurityScheme(scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
}
|
||||
globalParams = append(globalParams, &openapi3.ParameterRef{Value: param})
|
||||
continue schemaLabel
|
||||
} else {
|
||||
missing = append(missing, name)
|
||||
}
|
||||
}
|
||||
if !found && len(security) > 1 {
|
||||
// if this is case then both security schemes are required
|
||||
return nil, errorutil.NewWithTag("openapi", "security requirement (%+v) not found in openapi file", security)
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return nil, errorutil.NewWithTag("openapi", "security requirement (%+v) not found in openapi file", requirement)
|
||||
if len(missing) > 0 {
|
||||
return nil, errkit.New("missing schema of following security requirements (%+v)", missing)
|
||||
}
|
||||
|
||||
return globalParams, nil
|
||||
}
|
||||
|
||||
@@ -463,3 +474,15 @@ func GenerateParameterFromSecurityScheme(scheme *openapi3.SecuritySchemeRef) (*o
|
||||
}
|
||||
return nil, errorutil.NewWithTag("openapi", "unsupported security scheme type (%s) found in openapi file", scheme.Value.Type)
|
||||
}
|
||||
|
||||
func fileNameFromTitle(title string) string {
|
||||
parts := strings.Fields(title)
|
||||
if len(parts) == 0 {
|
||||
return "openapi_vars.txt"
|
||||
}
|
||||
if len(parts) > 2 {
|
||||
parts = parts[:2]
|
||||
}
|
||||
fileName := strings.ToLower(strings.Join(parts, "_"))
|
||||
return fileName + "_vars.txt"
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package swagger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
@@ -10,7 +11,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/input/formats"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/input/formats/openapi"
|
||||
"gopkg.in/yaml.v2"
|
||||
"github.com/invopop/yaml"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi2conv"
|
||||
)
|
||||
@@ -49,7 +50,11 @@ func (j *SwaggerFormat) Parse(input string, resultsCb formats.ParseReqRespCallba
|
||||
ext := path.Ext(input)
|
||||
|
||||
if ext == ".yaml" || ext == ".yml" {
|
||||
err = yaml.NewDecoder(file).Decode(schemav2)
|
||||
data, err_data := io.ReadAll(file)
|
||||
if err_data != nil {
|
||||
return errors.Wrap(err, "could not read data file")
|
||||
}
|
||||
err = yaml.Unmarshal(data, schemav2)
|
||||
} else {
|
||||
err = json.NewDecoder(file).Decode(schemav2)
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ func TestSwaggerAPIParser(t *testing.T) {
|
||||
}
|
||||
|
||||
expectedURLs := []string{
|
||||
"https://localhost/users",
|
||||
"https://localhost/users/1?test=asc",
|
||||
"https://localhost/v1/users",
|
||||
"https://localhost/v1/users/1?test=asc",
|
||||
}
|
||||
require.ElementsMatch(t, gotMethodsToURLs, expectedURLs, "could not get swagger urls")
|
||||
}
|
||||
@@ -1,17 +1,14 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/projectdiscovery/gologger"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/input/formats"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/input/provider/http"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/input/provider/list"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/input/types"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
|
||||
configTypes "github.com/projectdiscovery/nuclei/v3/pkg/types"
|
||||
errorutil "github.com/projectdiscovery/utils/errors"
|
||||
stringsutil "github.com/projectdiscovery/utils/strings"
|
||||
@@ -82,23 +79,6 @@ type InputOptions struct {
|
||||
// NewInputProvider creates a new input provider based on the options
|
||||
// and returns it
|
||||
func NewInputProvider(opts InputOptions) (InputProvider, error) {
|
||||
// optionally load generated vars values if available
|
||||
val, err := formats.ReadOpenAPIVarDumpFile()
|
||||
if err != nil && !errors.Is(err, formats.ErrNoVarsDumpFile) {
|
||||
// log error and continue
|
||||
gologger.Error().Msgf("Could not read vars dump file: %s\n", err)
|
||||
}
|
||||
extraVars := make(map[string]interface{})
|
||||
if val != nil {
|
||||
for _, v := range val.Var {
|
||||
v = strings.TrimSpace(v)
|
||||
// split into key value
|
||||
parts := strings.SplitN(v, "=", 2)
|
||||
if len(parts) == 2 {
|
||||
extraVars[parts[0]] = parts[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if input provider is supported
|
||||
if strings.EqualFold(opts.Options.InputFileMode, "list") {
|
||||
@@ -113,7 +93,7 @@ func NewInputProvider(opts InputOptions) (InputProvider, error) {
|
||||
InputFile: opts.Options.TargetsFilePath,
|
||||
InputMode: opts.Options.InputFileMode,
|
||||
Options: formats.InputFormatOptions{
|
||||
Variables: generators.MergeMaps(extraVars, opts.Options.Vars.AsMap()),
|
||||
Variables: opts.Options.Vars.AsMap(),
|
||||
SkipFormatValidation: opts.Options.SkipFormatValidation,
|
||||
RequiredOnly: opts.Options.FormatUseRequiredOnly,
|
||||
},
|
||||
|
||||
@@ -249,7 +249,7 @@ func identifyGenDecl(pkg *ast.Package, decl *ast.GenDecl, data *TemplateData) {
|
||||
if !spec.Names[0].IsExported() {
|
||||
continue
|
||||
}
|
||||
if spec.Values == nil || len(spec.Values) == 0 {
|
||||
if len(spec.Values) == 0 {
|
||||
continue
|
||||
}
|
||||
data.PackageVars[spec.Names[0].Name] = spec.Names[0].Name
|
||||
|
||||
@@ -489,7 +489,7 @@ func (p *EntityParser) extractVarsNConstants() {
|
||||
if !spec.Names[0].IsExported() {
|
||||
continue
|
||||
}
|
||||
if spec.Values == nil || len(spec.Values) == 0 {
|
||||
if len(spec.Values) == 0 {
|
||||
continue
|
||||
}
|
||||
// get comments or description
|
||||
|
||||
@@ -60,12 +60,16 @@ func (j *NucleiJS) HandleError(err error, msg ...string) {
|
||||
if len(msg) == 0 {
|
||||
j.ThrowError(err)
|
||||
}
|
||||
j.Throw(fmt.Sprintf("%s: %s", strings.Join(msg, ":"), err.Error()))
|
||||
j.Throw("%s: %s", strings.Join(msg, ":"), err.Error())
|
||||
}
|
||||
|
||||
// Throw throws an error in goja runtime
|
||||
func (j *NucleiJS) Throw(format string, args ...interface{}) {
|
||||
panic(j.runtime().ToValue(fmt.Sprintf(format, args...)))
|
||||
if len(args) > 0 {
|
||||
panic(j.runtime().ToValue(fmt.Sprintf(format, args...)))
|
||||
}
|
||||
|
||||
panic(j.runtime().ToValue(format))
|
||||
}
|
||||
|
||||
// GetArg returns argument at index from goja runtime if not found throws error
|
||||
@@ -95,7 +99,7 @@ func (j *NucleiJS) GetArgSafe(args []goja.Value, index int, defaultValue any) an
|
||||
// Require throws an error if expression is false
|
||||
func (j *NucleiJS) Require(expr bool, msg string) {
|
||||
if !expr {
|
||||
j.Throw(msg)
|
||||
j.Throw("%s", msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-2
@@ -71,6 +71,7 @@ type StandardWriter struct {
|
||||
omitTemplate bool
|
||||
DisableStdout bool
|
||||
AddNewLinesOutputFile bool // by default this is only done for stdout
|
||||
KeysToRedact []string
|
||||
}
|
||||
|
||||
var decolorizerRegex = regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`)
|
||||
@@ -253,6 +254,7 @@ func NewStandardWriter(options *types.Options) (*StandardWriter, error) {
|
||||
storeResponse: options.StoreResponse,
|
||||
storeResponseDir: options.StoreResponseDir,
|
||||
omitTemplate: options.OmitTemplate,
|
||||
KeysToRedact: options.Redact,
|
||||
}
|
||||
return writer, nil
|
||||
}
|
||||
@@ -264,6 +266,13 @@ func (w *StandardWriter) Write(event *ResultEvent) error {
|
||||
event.Template, event.TemplateURL = utils.TemplatePathURL(types.ToString(event.TemplatePath), types.ToString(event.TemplateID))
|
||||
}
|
||||
|
||||
if len(w.KeysToRedact) > 0 {
|
||||
event.Request = redactKeys(event.Request, w.KeysToRedact)
|
||||
event.Response = redactKeys(event.Response, w.KeysToRedact)
|
||||
event.CURLCommand = redactKeys(event.CURLCommand, w.KeysToRedact)
|
||||
event.Matched = redactKeys(event.Matched, w.KeysToRedact)
|
||||
}
|
||||
|
||||
event.Timestamp = time.Now()
|
||||
|
||||
var data []byte
|
||||
@@ -302,6 +311,14 @@ func (w *StandardWriter) Write(event *ResultEvent) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func redactKeys(data string, keysToRedact []string) string {
|
||||
for _, key := range keysToRedact {
|
||||
keyPattern := regexp.MustCompile(fmt.Sprintf(`(?i)(%s\s*[:=]\s*["']?)[^"'\r\n&]+(["'\r\n]?)`, regexp.QuoteMeta(key)))
|
||||
data = keyPattern.ReplaceAllString(data, `$1***$2`)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// JSONLogRequest is a trace/error log request written to file
|
||||
type JSONLogRequest struct {
|
||||
Template string `json:"template"`
|
||||
@@ -508,12 +525,12 @@ func tryParseCause(err error) error {
|
||||
if strings.HasPrefix(msg, "ReadStatusLine:") {
|
||||
// last index is actual error (from rawhttp)
|
||||
parts := strings.Split(msg, ":")
|
||||
return errkit.New(strings.TrimSpace(parts[len(parts)-1]))
|
||||
return errkit.New("%s", strings.TrimSpace(parts[len(parts)-1]))
|
||||
}
|
||||
if strings.Contains(msg, "read ") {
|
||||
// same here
|
||||
parts := strings.Split(msg, ":")
|
||||
return errkit.New(strings.TrimSpace(parts[len(parts)-1]))
|
||||
return errkit.New("%s", strings.TrimSpace(parts[len(parts)-1]))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -17,7 +17,7 @@ func hash(v interface{}) (string, error) {
|
||||
|
||||
sh := sha256.New()
|
||||
|
||||
if _, err = io.WriteString(sh, string(data)); err != nil {
|
||||
if _, err = sh.Write(data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(sh.Sum(nil)), nil
|
||||
|
||||
@@ -44,7 +44,8 @@ func toHighLightedHexDump(hexDump, snippetToHighlight string) (HighlightableHexD
|
||||
hexDumpRowValues := hexDumpParsePattern.FindAllStringSubmatch(hexDump, -1)
|
||||
if hexDumpRowValues == nil || len(hexDumpRowValues) != strings.Count(hexDump, "\n") {
|
||||
message := "could not parse hexdump"
|
||||
gologger.Warning().Msgf(message)
|
||||
gologger.Warning().Msg(message)
|
||||
|
||||
return HighlightableHexDump{}, errors.New(message)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"sync"
|
||||
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/pkg/errors"
|
||||
@@ -19,9 +20,17 @@ import (
|
||||
|
||||
// Dialer is a shared fastdialer instance for host DNS resolution
|
||||
var (
|
||||
Dialer *fastdialer.Dialer
|
||||
muDialer sync.RWMutex
|
||||
Dialer *fastdialer.Dialer
|
||||
)
|
||||
|
||||
func GetDialer() *fastdialer.Dialer {
|
||||
muDialer.RLock()
|
||||
defer muDialer.RUnlock()
|
||||
|
||||
return Dialer
|
||||
}
|
||||
|
||||
func ShouldInit() bool {
|
||||
return Dialer == nil
|
||||
}
|
||||
@@ -210,10 +219,12 @@ func interfaceAddresses(interfaceName string) ([]net.Addr, error) {
|
||||
|
||||
// Close closes the global shared fastdialer
|
||||
func Close() {
|
||||
muDialer.Lock()
|
||||
defer muDialer.Unlock()
|
||||
|
||||
if Dialer != nil {
|
||||
Dialer.Close()
|
||||
Dialer = nil
|
||||
}
|
||||
Dialer = nil
|
||||
StopActiveMemGuardian()
|
||||
}
|
||||
@@ -142,7 +142,7 @@ func (request *Request) execute(input *contextargs.Context, domain string, metad
|
||||
if request.options.Options.Debug || request.options.Options.DebugRequests || request.options.Options.StoreResponse {
|
||||
msg := fmt.Sprintf("[%s] Dumped DNS request for %s", request.options.TemplateID, question)
|
||||
if request.options.Options.Debug || request.options.Options.DebugRequests {
|
||||
gologger.Info().Str("domain", domain).Msgf(msg)
|
||||
gologger.Info().Str("domain", domain).Msg(msg)
|
||||
gologger.Print().Msgf("%s", requestString)
|
||||
}
|
||||
if request.options.Options.StoreResponse {
|
||||
|
||||
@@ -174,7 +174,7 @@ func (request *Request) executeRequestWithPayloads(input *contextargs.Context, p
|
||||
reqBuilder.WriteString("\t" + actStepStr + "\n")
|
||||
}
|
||||
}
|
||||
gologger.Debug().Msgf(reqBuilder.String())
|
||||
gologger.Debug().Msg(reqBuilder.String())
|
||||
}
|
||||
|
||||
var responseBody string
|
||||
|
||||
@@ -90,9 +90,9 @@ func (g *generatedRequest) ApplyAuth(provider authprovider.AuthProvider) {
|
||||
return
|
||||
}
|
||||
if g.request != nil {
|
||||
auth := provider.LookupURLX(g.request.URL)
|
||||
if auth != nil {
|
||||
auth.ApplyOnRR(g.request)
|
||||
authStrategies := provider.LookupURLX(g.request.URL)
|
||||
for _, strategy := range authStrategies {
|
||||
strategy.ApplyOnRR(g.request)
|
||||
}
|
||||
}
|
||||
if g.rawRequest != nil {
|
||||
@@ -101,11 +101,11 @@ func (g *generatedRequest) ApplyAuth(provider authprovider.AuthProvider) {
|
||||
gologger.Warning().Msgf("[authprovider] Could not parse URL %s: %s\n", g.rawRequest.FullURL, err)
|
||||
return
|
||||
}
|
||||
auth := provider.LookupURLX(parsed)
|
||||
if auth != nil {
|
||||
// here we need to apply it custom because we don't have a standard/official
|
||||
// rawhttp request format ( which we probably should have )
|
||||
g.rawRequest.ApplyAuthStrategy(auth)
|
||||
authStrategies := provider.LookupURLX(parsed)
|
||||
// here we need to apply it custom because we don't have a standard/official
|
||||
// rawhttp request format ( which we probably should have )
|
||||
for _, strategy := range authStrategies {
|
||||
g.rawRequest.ApplyAuthStrategy(strategy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +147,10 @@ type Request struct {
|
||||
// - "AWS"
|
||||
Signature SignatureTypeHolder `yaml:"signature,omitempty" json:"signature,omitempty" jsonschema:"title=signature is the http request signature method,description=Signature is the HTTP Request signature Method,enum=AWS"`
|
||||
|
||||
// description: |
|
||||
// SkipSecretFile skips the authentication or authorization configured in the secret file.
|
||||
SkipSecretFile bool `yaml:"skip-secret-file,omitempty" json:"skip-secret-file,omitempty" jsonschema:"title=bypass secret file,description=Skips the authentication or authorization configured in the secret file"`
|
||||
|
||||
// description: |
|
||||
// CookieReuse is an optional setting that enables cookie reuse for
|
||||
// all requests defined in raw section.
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
|
||||
var (
|
||||
rawHttpClient *rawhttp.Client
|
||||
rawHttpClientOnce sync.Once
|
||||
forceMaxRedirects int
|
||||
normalClient *retryablehttp.Client
|
||||
clientPool *mapsutil.SyncLockMap[string, *retryablehttp.Client]
|
||||
@@ -102,6 +103,22 @@ type Configuration struct {
|
||||
ResponseHeaderTimeout time.Duration
|
||||
}
|
||||
|
||||
func (c *Configuration) Clone() *Configuration {
|
||||
clone := *c
|
||||
if c.Connection != nil {
|
||||
cloneConnection := &ConnectionConfiguration{
|
||||
DisableKeepAlive: c.Connection.DisableKeepAlive,
|
||||
}
|
||||
if c.Connection.HasCookieJar() {
|
||||
cookiejar := *c.Connection.GetCookieJar()
|
||||
cloneConnection.SetCookieJar(&cookiejar)
|
||||
}
|
||||
clone.Connection = cloneConnection
|
||||
}
|
||||
|
||||
return &clone
|
||||
}
|
||||
|
||||
// Hash returns the hash of the configuration to allow client pooling
|
||||
func (c *Configuration) Hash() string {
|
||||
builder := &strings.Builder{}
|
||||
@@ -131,7 +148,7 @@ func (c *Configuration) HasStandardOptions() bool {
|
||||
|
||||
// GetRawHTTP returns the rawhttp request client
|
||||
func GetRawHTTP(options *protocols.ExecutorOptions) *rawhttp.Client {
|
||||
if rawHttpClient == nil {
|
||||
rawHttpClientOnce.Do(func() {
|
||||
rawHttpOptions := rawhttp.DefaultOptions
|
||||
if types.ProxyURL != "" {
|
||||
rawHttpOptions.Proxy = types.ProxyURL
|
||||
@@ -142,7 +159,7 @@ func GetRawHTTP(options *protocols.ExecutorOptions) *rawhttp.Client {
|
||||
}
|
||||
rawHttpOptions.Timeout = options.Options.GetTimeouts().HttpTimeout
|
||||
rawHttpClient = rawhttp.NewClient(rawHttpOptions)
|
||||
}
|
||||
})
|
||||
return rawHttpClient
|
||||
}
|
||||
|
||||
@@ -233,7 +250,7 @@ func wrappedGet(options *types.Options, configuration *Configuration) (*retryabl
|
||||
|
||||
transport := &http.Transport{
|
||||
ForceAttemptHTTP2: options.ForceAttemptHTTP2,
|
||||
DialContext: protocolstate.Dialer.Dial,
|
||||
DialContext: protocolstate.GetDialer().Dial,
|
||||
DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
if options.TlsImpersonate {
|
||||
return protocolstate.Dialer.DialTLSWithConfigImpersonate(ctx, network, addr, tlsConfig, impersonate.Random, nil)
|
||||
@@ -241,7 +258,7 @@ func wrappedGet(options *types.Options, configuration *Configuration) (*retryabl
|
||||
if options.HasClientCertificates() || options.ForceAttemptHTTP2 {
|
||||
return protocolstate.Dialer.DialTLSWithConfig(ctx, network, addr, tlsConfig)
|
||||
}
|
||||
return protocolstate.Dialer.DialTLS(ctx, network, addr)
|
||||
return protocolstate.GetDialer().DialTLS(ctx, network, addr)
|
||||
},
|
||||
MaxIdleConns: maxIdleConns,
|
||||
MaxIdleConnsPerHost: maxIdleConnsPerHost,
|
||||
|
||||
@@ -689,7 +689,7 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ
|
||||
}
|
||||
|
||||
// === apply auth strategies ===
|
||||
if generatedRequest.request != nil {
|
||||
if generatedRequest.request != nil && !request.SkipSecretFile {
|
||||
generatedRequest.ApplyAuth(request.options.AuthProvider)
|
||||
}
|
||||
|
||||
@@ -770,7 +770,7 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ
|
||||
|
||||
// check for cookie related configuration
|
||||
if input.CookieJar != nil {
|
||||
connConfiguration := request.connConfiguration
|
||||
connConfiguration := request.connConfiguration.Clone()
|
||||
connConfiguration.Connection.SetCookieJar(input.CookieJar)
|
||||
modifiedConfig = connConfiguration
|
||||
}
|
||||
@@ -778,7 +778,8 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ
|
||||
updatedTimeout, ok := generatedRequest.request.Context().Value(httpclientpool.WithCustomTimeout{}).(httpclientpool.WithCustomTimeout)
|
||||
if ok {
|
||||
if modifiedConfig == nil {
|
||||
modifiedConfig = request.connConfiguration
|
||||
connConfiguration := request.connConfiguration.Clone()
|
||||
modifiedConfig = connConfiguration
|
||||
}
|
||||
modifiedConfig.ResponseHeaderTimeout = updatedTimeout.Timeout
|
||||
}
|
||||
@@ -941,7 +942,11 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ
|
||||
if input.MetaInput.CustomIP != "" {
|
||||
outputEvent["ip"] = input.MetaInput.CustomIP
|
||||
} else {
|
||||
outputEvent["ip"] = protocolstate.Dialer.GetDialedIP(hostname)
|
||||
dialer := protocolstate.GetDialer()
|
||||
if dialer != nil {
|
||||
outputEvent["ip"] = dialer.GetDialedIP(hostname)
|
||||
}
|
||||
|
||||
// try getting cname
|
||||
request.addCNameIfAvailable(hostname, outputEvent)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/output"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/interactsh"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/utils/vardump"
|
||||
protocolutils "github.com/projectdiscovery/nuclei/v3/pkg/protocols/utils"
|
||||
@@ -112,6 +113,7 @@ func (request *Request) executeFuzzingRule(input *contextargs.Context, previous
|
||||
// executeAllFuzzingRules executes all fuzzing rules defined in template for a given base request
|
||||
func (request *Request) executeAllFuzzingRules(input *contextargs.Context, values map[string]interface{}, baseRequest *retryablehttp.Request, callback protocols.OutputEventCallback) error {
|
||||
applicable := false
|
||||
values = generators.MergeMaps(request.filterDataMap(input), values)
|
||||
for _, rule := range request.Fuzzing {
|
||||
select {
|
||||
case <-input.Context().Done():
|
||||
@@ -234,7 +236,12 @@ func (request *Request) ShouldFuzzTarget(input *contextargs.Context) bool {
|
||||
}
|
||||
status := []bool{}
|
||||
for index, filter := range request.FuzzPreCondition {
|
||||
isMatch, _ := request.Match(request.filterDataMap(input), filter)
|
||||
dataMap := request.filterDataMap(input)
|
||||
// dump if svd is enabled
|
||||
if request.options.Options.ShowVarDump {
|
||||
gologger.Debug().Msgf("Fuzz Filter Variables: \n%s\n", vardump.DumpVariables(dataMap))
|
||||
}
|
||||
isMatch, _ := request.Match(dataMap, filter)
|
||||
status = append(status, isMatch)
|
||||
if request.options.Options.MatcherStatus {
|
||||
gologger.Debug().Msgf("[%s] [%s] Filter => %s : %v", input.MetaInput.Target(), request.options.TemplateID, operators.GetMatcherName(filter, index), isMatch)
|
||||
@@ -295,10 +302,5 @@ func (request *Request) filterDataMap(input *contextargs.Context) map[string]int
|
||||
// add default method value
|
||||
m["method"] = http.MethodGet
|
||||
}
|
||||
|
||||
// dump if svd is enabled
|
||||
if request.options.Options.ShowVarDump {
|
||||
gologger.Debug().Msgf("Fuzz Filter Variables: \n%s\n", vardump.DumpVariables(m))
|
||||
}
|
||||
return m
|
||||
}
|
||||
@@ -240,7 +240,7 @@ func (c *ReportingClient) Close() {
|
||||
if failed > 0 {
|
||||
msgBuilder.WriteString(fmt.Sprintf(", %d failed", failed))
|
||||
}
|
||||
gologger.Info().Msgf(msgBuilder.String())
|
||||
gologger.Info().Msgf("%v", msgBuilder.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ func (i *Integration) CreateIssue(event *output.ResultEvent) (*filters.CreateIss
|
||||
if label := i.options.IssueLabel; label != "" {
|
||||
labels = append(labels, label)
|
||||
}
|
||||
customLabels := gitlab.Labels(labels)
|
||||
customLabels := gitlab.LabelOptions(labels)
|
||||
assigneeIDs := []int{i.userID}
|
||||
if i.options.DuplicateIssueCheck {
|
||||
searchIn := "title"
|
||||
|
||||
@@ -70,9 +70,13 @@ type Options struct {
|
||||
// Token is the token for jira instance.
|
||||
Token string `yaml:"token" json:"token" validate:"required"`
|
||||
// ProjectName is the name of the project.
|
||||
ProjectName string `yaml:"project-name" json:"project_name" validate:"required"`
|
||||
ProjectName string `yaml:"project-name" json:"project_name"`
|
||||
// ProjectID is the ID of the project (optional)
|
||||
ProjectID string `yaml:"project-id" json:"project_id"`
|
||||
// IssueType (optional) is the name of the created issue type
|
||||
IssueType string `yaml:"issue-type" json:"issue_type"`
|
||||
// IssueTypeID (optional) is the ID of the created issue type
|
||||
IssueTypeID string `yaml:"issue-type-id" json:"issue_type_id"`
|
||||
// SeverityAsLabel (optional) sends the severity as the label of the created
|
||||
// issue.
|
||||
SeverityAsLabel bool `yaml:"severity-as-label" json:"severity_as_label"`
|
||||
@@ -183,6 +187,7 @@ func (i *Integration) CreateNewIssue(event *output.ResultEvent) (*filters.Create
|
||||
Project: jira.Project{Key: i.options.ProjectName},
|
||||
Summary: summary,
|
||||
}
|
||||
|
||||
// On-prem version of Jira server does not use AccountID
|
||||
if !i.options.Cloud {
|
||||
fields = &jira.IssueFields{
|
||||
@@ -195,6 +200,12 @@ func (i *Integration) CreateNewIssue(event *output.ResultEvent) (*filters.Create
|
||||
Unknowns: customFields,
|
||||
}
|
||||
}
|
||||
if i.options.IssueTypeID != "" {
|
||||
fields.Type = jira.IssueType{ID: i.options.IssueTypeID}
|
||||
}
|
||||
if i.options.ProjectID != "" {
|
||||
fields.Project = jira.Project{ID: i.options.ProjectID}
|
||||
}
|
||||
|
||||
issueData := &jira.Issue{
|
||||
Fields: fields,
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -21,18 +20,21 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ReDigest = regexp.MustCompile(`(?m)^#\sdigest:\s.+$`)
|
||||
ErrUnknownAlgorithm = errors.New("unknown algorithm")
|
||||
SignaturePattern = "# digest: "
|
||||
SignatureFmt = SignaturePattern + "%x" + ":%v" // `#digest: <signature>:<fragment>`
|
||||
)
|
||||
|
||||
func RemoveSignatureFromData(data []byte) []byte {
|
||||
return bytes.Trim(ReDigest.ReplaceAll(data, []byte("")), "\n")
|
||||
}
|
||||
|
||||
func GetSignatureFromData(data []byte) []byte {
|
||||
return ReDigest.Find(data)
|
||||
// ExtractSignatureAndContent extracts the signature (if present) and returns the content without the signature
|
||||
func ExtractSignatureAndContent(data []byte) (signature, content []byte) {
|
||||
dataStr := string(data)
|
||||
if idx := strings.LastIndex(dataStr, SignaturePattern); idx != -1 {
|
||||
signature = []byte(strings.TrimSpace(dataStr[idx:]))
|
||||
content = []byte(strings.TrimSpace(dataStr[:idx]))
|
||||
} else {
|
||||
content = data
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SignableTemplate is a template that can be signed
|
||||
@@ -69,26 +71,29 @@ func (t *TemplateSigner) GetUserFragment() string {
|
||||
|
||||
// Sign signs the given template with the template signer and returns the signature
|
||||
func (t *TemplateSigner) Sign(data []byte, tmpl SignableTemplate) (string, error) {
|
||||
existingSignature, content := ExtractSignatureAndContent(data)
|
||||
|
||||
// while re-signing template check if it has a code protocol
|
||||
// if it does then verify that it is signed by current signer
|
||||
// if not then return error
|
||||
if tmpl.HasCodeProtocol() {
|
||||
sig := GetSignatureFromData(data)
|
||||
arr := strings.SplitN(string(sig), ":", 3)
|
||||
if len(arr) == 2 {
|
||||
// signature has no fragment
|
||||
return "", errorutil.NewWithTag("signer", "re-signing code templates are not allowed for security reasons.")
|
||||
}
|
||||
if len(arr) == 3 {
|
||||
// signature has fragment verify if it is equal to current fragment
|
||||
fragment := t.GetUserFragment()
|
||||
if fragment != arr[2] {
|
||||
if len(existingSignature) > 0 {
|
||||
arr := strings.SplitN(string(existingSignature), ":", 3)
|
||||
if len(arr) == 2 {
|
||||
// signature has no fragment
|
||||
return "", errorutil.NewWithTag("signer", "re-signing code templates are not allowed for security reasons.")
|
||||
}
|
||||
if len(arr) == 3 {
|
||||
// signature has fragment verify if it is equal to current fragment
|
||||
fragment := t.GetUserFragment()
|
||||
if fragment != arr[2] {
|
||||
return "", errorutil.NewWithTag("signer", "re-signing code templates are not allowed for security reasons.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buff := bytes.NewBuffer(RemoveSignatureFromData(data))
|
||||
buff := bytes.NewBuffer(content)
|
||||
// if file has any imports process them
|
||||
for _, file := range tmpl.GetFileImports() {
|
||||
bin, err := os.ReadFile(file)
|
||||
@@ -123,12 +128,16 @@ func (t *TemplateSigner) sign(data []byte) (string, error) {
|
||||
|
||||
// Verify verifies the given template with the template signer
|
||||
func (t *TemplateSigner) Verify(data []byte, tmpl SignableTemplate) (bool, error) {
|
||||
digestData := ReDigest.Find(data)
|
||||
if len(digestData) == 0 {
|
||||
return false, errors.New("digest not found")
|
||||
signature, content := ExtractSignatureAndContent(data)
|
||||
if len(signature) == 0 {
|
||||
return false, errors.New("no signature found")
|
||||
}
|
||||
|
||||
digestData = bytes.TrimSpace(bytes.TrimPrefix(digestData, []byte(SignaturePattern)))
|
||||
if !bytes.HasPrefix(signature, []byte(SignaturePattern)) {
|
||||
return false, errors.New("signature must be at the end of the template")
|
||||
}
|
||||
|
||||
digestData := bytes.TrimSpace(bytes.TrimPrefix(signature, []byte(SignaturePattern)))
|
||||
// remove fragment from digest as it is used for re-signing purposes only
|
||||
digestString := strings.TrimSuffix(string(digestData), ":"+t.GetUserFragment())
|
||||
digest, err := hex.DecodeString(digestString)
|
||||
@@ -136,7 +145,7 @@ func (t *TemplateSigner) Verify(data []byte, tmpl SignableTemplate) (bool, error
|
||||
return false, err
|
||||
}
|
||||
|
||||
buff := bytes.NewBuffer(RemoveSignatureFromData(data))
|
||||
buff := bytes.NewBuffer(content)
|
||||
// if file has any imports process them
|
||||
for _, file := range tmpl.GetFileImports() {
|
||||
bin, err := os.ReadFile(file)
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package signer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
testCertFile = "../../../integration_tests/protocols/keys/ci.crt"
|
||||
testKeyFile = "../../../integration_tests/protocols/keys/ci-private-key.pem"
|
||||
)
|
||||
|
||||
type mockSignableTemplate struct {
|
||||
imports []string
|
||||
hasCode bool
|
||||
}
|
||||
|
||||
func (m *mockSignableTemplate) GetFileImports() []string {
|
||||
return m.imports
|
||||
}
|
||||
|
||||
func (m *mockSignableTemplate) HasCodeProtocol() bool {
|
||||
return m.hasCode
|
||||
}
|
||||
|
||||
var signer, _ = NewTemplateSignerFromFiles(testCertFile, testKeyFile)
|
||||
|
||||
func TestTemplateSignerSignAndVerify(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
data []byte
|
||||
tmpl SignableTemplate
|
||||
wantSignErr bool
|
||||
wantVerifyErr bool
|
||||
wantVerified bool
|
||||
modifyAfterSign func([]byte) []byte
|
||||
}{
|
||||
{
|
||||
name: "Simple template",
|
||||
data: []byte("id: test-template\ninfo:\n name: Test Template"),
|
||||
tmpl: &mockSignableTemplate{},
|
||||
wantVerified: true,
|
||||
},
|
||||
{
|
||||
name: "Template with imports",
|
||||
data: []byte("id: test-template\ninfo:\n name: Test Template"),
|
||||
tmpl: &mockSignableTemplate{imports: []string{
|
||||
filepath.Join(tempDir, "import1.yaml"),
|
||||
filepath.Join(tempDir, "import2.yaml"),
|
||||
}},
|
||||
wantVerified: true,
|
||||
},
|
||||
{
|
||||
name: "Template with code protocol",
|
||||
data: []byte("id: test-template\ninfo:\n name: Test Template\n\ncode:\n - engine: bash\n source: echo 'Hello, World!'"),
|
||||
tmpl: &mockSignableTemplate{hasCode: true},
|
||||
wantSignErr: false,
|
||||
wantVerified: true,
|
||||
},
|
||||
{
|
||||
name: "Tampered template",
|
||||
data: []byte("id: test-template\ninfo:\n name: Test Template"),
|
||||
tmpl: &mockSignableTemplate{},
|
||||
modifyAfterSign: func(data []byte) []byte {
|
||||
signatureIndex := bytes.LastIndex(data, []byte(SignaturePattern))
|
||||
if signatureIndex == -1 {
|
||||
return data
|
||||
}
|
||||
return append(data[:signatureIndex], append([]byte("# Tampered content\n"), data[signatureIndex:]...)...)
|
||||
},
|
||||
wantVerified: false,
|
||||
},
|
||||
{
|
||||
name: "Invalid signature",
|
||||
data: []byte("id: test-template\ninfo:\n name: Test Template"),
|
||||
tmpl: &mockSignableTemplate{},
|
||||
modifyAfterSign: func(data []byte) []byte {
|
||||
return append(bytes.TrimSuffix(data, []byte("\n")), []byte("\n# digest: invalid_signature:fragment")...)
|
||||
},
|
||||
wantVerifyErr: true,
|
||||
wantVerified: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create import files if needed
|
||||
for _, imp := range tt.tmpl.GetFileImports() {
|
||||
err := os.WriteFile(imp, []byte("imported content"), 0644)
|
||||
require.NoError(t, err, "Failed to create import file")
|
||||
}
|
||||
|
||||
// Sign the template
|
||||
signature, err := signer.Sign(tt.data, tt.tmpl)
|
||||
if tt.wantSignErr {
|
||||
assert.Error(t, err, "Expected an error during signing")
|
||||
return
|
||||
}
|
||||
require.NoError(t, err, "Failed to sign template")
|
||||
|
||||
// Append signature to the template data
|
||||
signedData := append(tt.data, []byte("\n"+signature)...)
|
||||
|
||||
// Apply any modifications after signing if specified
|
||||
if tt.modifyAfterSign != nil {
|
||||
signedData = tt.modifyAfterSign(signedData)
|
||||
}
|
||||
|
||||
// Verify the signature
|
||||
verified, err := signer.Verify(signedData, tt.tmpl)
|
||||
if tt.wantVerifyErr {
|
||||
assert.Error(t, err, "Expected an error during verification")
|
||||
} else {
|
||||
assert.NoError(t, err, "Unexpected error during verification")
|
||||
}
|
||||
assert.Equal(t, tt.wantVerified, verified, "Unexpected verification result")
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -75,11 +75,12 @@ func SignTemplate(templateSigner *signer.TemplateSigner, templatePath string) er
|
||||
return ErrNotATemplate
|
||||
}
|
||||
if !template.Verified {
|
||||
_, content := signer.ExtractSignatureAndContent(bin)
|
||||
signatureData, err := templateSigner.Sign(bin, template)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buff := bytes.NewBuffer(signer.RemoveSignatureFromData(bin))
|
||||
buff := bytes.NewBuffer(content)
|
||||
buff.WriteString("\n" + signatureData)
|
||||
return os.WriteFile(templatePath, buff.Bytes(), 0644)
|
||||
}
|
||||
|
||||
@@ -459,7 +459,7 @@ func init() {
|
||||
Value: "HTTP response headers in name:value format",
|
||||
},
|
||||
}
|
||||
HTTPRequestDoc.Fields = make([]encoder.Doc, 35)
|
||||
HTTPRequestDoc.Fields = make([]encoder.Doc, 36)
|
||||
HTTPRequestDoc.Fields[0].Name = "path"
|
||||
HTTPRequestDoc.Fields[0].Type = "[]string"
|
||||
HTTPRequestDoc.Fields[0].Note = ""
|
||||
@@ -578,91 +578,96 @@ func init() {
|
||||
HTTPRequestDoc.Fields[17].Values = []string{
|
||||
"AWS",
|
||||
}
|
||||
HTTPRequestDoc.Fields[18].Name = "cookie-reuse"
|
||||
HTTPRequestDoc.Fields[18].Name = "skip-secret-file"
|
||||
HTTPRequestDoc.Fields[18].Type = "bool"
|
||||
HTTPRequestDoc.Fields[18].Note = ""
|
||||
HTTPRequestDoc.Fields[18].Description = "CookieReuse is an optional setting that enables cookie reuse for\nall requests defined in raw section."
|
||||
HTTPRequestDoc.Fields[18].Comments[encoder.LineComment] = "CookieReuse is an optional setting that enables cookie reuse for"
|
||||
HTTPRequestDoc.Fields[19].Name = "disable-cookie"
|
||||
HTTPRequestDoc.Fields[18].Description = "SkipSecretFile skips the authentication or authorization configured in the secret file."
|
||||
HTTPRequestDoc.Fields[18].Comments[encoder.LineComment] = "SkipSecretFile skips the authentication or authorization configured in the secret file."
|
||||
HTTPRequestDoc.Fields[19].Name = "cookie-reuse"
|
||||
HTTPRequestDoc.Fields[19].Type = "bool"
|
||||
HTTPRequestDoc.Fields[19].Note = ""
|
||||
HTTPRequestDoc.Fields[19].Description = "DisableCookie is an optional setting that disables cookie reuse"
|
||||
HTTPRequestDoc.Fields[19].Comments[encoder.LineComment] = "DisableCookie is an optional setting that disables cookie reuse"
|
||||
HTTPRequestDoc.Fields[20].Name = "read-all"
|
||||
HTTPRequestDoc.Fields[19].Description = "CookieReuse is an optional setting that enables cookie reuse for\nall requests defined in raw section."
|
||||
HTTPRequestDoc.Fields[19].Comments[encoder.LineComment] = "CookieReuse is an optional setting that enables cookie reuse for"
|
||||
HTTPRequestDoc.Fields[20].Name = "disable-cookie"
|
||||
HTTPRequestDoc.Fields[20].Type = "bool"
|
||||
HTTPRequestDoc.Fields[20].Note = ""
|
||||
HTTPRequestDoc.Fields[20].Description = "Enables force reading of the entire raw unsafe request body ignoring\nany specified content length headers."
|
||||
HTTPRequestDoc.Fields[20].Comments[encoder.LineComment] = "Enables force reading of the entire raw unsafe request body ignoring"
|
||||
HTTPRequestDoc.Fields[21].Name = "redirects"
|
||||
HTTPRequestDoc.Fields[20].Description = "DisableCookie is an optional setting that disables cookie reuse"
|
||||
HTTPRequestDoc.Fields[20].Comments[encoder.LineComment] = "DisableCookie is an optional setting that disables cookie reuse"
|
||||
HTTPRequestDoc.Fields[21].Name = "read-all"
|
||||
HTTPRequestDoc.Fields[21].Type = "bool"
|
||||
HTTPRequestDoc.Fields[21].Note = ""
|
||||
HTTPRequestDoc.Fields[21].Description = "Redirects specifies whether redirects should be followed by the HTTP Client.\n\nThis can be used in conjunction with `max-redirects` to control the HTTP request redirects."
|
||||
HTTPRequestDoc.Fields[21].Comments[encoder.LineComment] = "Redirects specifies whether redirects should be followed by the HTTP Client."
|
||||
HTTPRequestDoc.Fields[22].Name = "host-redirects"
|
||||
HTTPRequestDoc.Fields[21].Description = "Enables force reading of the entire raw unsafe request body ignoring\nany specified content length headers."
|
||||
HTTPRequestDoc.Fields[21].Comments[encoder.LineComment] = "Enables force reading of the entire raw unsafe request body ignoring"
|
||||
HTTPRequestDoc.Fields[22].Name = "redirects"
|
||||
HTTPRequestDoc.Fields[22].Type = "bool"
|
||||
HTTPRequestDoc.Fields[22].Note = ""
|
||||
HTTPRequestDoc.Fields[22].Description = "Redirects specifies whether only redirects to the same host should be followed by the HTTP Client.\n\nThis can be used in conjunction with `max-redirects` to control the HTTP request redirects."
|
||||
HTTPRequestDoc.Fields[22].Comments[encoder.LineComment] = "Redirects specifies whether only redirects to the same host should be followed by the HTTP Client."
|
||||
HTTPRequestDoc.Fields[23].Name = "pipeline"
|
||||
HTTPRequestDoc.Fields[22].Description = "Redirects specifies whether redirects should be followed by the HTTP Client.\n\nThis can be used in conjunction with `max-redirects` to control the HTTP request redirects."
|
||||
HTTPRequestDoc.Fields[22].Comments[encoder.LineComment] = "Redirects specifies whether redirects should be followed by the HTTP Client."
|
||||
HTTPRequestDoc.Fields[23].Name = "host-redirects"
|
||||
HTTPRequestDoc.Fields[23].Type = "bool"
|
||||
HTTPRequestDoc.Fields[23].Note = ""
|
||||
HTTPRequestDoc.Fields[23].Description = "Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining\n\nAll requests must be idempotent (GET/POST). This can be used for race conditions/billions requests."
|
||||
HTTPRequestDoc.Fields[23].Comments[encoder.LineComment] = "Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining"
|
||||
HTTPRequestDoc.Fields[24].Name = "unsafe"
|
||||
HTTPRequestDoc.Fields[23].Description = "Redirects specifies whether only redirects to the same host should be followed by the HTTP Client.\n\nThis can be used in conjunction with `max-redirects` to control the HTTP request redirects."
|
||||
HTTPRequestDoc.Fields[23].Comments[encoder.LineComment] = "Redirects specifies whether only redirects to the same host should be followed by the HTTP Client."
|
||||
HTTPRequestDoc.Fields[24].Name = "pipeline"
|
||||
HTTPRequestDoc.Fields[24].Type = "bool"
|
||||
HTTPRequestDoc.Fields[24].Note = ""
|
||||
HTTPRequestDoc.Fields[24].Description = "Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests.\n\nThis uses the [rawhttp](https://github.com/projectdiscovery/rawhttp) engine to achieve complete\ncontrol over the request, with no normalization performed by the client."
|
||||
HTTPRequestDoc.Fields[24].Comments[encoder.LineComment] = "Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests."
|
||||
HTTPRequestDoc.Fields[25].Name = "race"
|
||||
HTTPRequestDoc.Fields[24].Description = "Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining\n\nAll requests must be idempotent (GET/POST). This can be used for race conditions/billions requests."
|
||||
HTTPRequestDoc.Fields[24].Comments[encoder.LineComment] = "Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining"
|
||||
HTTPRequestDoc.Fields[25].Name = "unsafe"
|
||||
HTTPRequestDoc.Fields[25].Type = "bool"
|
||||
HTTPRequestDoc.Fields[25].Note = ""
|
||||
HTTPRequestDoc.Fields[25].Description = "Race determines if all the request have to be attempted at the same time (Race Condition)\n\nThe actual number of requests that will be sent is determined by the `race_count` field."
|
||||
HTTPRequestDoc.Fields[25].Comments[encoder.LineComment] = "Race determines if all the request have to be attempted at the same time (Race Condition)"
|
||||
HTTPRequestDoc.Fields[26].Name = "req-condition"
|
||||
HTTPRequestDoc.Fields[25].Description = "Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests.\n\nThis uses the [rawhttp](https://github.com/projectdiscovery/rawhttp) engine to achieve complete\ncontrol over the request, with no normalization performed by the client."
|
||||
HTTPRequestDoc.Fields[25].Comments[encoder.LineComment] = "Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests."
|
||||
HTTPRequestDoc.Fields[26].Name = "race"
|
||||
HTTPRequestDoc.Fields[26].Type = "bool"
|
||||
HTTPRequestDoc.Fields[26].Note = ""
|
||||
HTTPRequestDoc.Fields[26].Description = "ReqCondition automatically assigns numbers to requests and preserves their history.\n\nThis allows matching on them later for multi-request conditions."
|
||||
HTTPRequestDoc.Fields[26].Comments[encoder.LineComment] = "ReqCondition automatically assigns numbers to requests and preserves their history."
|
||||
HTTPRequestDoc.Fields[27].Name = "stop-at-first-match"
|
||||
HTTPRequestDoc.Fields[26].Description = "Race determines if all the request have to be attempted at the same time (Race Condition)\n\nThe actual number of requests that will be sent is determined by the `race_count` field."
|
||||
HTTPRequestDoc.Fields[26].Comments[encoder.LineComment] = "Race determines if all the request have to be attempted at the same time (Race Condition)"
|
||||
HTTPRequestDoc.Fields[27].Name = "req-condition"
|
||||
HTTPRequestDoc.Fields[27].Type = "bool"
|
||||
HTTPRequestDoc.Fields[27].Note = ""
|
||||
HTTPRequestDoc.Fields[27].Description = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
|
||||
HTTPRequestDoc.Fields[27].Comments[encoder.LineComment] = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
|
||||
HTTPRequestDoc.Fields[28].Name = "skip-variables-check"
|
||||
HTTPRequestDoc.Fields[27].Description = "ReqCondition automatically assigns numbers to requests and preserves their history.\n\nThis allows matching on them later for multi-request conditions."
|
||||
HTTPRequestDoc.Fields[27].Comments[encoder.LineComment] = "ReqCondition automatically assigns numbers to requests and preserves their history."
|
||||
HTTPRequestDoc.Fields[28].Name = "stop-at-first-match"
|
||||
HTTPRequestDoc.Fields[28].Type = "bool"
|
||||
HTTPRequestDoc.Fields[28].Note = ""
|
||||
HTTPRequestDoc.Fields[28].Description = "SkipVariablesCheck skips the check for unresolved variables in request"
|
||||
HTTPRequestDoc.Fields[28].Comments[encoder.LineComment] = "SkipVariablesCheck skips the check for unresolved variables in request"
|
||||
HTTPRequestDoc.Fields[29].Name = "iterate-all"
|
||||
HTTPRequestDoc.Fields[28].Description = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
|
||||
HTTPRequestDoc.Fields[28].Comments[encoder.LineComment] = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
|
||||
HTTPRequestDoc.Fields[29].Name = "skip-variables-check"
|
||||
HTTPRequestDoc.Fields[29].Type = "bool"
|
||||
HTTPRequestDoc.Fields[29].Note = ""
|
||||
HTTPRequestDoc.Fields[29].Description = "IterateAll iterates all the values extracted from internal extractors"
|
||||
HTTPRequestDoc.Fields[29].Comments[encoder.LineComment] = "IterateAll iterates all the values extracted from internal extractors"
|
||||
HTTPRequestDoc.Fields[30].Name = "digest-username"
|
||||
HTTPRequestDoc.Fields[30].Type = "string"
|
||||
HTTPRequestDoc.Fields[29].Description = "SkipVariablesCheck skips the check for unresolved variables in request"
|
||||
HTTPRequestDoc.Fields[29].Comments[encoder.LineComment] = "SkipVariablesCheck skips the check for unresolved variables in request"
|
||||
HTTPRequestDoc.Fields[30].Name = "iterate-all"
|
||||
HTTPRequestDoc.Fields[30].Type = "bool"
|
||||
HTTPRequestDoc.Fields[30].Note = ""
|
||||
HTTPRequestDoc.Fields[30].Description = "DigestAuthUsername specifies the username for digest authentication"
|
||||
HTTPRequestDoc.Fields[30].Comments[encoder.LineComment] = "DigestAuthUsername specifies the username for digest authentication"
|
||||
HTTPRequestDoc.Fields[31].Name = "digest-password"
|
||||
HTTPRequestDoc.Fields[30].Description = "IterateAll iterates all the values extracted from internal extractors"
|
||||
HTTPRequestDoc.Fields[30].Comments[encoder.LineComment] = "IterateAll iterates all the values extracted from internal extractors"
|
||||
HTTPRequestDoc.Fields[31].Name = "digest-username"
|
||||
HTTPRequestDoc.Fields[31].Type = "string"
|
||||
HTTPRequestDoc.Fields[31].Note = ""
|
||||
HTTPRequestDoc.Fields[31].Description = "DigestAuthPassword specifies the password for digest authentication"
|
||||
HTTPRequestDoc.Fields[31].Comments[encoder.LineComment] = "DigestAuthPassword specifies the password for digest authentication"
|
||||
HTTPRequestDoc.Fields[32].Name = "disable-path-automerge"
|
||||
HTTPRequestDoc.Fields[32].Type = "bool"
|
||||
HTTPRequestDoc.Fields[31].Description = "DigestAuthUsername specifies the username for digest authentication"
|
||||
HTTPRequestDoc.Fields[31].Comments[encoder.LineComment] = "DigestAuthUsername specifies the username for digest authentication"
|
||||
HTTPRequestDoc.Fields[32].Name = "digest-password"
|
||||
HTTPRequestDoc.Fields[32].Type = "string"
|
||||
HTTPRequestDoc.Fields[32].Note = ""
|
||||
HTTPRequestDoc.Fields[32].Description = "DisablePathAutomerge disables merging target url path with raw request path"
|
||||
HTTPRequestDoc.Fields[32].Comments[encoder.LineComment] = "DisablePathAutomerge disables merging target url path with raw request path"
|
||||
HTTPRequestDoc.Fields[33].Name = "pre-condition"
|
||||
HTTPRequestDoc.Fields[33].Type = "[]matchers.Matcher"
|
||||
HTTPRequestDoc.Fields[32].Description = "DigestAuthPassword specifies the password for digest authentication"
|
||||
HTTPRequestDoc.Fields[32].Comments[encoder.LineComment] = "DigestAuthPassword specifies the password for digest authentication"
|
||||
HTTPRequestDoc.Fields[33].Name = "disable-path-automerge"
|
||||
HTTPRequestDoc.Fields[33].Type = "bool"
|
||||
HTTPRequestDoc.Fields[33].Note = ""
|
||||
HTTPRequestDoc.Fields[33].Description = "Fuzz PreCondition is matcher-like field to check if fuzzing should be performed on this request or not"
|
||||
HTTPRequestDoc.Fields[33].Comments[encoder.LineComment] = "Fuzz PreCondition is matcher-like field to check if fuzzing should be performed on this request or not"
|
||||
HTTPRequestDoc.Fields[34].Name = "pre-condition-operator"
|
||||
HTTPRequestDoc.Fields[34].Type = "string"
|
||||
HTTPRequestDoc.Fields[33].Description = "DisablePathAutomerge disables merging target url path with raw request path"
|
||||
HTTPRequestDoc.Fields[33].Comments[encoder.LineComment] = "DisablePathAutomerge disables merging target url path with raw request path"
|
||||
HTTPRequestDoc.Fields[34].Name = "pre-condition"
|
||||
HTTPRequestDoc.Fields[34].Type = "[]matchers.Matcher"
|
||||
HTTPRequestDoc.Fields[34].Note = ""
|
||||
HTTPRequestDoc.Fields[34].Description = "FuzzPreConditionOperator is the operator between multiple PreConditions for fuzzing Default is OR"
|
||||
HTTPRequestDoc.Fields[34].Comments[encoder.LineComment] = "FuzzPreConditionOperator is the operator between multiple PreConditions for fuzzing Default is OR"
|
||||
HTTPRequestDoc.Fields[34].Description = "Fuzz PreCondition is matcher-like field to check if fuzzing should be performed on this request or not"
|
||||
HTTPRequestDoc.Fields[34].Comments[encoder.LineComment] = "Fuzz PreCondition is matcher-like field to check if fuzzing should be performed on this request or not"
|
||||
HTTPRequestDoc.Fields[35].Name = "pre-condition-operator"
|
||||
HTTPRequestDoc.Fields[35].Type = "string"
|
||||
HTTPRequestDoc.Fields[35].Note = ""
|
||||
HTTPRequestDoc.Fields[35].Description = "FuzzPreConditionOperator is the operator between multiple PreConditions for fuzzing Default is OR"
|
||||
HTTPRequestDoc.Fields[35].Comments[encoder.LineComment] = "FuzzPreConditionOperator is the operator between multiple PreConditions for fuzzing Default is OR"
|
||||
|
||||
GENERATORSAttackTypeHolderDoc.Type = "generators.AttackTypeHolder"
|
||||
GENERATORSAttackTypeHolderDoc.Comments[encoder.LineComment] = " AttackTypeHolder is used to hold internal type of the protocol"
|
||||
|
||||
@@ -68,8 +68,10 @@ func (e *TemplateExecuter) Compile() error {
|
||||
if cliOptions.Verbose {
|
||||
rawErrorMessage := dslCompilationError.Error()
|
||||
formattedErrorMessage := strings.ToUpper(rawErrorMessage[:1]) + rawErrorMessage[1:] + "."
|
||||
gologger.Warning().Msgf(formattedErrorMessage)
|
||||
|
||||
gologger.Warning().Msg(formattedErrorMessage)
|
||||
gologger.Info().Msgf("The available custom DSL functions are:")
|
||||
|
||||
fmt.Println(dsl.GetPrintableDslFunctionSignatures(cliOptions.NoColor))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +220,8 @@ type Options struct {
|
||||
JSONExport string
|
||||
// JSONLExport is the file to export JSONL output format to
|
||||
JSONLExport string
|
||||
// Redact redacts given keys in
|
||||
Redact goflags.StringSlice
|
||||
// EnableProgressBar enables progress bar
|
||||
EnableProgressBar bool
|
||||
// TemplateDisplay displays the template contents
|
||||
@@ -382,6 +384,8 @@ type Options struct {
|
||||
ScanID string
|
||||
// ScanName is the name of the scan to be uploaded
|
||||
ScanName string
|
||||
// TeamID is the team ID to use for cloud upload
|
||||
TeamID string
|
||||
// JsConcurrency is the number of concurrent js routines to run
|
||||
JsConcurrency int
|
||||
// SecretsFile is file containing secrets for nuclei
|
||||
|
||||
Reference in new issue
Block a user