Tarun Koyalwar c35162c8ef
nuclei v3 bug fixes (#4176)
* store and generate signer keys

* fix trailing newline in code_response

* fix formatting and update error string

* fix integration test

* fix rsaSigned code integration test

* bug fixes , docs and more

* bump go -> 1.21

* use 'response' as default part in code templates

* disable sourcemaps for all js runtimes

* disable eval function

* rewrite file validation in sandbox mode

* sandbox file read improvements + minor refactor

* refactor sign and verify logic

* fix panic and missing id in code protocol

* disable re-signing code protocol templates

* fix code resigning in tests

* allow -lfa in test for signing templates

* start index from 1 in flow and multiproto

* remove testfiles

* add python in integration test

* update code protocol docs

* add python engine in template

* rework template signer

* fix integration test and more

* reworked template signer

* fix lint error

* display signature stats

* update docs

* add user fragment to signature

* use md5 to generate fragment

* update docs with code re-sign

* misc updates

* public crt update

* remove workflow info statement

* fix printing issues

* refactor preprocessor logic

* remove debug statement

* fix failing example test

* go mod tidy

---------

Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com>
Co-authored-by: Sandeep Singh <sandeep@projectdiscovery.io>
2023-10-13 13:17:27 +05:30

141 lines
3.8 KiB
Go

package main
import (
"errors"
"log"
"path/filepath"
osutils "github.com/projectdiscovery/utils/os"
"github.com/projectdiscovery/nuclei/v2/pkg/templates"
"github.com/projectdiscovery/nuclei/v2/pkg/templates/signer"
"github.com/projectdiscovery/nuclei/v2/pkg/testutils"
)
var codeTestCases = []TestCaseInfo{
{Path: "protocols/code/py-snippet.yaml", TestCase: &codeSnippet{}},
{Path: "protocols/code/py-file.yaml", TestCase: &codeFile{}},
{Path: "protocols/code/py-env-var.yaml", TestCase: &codeEnvVar{}},
{Path: "protocols/code/unsigned.yaml", TestCase: &unsignedCode{}},
{Path: "protocols/code/py-nosig.yaml", TestCase: &codePyNoSig{}},
{Path: "protocols/code/py-interactsh.yaml", TestCase: &codeSnippet{}},
{Path: "protocols/code/ps1-snippet.yaml", TestCase: &codeSnippet{}, DisableOn: func() bool { return !osutils.IsWindows() }},
}
const (
testCertFile = "protocols/keys/ci.crt"
testKeyFile = "protocols/keys/ci-private-key.pem"
)
var testcertpath = ""
func init() {
// allow local file access to load content of file references in template
// in order to sign them for testing purposes
templates.TemplateSignerLFA()
tsigner, err := signer.NewTemplateSignerFromFiles(testCertFile, testKeyFile)
if err != nil {
panic(err)
}
testcertpath, _ = filepath.Abs(testCertFile)
for _, v := range codeTestCases {
templatePath := v.Path
testCase := v.TestCase
if v.DisableOn != nil && v.DisableOn() {
// skip ps1 test case on non-windows platforms
continue
}
templatePath, err := filepath.Abs(templatePath)
if err != nil {
panic(err)
}
// skip
// - unsigned test cases
if _, ok := testCase.(*unsignedCode); ok {
continue
}
if _, ok := testCase.(*codePyNoSig); ok {
continue
}
if err := templates.SignTemplate(tsigner, templatePath); err != nil {
log.Fatalf("Could not sign template %v got: %s\n", templatePath, err)
}
}
}
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")
if err != nil {
return err
}
return expectResultsCount(results, 1)
}
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")
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")
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")
// 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")
// 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"))
}