mirror of
https://github.com/projectdiscovery/nuclei
synced 2026-06-08 16:50:47 +00:00
f893b6c0cb
Signed-off-by: Dwi Siswanto <git@dw1.io>
195 lines
6.0 KiB
Go
195 lines
6.0 KiB
Go
//go:build integration
|
|
// +build integration
|
|
|
|
package integration_test
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"os/exec"
|
|
"sync"
|
|
|
|
osutils "github.com/projectdiscovery/utils/os"
|
|
|
|
"github.com/projectdiscovery/nuclei/v3/internal/tests/testutils"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/templates"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/templates/signer"
|
|
)
|
|
|
|
var isCodeDisabled = func() bool { return osutils.IsWindows() && os.Getenv("CI") == "true" }
|
|
var signedCodeTemplates sync.Once
|
|
var signedCodeTemplatesErr error
|
|
|
|
func hasAnyExecutable(names ...string) bool {
|
|
for _, name := range names {
|
|
if _, err := exec.LookPath(name); err == nil {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
var codeTestCases = []integrationCase{
|
|
{Path: "protocols/code/py-snippet.yaml", TestCase: &codeSnippet{}, DisableOn: isCodeDisabled},
|
|
{Path: "protocols/code/py-file.yaml", TestCase: &codeFile{}, DisableOn: isCodeDisabled},
|
|
{Path: "protocols/code/py-env-var.yaml", TestCase: &codeEnvVar{}, DisableOn: isCodeDisabled},
|
|
{Path: "protocols/code/unsigned.yaml", TestCase: &unsignedCode{}, DisableOn: isCodeDisabled},
|
|
{Path: "protocols/code/py-nosig.yaml", TestCase: &codePyNoSig{}, DisableOn: isCodeDisabled},
|
|
{Path: "protocols/code/py-interactsh.yaml", TestCase: &codeSnippet{}, DisableOn: isCodeDisabled},
|
|
{Path: "protocols/code/ps1-snippet.yaml", TestCase: &codeSnippet{}, DisableOn: func() bool { return !osutils.IsWindows() || isCodeDisabled() }},
|
|
{Path: "protocols/code/pre-condition.yaml", TestCase: &codePreCondition{}, DisableOn: isCodeDisabled},
|
|
{Path: "protocols/code/sh-virtual.yaml", TestCase: &codeSnippet{}, DisableOn: func() bool { return !osutils.IsLinux() || isCodeDisabled() || !hasAnyExecutable("docker", "podman") }, Serial: true},
|
|
{Path: "protocols/code/py-virtual.yaml", TestCase: &codeSnippet{}, DisableOn: func() bool { return !osutils.IsLinux() || isCodeDisabled() || !hasAnyExecutable("docker", "podman") }, Serial: true},
|
|
{Path: "protocols/code/pwsh-echo.yaml", TestCase: &codeSnippet{}, DisableOn: func() bool { return isCodeDisabled() || !hasAnyExecutable("pwsh", "powershell", "powershell.exe") }},
|
|
}
|
|
|
|
const (
|
|
testCertFile = "protocols/keys/ci.crt"
|
|
testKeyFile = "protocols/keys/ci-private-key.pem"
|
|
)
|
|
|
|
var testcertpath = ""
|
|
|
|
func ensureSignedCodeTemplates() error {
|
|
if isCodeDisabled() {
|
|
return nil
|
|
}
|
|
signedCodeTemplates.Do(func() {
|
|
previousWD, err := os.Getwd()
|
|
if err != nil {
|
|
signedCodeTemplatesErr = err
|
|
return
|
|
}
|
|
if err := os.Chdir(suite.fixturesDir); err != nil {
|
|
signedCodeTemplatesErr = err
|
|
return
|
|
}
|
|
defer func() {
|
|
if chdirErr := os.Chdir(previousWD); chdirErr != nil && signedCodeTemplatesErr == nil {
|
|
signedCodeTemplatesErr = chdirErr
|
|
}
|
|
}()
|
|
|
|
templates.TemplateSignerLFA()
|
|
|
|
certPath := fixturePath(testCertFile)
|
|
keyPath := fixturePath(testKeyFile)
|
|
testcertpath = certPath
|
|
|
|
tsigner, err := signer.NewTemplateSignerFromFiles(certPath, keyPath)
|
|
if err != nil {
|
|
signedCodeTemplatesErr = err
|
|
return
|
|
}
|
|
|
|
templatesToSign := []string{
|
|
"workflow/code-template-1.yaml",
|
|
"workflow/code-template-2.yaml",
|
|
}
|
|
for _, v := range codeTestCases {
|
|
if v.DisableOn != nil && v.DisableOn() {
|
|
continue
|
|
}
|
|
if _, ok := v.TestCase.(*unsignedCode); ok {
|
|
continue
|
|
}
|
|
if _, ok := v.TestCase.(*codePyNoSig); ok {
|
|
continue
|
|
}
|
|
templatesToSign = append(templatesToSign, v.Path)
|
|
}
|
|
for _, templatePath := range templatesToSign {
|
|
if err := templates.SignTemplate(tsigner, fixturePath(templatePath)); err != nil {
|
|
signedCodeTemplatesErr = err
|
|
return
|
|
}
|
|
}
|
|
})
|
|
return signedCodeTemplatesErr
|
|
}
|
|
|
|
func getEnvValues() []string {
|
|
return []string{
|
|
signer.CertEnvVarName + "=" + testcertpath,
|
|
}
|
|
}
|
|
|
|
type codeSnippet struct{}
|
|
|
|
// Execute executes a test case and returns an error if occurred
|
|
func (h *codeSnippet) Execute(filePath string) error {
|
|
results, err := testutils.RunNucleiArgsWithEnvAndGetResults(debug, getEnvValues(), "-t", filePath, "-u", "input", "-code")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return expectResultsCount(results, 1)
|
|
}
|
|
|
|
type codePreCondition struct{}
|
|
|
|
// Execute executes a test case and returns an error if occurred
|
|
func (h *codePreCondition) Execute(filePath string) error {
|
|
results, err := testutils.RunNucleiArgsWithEnvAndGetResults(debug, getEnvValues(), "-t", filePath, "-u", "input", "-code", "-esc")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if osutils.IsLinux() {
|
|
return expectResultsCount(results, 1)
|
|
} else {
|
|
return expectResultsCount(results, 0)
|
|
|
|
}
|
|
}
|
|
|
|
type codeFile struct{}
|
|
|
|
// Execute executes a test case and returns an error if occurred
|
|
func (h *codeFile) Execute(filePath string) error {
|
|
results, err := testutils.RunNucleiArgsWithEnvAndGetResults(debug, getEnvValues(), "-t", filePath, "-u", "input", "-code")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return expectResultsCount(results, 1)
|
|
}
|
|
|
|
type codeEnvVar struct{}
|
|
|
|
// Execute executes a test case and returns an error if occurred
|
|
func (h *codeEnvVar) Execute(filePath string) error {
|
|
results, err := testutils.RunNucleiArgsWithEnvAndGetResults(debug, getEnvValues(), "-t", filePath, "-u", "input", "-V", "baz=baz", "-code")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return expectResultsCount(results, 1)
|
|
}
|
|
|
|
type unsignedCode struct{}
|
|
|
|
// Execute executes a test case and returns an error if occurred
|
|
func (h *unsignedCode) Execute(filePath string) error {
|
|
results, err := testutils.RunNucleiArgsWithEnvAndGetResults(debug, getEnvValues(), "-t", filePath, "-u", "input", "-code")
|
|
|
|
// should error out
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
// this point should never be reached
|
|
return errors.Join(expectResultsCount(results, 1), errors.New("unsigned template was executed"))
|
|
}
|
|
|
|
type codePyNoSig struct{}
|
|
|
|
// Execute executes a test case and returns an error if occurred
|
|
func (h *codePyNoSig) Execute(filePath string) error {
|
|
results, err := testutils.RunNucleiArgsWithEnvAndGetResults(debug, getEnvValues(), "-t", filePath, "-u", "input", "-code")
|
|
|
|
// should error out
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
// this point should never be reached
|
|
return errors.Join(expectResultsCount(results, 1), errors.New("unsigned template was executed"))
|
|
}
|