Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix: data race at protocolstate, contextargs & some outdated test cases #5820

Merged
merged 10 commits into from
Nov 19, 2024
2 changes: 1 addition & 1 deletion cmd/integration-test/flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var flowTestcases = []TestCaseInfo{
type conditionalFlow struct{}

func (t *conditionalFlow) Execute(filePath string) error {
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "blog.projectdiscovery.io", debug)
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "cloud.projectdiscovery.io", debug)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/integration-test/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (h *httpInteractshRequest) Execute(filePath string) error {
return err
}

return expectResultsCount(results, 1)
return expectResultsCount(results, 1, 2)
}

type httpDefaultMatcherCondition struct{}
Expand Down
2 changes: 1 addition & 1 deletion cmd/integration-test/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type multiProtoDynamicExtractor struct{}

// Execute executes a test case and returns an error if occurred
func (h *multiProtoDynamicExtractor) Execute(templatePath string) error {
results, err := testutils.RunNucleiTemplateAndGetResults(templatePath, "blog.projectdiscovery.io", debug)
results, err := testutils.RunNucleiTemplateAndGetResults(templatePath, "docs.projectdiscovery.io", debug)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions integration_tests/flow/conditional-flow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dns:
matchers:
- type: word
words:
- "ghost.io"
- ".vercel-dns.com"
internal: true

http:
Expand All @@ -25,4 +25,4 @@ http:
matchers:
- type: word
words:
- "ghost.io"
- "html>"
2 changes: 1 addition & 1 deletion integration_tests/protocols/code/pre-condition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ code:
- type: dsl
dsl:
- true
# digest: 4a0a0047304502200307590191cb7c766b6c21e5777d345bdddf7adf9d6da8f7d336d585d9ac4a8b022100fd30fb0c7722778eb3d861d60e721d805925b8d8df2b979ef2104c35ec57d5cb:4a3eb6b4988d95847d4203be25ed1d46
# digest: 490a00463044022048c083c338c0195f5012122d40c1009d2e2030c583e56558e0d6249a41e6f3f4022070656adf748f4874018d7a01fce116db10a3acd1f9b03e12a83906fb625b5c50:4a3eb6b4988d95847d4203be25ed1d46
2 changes: 1 addition & 1 deletion integration_tests/protocols/code/py-env-var.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ code:
- type: word
words:
- "hello from input baz"
# digest: 4a0a0047304502203fe1d7d52bc2a41886d576a90c82c3be42078baaa4b46e1f3d8519665d6f88b202210081feb82c41150c5b218e226fc4f299ded19f42ba01ef34ba60b0634b4ea6ee12:4a3eb6b4988d95847d4203be25ed1d46
# digest: 4b0a00483046022100cbbdb7214f669d111b671d271110872dc8af2ab41cf5c312b6e4f64126f55337022100a60547952a0c2bea58388f2d2effe8ad73cd6b6fc92e73eb3c8f88beab6105ec:4a3eb6b4988d95847d4203be25ed1d46
2 changes: 1 addition & 1 deletion integration_tests/protocols/code/py-file.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ code:
- type: word
words:
- "hello from input"
# digest: 4b0a00483046022100afb5ebff14a40e7f9b679ffc4d93ce7849e33eb398ebb47f2e757cd24831f9dd02210089ffa21b2763e99ebce95dfc5b91e1e62da4ccdc9d2ad5c48584fa350ba335af:4a3eb6b4988d95847d4203be25ed1d46
# digest: 4a0a00473045022032b81e8bb7475abf27639b0ced71355497166d664698021f26498e7031d62a23022100e99ccde578bfc0b658f16427ae9a3d18922849d3ba3e022032ea0d2a8e77fadb:4a3eb6b4988d95847d4203be25ed1d46
2 changes: 1 addition & 1 deletion integration_tests/protocols/code/py-interactsh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ code:
part: interactsh_protocol
words:
- "http"
# digest: 4b0a00483046022100939f83e74d43932a5bd792b1fd2c100eec2df60f2b2a8dd56b5c8ef5faa92b17022100f93031b0de373af7d78e623968ea5a2d67c4561ef70e3e6da15aef7e5c853115:4a3eb6b4988d95847d4203be25ed1d46
# digest: 4a0a0047304502201a5dd0eddfab4f02588a5a8ac1947a5fa41fed80b59d698ad5cc00456296efb6022100fe6e608e38c060964800f5f863a7cdc93f686f2d0f4b52854f73948b808b4511:4a3eb6b4988d95847d4203be25ed1d46
2 changes: 1 addition & 1 deletion integration_tests/protocols/code/py-snippet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ code:
- type: word
words:
- "hello from input"
# digest: 4a0a00473045022100b8e676ce0c57b60c233a0203539dec20457bbb5f1790d351a5d45405b6668b2602204b1f2fa18e7db099f05329009597ceb2d9b7337562c1a676e8d50ea2f1c6fcbe:4a3eb6b4988d95847d4203be25ed1d46
# digest: 4b0a00483046022100ced1702728cc68f906c4c7d2c4d05ed071bfabee1e36eec7ebecbeca795a170c022100d20fd41796f130a8f9c4972fee85386d67d61eb5fc1119b1afe2a851eb2f3e65:4a3eb6b4988d95847d4203be25ed1d46
6 changes: 3 additions & 3 deletions integration_tests/protocols/multi/dynamic-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dns:
- type: dsl
name: blogid
dsl:
- trim_suffix(cname,'.ghost.io')
- trim_suffix(cname,'.vercel-dns.com')
internal: true

http:
Expand All @@ -24,6 +24,6 @@ http:
matchers:
- type: dsl
dsl:
- contains(body,'ProjectDiscovery.io') # check for http string
- blogid == 'projectdiscovery' # check for cname (extracted information from dns response)
- contains(body,'introduction') # check for http string
- blogid == 'cname' # check for cname (extracted information from dns response)
condition: and
8 changes: 4 additions & 4 deletions integration_tests/protocols/multi/evaluate-variables.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ info:


variables:
cname_filtered: '{{trim_suffix(dns_cname,".ghost.io")}}'
cname_filtered: '{{trim_suffix(dns_cname,".vercel-dns.com")}}'

dns:
- name: "{{FQDN}}" # DNS Request
Expand All @@ -24,7 +24,7 @@ http:
matchers:
- type: dsl
dsl:
- contains(http_body,'ProjectDiscovery.io') # check for http string
- cname_filtered == 'projectdiscovery' # check for cname (extracted information from dns response)
- ssl_subject_cn == 'blog.projectdiscovery.io'
- contains(http_body,'introduction') # check for http string
- cname_filtered == 'cname' # check for cname (extracted information from dns response)
- ssl_subject_cn == 'docs.projectdiscovery.io'
condition: and
6 changes: 3 additions & 3 deletions integration_tests/protocols/multi/exported-response-vars.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ http:
matchers:
- type: dsl
dsl:
- contains(http_body,'ProjectDiscovery.io') # check for http string
- trim_suffix(dns_cname,'.ghost.io') == 'projectdiscovery' # check for cname (extracted information from dns response)
- ssl_subject_cn == 'blog.projectdiscovery.io'
- contains(http_body,'introduction') # check for http string
- trim_suffix(dns_cname,'.vercel-dns.com') == 'cname' # check for cname (extracted information from dns response)
- ssl_subject_cn == 'docs.projectdiscovery.io'
condition: and
2 changes: 1 addition & 1 deletion integration_tests/workflow/code-template-1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ code:
regex:
- 'hello from (.*)'
group: 1
# digest: 490a00463044022050da011362cf08c2cb81e812c7f86d7282afe0562d4bf00d390f1300d19bc910022029e9d305da69e941ac18797645aecb217abde6557f891e141301b48e89a3c0cd:4a3eb6b4988d95847d4203be25ed1d46
# digest: 490a0046304402206b3648e8d393ac4df82c7d59b1a6ee3731c66c249dbd4d9bf31f0b7f176b37ec02203184d36373e516757c7d708b5799bc16edb1cebc0a64f3442d13ded4b33c42fb:4a3eb6b4988d95847d4203be25ed1d46
2 changes: 1 addition & 1 deletion integration_tests/workflow/code-template-2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ code:
- type: word
words:
- "hello from first"
# digest: 4b0a00483046022100b3b8759c0df028455eb59b1433ac240e5d4604b011bb0c63680bd3cc159ac6f0022100f44aa11b640d11ad0e2902897f4eb51666ab3cd83c31dfd2590f6e43391e39b0:4a3eb6b4988d95847d4203be25ed1d46
# digest: 490a0046304402204cbb1bdf8370e49bb930b17460fb35e15f285a3b48b165736ac0e7ba2f9bc0fb022067c134790c4a2cf646b195aa4488e2c222266436e6bda47931908a28807bdb81:4a3eb6b4988d95847d4203be25ed1d46
36 changes: 31 additions & 5 deletions pkg/external/customtemplates/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,33 +137,59 @@ getRepo:

// download the git repo to a given path
func (ctr *customTemplateGitHubRepo) cloneRepo(clonePath, githubToken string) error {
r, err := git.PlainClone(clonePath, false, &git.CloneOptions{
URL: ctr.gitCloneURL,
Auth: getAuth(ctr.owner, githubToken),
})
cloneOpts := &git.CloneOptions{
URL: ctr.gitCloneURL,
Auth: getAuth(ctr.owner, githubToken),
SingleBranch: true,
Depth: 1,
}

err := cloneOpts.Validate()
if err != nil {
return err
}

r, err := git.PlainClone(clonePath, false, cloneOpts)
if err != nil {
return errors.Errorf("%s/%s: %s", ctr.owner, ctr.reponame, err.Error())
}

// Add the user as well in the config. By default, user is not set
config, _ := r.Storer.Config()
config.User.Name = ctr.owner

return r.SetConfig(config)
}

// performs the git pull on given repo
func (ctr *customTemplateGitHubRepo) pullChanges(repoPath, githubToken string) error {
pullOpts := &git.PullOptions{
RemoteName: "origin",
Auth: getAuth(ctr.owner, githubToken),
SingleBranch: true,
Depth: 1,
}

err := pullOpts.Validate()
if err != nil {
return err
}

r, err := git.PlainOpen(repoPath)
if err != nil {
return err
}

w, err := r.Worktree()
if err != nil {
return err
}
err = w.Pull(&git.PullOptions{RemoteName: "origin", Auth: getAuth(ctr.owner, githubToken)})

err = w.Pull(pullOpts)
if err != nil {
return errors.Errorf("%s/%s: %s", ctr.owner, ctr.reponame, err.Error())
}

return nil
}

Expand Down
6 changes: 2 additions & 4 deletions pkg/external/customtemplates/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ func TestDownloadCustomTemplatesFromGitHub(t *testing.T) {
config.DefaultConfig.SetTemplatesDir(templatesDirectory)

options := testutils.DefaultOptions
options.GitHubTemplateRepo = []string{"projectdiscovery/nuclei-templates", "ehsandeep/nuclei-templates"}
options.GitHubToken = os.Getenv("GITHUB_TOKEN")
options.GitHubTemplateRepo = []string{"projectdiscovery/nuclei-templates-test"}

ctm, err := NewCustomTemplatesManager(options)
require.Nil(t, err, "could not create custom templates manager")

ctm.Download(context.Background())

require.DirExists(t, filepath.Join(templatesDirectory, "github", "projectdiscovery", "nuclei-templates"), "cloned directory does not exists")
require.DirExists(t, filepath.Join(templatesDirectory, "github", "ehsandeep", "nuclei-templates"), "cloned directory does not exists")
require.DirExists(t, filepath.Join(templatesDirectory, "github", "projectdiscovery", "nuclei-templates-test"), "cloned directory does not exists")
}
3 changes: 3 additions & 0 deletions pkg/protocols/common/contextargs/metainput.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ func (metaInput *MetaInput) Unmarshal(data string) error {
}

func (metaInput *MetaInput) Clone() *MetaInput {
metaInput.mu.Lock()
defer metaInput.mu.Unlock()

input := NewMetaInput()
input.Input = metaInput.Input
input.CustomIP = metaInput.CustomIP
Expand Down
2 changes: 1 addition & 1 deletion pkg/protocols/common/protocolstate/memguardian.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var (
)

func StartActiveMemGuardian(ctx context.Context) {
if memguardian.DefaultMemGuardian == nil {
if memguardian.DefaultMemGuardian == nil || memTimer != nil {
return
}

Expand Down
37 changes: 18 additions & 19 deletions pkg/tmplexec/flow/flow_executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func TestFlowWithConditionPositive(t *testing.T) {
err = Template.Executer.Compile()
require.Nil(t, err, "could not compile template")

input := contextargs.NewWithInput(context.Background(), "blog.projectdiscovery.io")
input := contextargs.NewWithInput(context.Background(), "cloud.projectdiscovery.io")
ctx := scan.NewScanContext(context.Background(), input)
// positive match . expect results also verify that both dns() and http() were executed
gotresults, err := Template.Executer.Execute(ctx)
Expand All @@ -150,36 +150,35 @@ func TestFlowWithNoMatchers(t *testing.T) {
// when using conditional flow with no matchers at all
// we implicitly assume that request was successful and internally changed the result to true (for scope of condition only)

// testcase-1 : no matchers but contains extractor
Template, err := templates.Parse("testcases/condition-flow-extractors.yaml", nil, executerOpts)
Template, err := templates.Parse("testcases/condition-flow-no-operators.yaml", nil, executerOpts)
require.Nil(t, err, "could not parse template")

require.True(t, Template.Flow != "", "not a flow template") // this is classifer if template is flow or not

err = Template.Executer.Compile()
require.Nil(t, err, "could not compile template")

input := contextargs.NewWithInput(context.Background(), "blog.projectdiscovery.io")
ctx := scan.NewScanContext(context.Background(), input)
anotherInput := contextargs.NewWithInput(context.Background(), "cloud.projectdiscovery.io")
anotherCtx := scan.NewScanContext(context.Background(), anotherInput)
// positive match . expect results also verify that both dns() and http() were executed
gotresults, err := Template.Executer.Execute(ctx)
gotresults, err := Template.Executer.Execute(anotherCtx)
require.Nil(t, err, "could not execute template")
require.True(t, gotresults)

// testcase-2 : no matchers and no extractors
Template, err = templates.Parse("testcases/condition-flow-no-operators.yaml", nil, executerOpts)
require.Nil(t, err, "could not parse template")

require.True(t, Template.Flow != "", "not a flow template") // this is classifer if template is flow or not
t.Run("Contains Extractor", func(t *testing.T) {
Template, err := templates.Parse("testcases/condition-flow-extractors.yaml", nil, executerOpts)
require.Nil(t, err, "could not parse template")

err = Template.Executer.Compile()
require.Nil(t, err, "could not compile template")
require.True(t, Template.Flow != "", "not a flow template") // this is classifer if template is flow or not

anotherInput := contextargs.NewWithInput(context.Background(), "blog.projectdiscovery.io")
anotherCtx := scan.NewScanContext(context.Background(), anotherInput)
// positive match . expect results also verify that both dns() and http() were executed
gotresults, err = Template.Executer.Execute(anotherCtx)
require.Nil(t, err, "could not execute template")
require.True(t, gotresults)
err = Template.Executer.Compile()
require.Nil(t, err, "could not compile template")

input := contextargs.NewWithInput(context.Background(), "scanme.sh")
ctx := scan.NewScanContext(context.Background(), input)
// positive match . expect results also verify that both dns() and http() were executed
gotresults, err := Template.Executer.Execute(ctx)
require.Nil(t, err, "could not execute template")
require.True(t, gotresults)
})
}
17 changes: 8 additions & 9 deletions pkg/tmplexec/flow/testcases/condition-flow-extractors.yaml
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
id: ghost-blog-detection
id: condition-flow-extractors
info:
name: Ghost blog detection
name: Condition Flow Extractors
author: pdteam
severity: info


flow: dns() && http()

dns:
- name: "{{FQDN}}"
type: CNAME
type: A

extractors:
- type: dsl
name: cname
name: a
internal: true
dsl:
- cname
- a

http:
- method: GET
path:
- "{{BaseURL}}?ref={{cname}}"
- "{{BaseURL}}/?ref={{a}}"

matchers:
- type: word
words:
- "ghost.io"
- "ok"
12 changes: 5 additions & 7 deletions pkg/tmplexec/flow/testcases/condition-flow-no-operators.yaml
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
id: ghost-blog-detection
id: condition-flow-no-operators
info:
name: Ghost blog detection
name: Condition Flow No Operators
author: pdteam
severity: info


flow: dns() && http()


dns:
- name: "{{FQDN}}"
type: CNAME

http:
- method: GET
path:
- "{{BaseURL}}?ref={{dns_cname}}"
- "{{BaseURL}}/?ref={{dns_cname}}"

matchers:
- type: word
words:
- "ghost.io"
- "html>"
Loading
Loading