From 7001edca12d60e7c24650a6c07f747573600d2f9 Mon Sep 17 00:00:00 2001 From: Kartikey Semwal Date: Thu, 15 Aug 2024 22:44:22 +0530 Subject: [PATCH 1/6] feat: responses saving in output folder (for -sr / -srd) and printing in console as json output (for -json) --- cmd/cariddi/main.go | 45 ++++++++++++++++++++-------------------- internal/file/file.go | 39 ++++++++++++++++++++++------------ pkg/crawler/colly.go | 15 +++++++++++--- pkg/crawler/options.go | 41 ++++++++++++++++++------------------ pkg/input/flags.go | 5 +++++ pkg/output/jsonl.go | 3 +++ pkg/output/jsonl_test.go | 21 ++++++++++++++++++- pkg/output/output.go | 33 ++++++++++++++++++++--------- pkg/output/responses.go | 26 +++++++++++------------ 9 files changed, 146 insertions(+), 82 deletions(-) diff --git a/cmd/cariddi/main.go b/cmd/cariddi/main.go index fc4d9bc..cff793e 100644 --- a/cmd/cariddi/main.go +++ b/cmd/cariddi/main.go @@ -69,25 +69,26 @@ func main() { // Setup the config according to the flags that were // passed via the CLI config := &crawler.Scan{ - Delay: flags.Delay, - Concurrency: flags.Concurrency, - Ignore: flags.Ignore, - IgnoreTxt: flags.IgnoreTXT, - Cache: flags.Cache, - JSON: flags.JSON, - Timeout: flags.Timeout, - Intensive: flags.Intensive, - Rua: flags.Rua, - Proxy: flags.Proxy, - SecretsFlag: flags.Secrets, - Plain: flags.Plain, - EndpointsFlag: flags.Endpoints, - FileType: flags.Extensions, - ErrorsFlag: flags.Errors, - InfoFlag: flags.Info, - Debug: flags.Debug, - UserAgent: flags.UserAgent, - StoreResp: flags.StoreResp, + Delay: flags.Delay, + Concurrency: flags.Concurrency, + Ignore: flags.Ignore, + IgnoreTxt: flags.IgnoreTXT, + Cache: flags.Cache, + JSON: flags.JSON, + Timeout: flags.Timeout, + Intensive: flags.Intensive, + Rua: flags.Rua, + Proxy: flags.Proxy, + SecretsFlag: flags.Secrets, + Plain: flags.Plain, + EndpointsFlag: flags.Endpoints, + FileType: flags.Extensions, + ErrorsFlag: flags.Errors, + InfoFlag: flags.Info, + Debug: flags.Debug, + UserAgent: flags.UserAgent, + StoreResp: flags.StoreResp, + StoredRespPath: flags.StoredRespDir, } // Read the targets from standard input. @@ -118,18 +119,18 @@ func main() { // Create output files if needed (txt / html). config.Txt = "" if flags.TXTout != "" { - config.Txt = fileUtils.CreateOutputFile(flags.TXTout, "results", "txt") + config.Txt = fileUtils.CreateOutputFile(flags.TXTout, "results", "txt", config.StoredRespPath) } var ResultHTML = "" if flags.HTMLout != "" { - ResultHTML = fileUtils.CreateOutputFile(flags.HTMLout, "", "html") + ResultHTML = fileUtils.CreateOutputFile(flags.HTMLout, "", "html", config.StoredRespPath) output.BannerHTML(ResultHTML) output.HeaderHTML("Results", ResultHTML) } if config.StoreResp { - fileUtils.CreateIndexOutputFile("index.responses.txt") + fileUtils.CreateIndexOutputFile("index.responses.txt", config.StoredRespPath) } // Read headers if needed diff --git a/internal/file/file.go b/internal/file/file.go index a0ed364..547a810 100644 --- a/internal/file/file.go +++ b/internal/file/file.go @@ -42,11 +42,16 @@ const ( Permission0644 = 0644 ) +// constant defined in output.go as well, for circular dependency +const ( + CariddiOutputFolder = "output-cariddi" +) + // CreateOutputFolder creates the output folder // If it fails exits with an error message. -func CreateOutputFolder() { +func CreateOutputFolder(outputDir string) { // Create a folder/directory at a full qualified path - err := os.Mkdir("output-cariddi", Permission0755) + err := os.MkdirAll(outputDir, Permission0755) if err != nil { fmt.Println("Can't create output folder.") os.Exit(1) @@ -56,9 +61,9 @@ func CreateOutputFolder() { // CreateHostOutputFolder creates the host output folder // for the HTTP responses. // If it fails exits with an error message. -func CreateHostOutputFolder(host string) { +func CreateHostOutputFolder(host string, outputDir string) { // Create a folder/directory at a full qualified path - err := os.MkdirAll(filepath.Join("output-cariddi", host), Permission0755) + err := os.MkdirAll(filepath.Join(outputDir, host), Permission0755) if err != nil { fmt.Println("Can't create host output folder.") os.Exit(1) @@ -71,21 +76,25 @@ func CreateHostOutputFolder(host string) { // already exists, if yes asks the user if cariddi has to overwrite it; // if no cariddi creates it. // Whenever an instruction fails, it exits with an error message. -func CreateOutputFile(target string, subcommand string, format string) string { +func CreateOutputFile(target string, subcommand string, format string, outputDir string) string { + if outputDir == "" { + outputDir = CariddiOutputFolder + } + target = ReplaceBadCharacterOutput(target) var filename string if subcommand != "" { - filename = filepath.Join("output-cariddi", target+"."+subcommand+"."+format) + filename = filepath.Join(outputDir, target+"."+subcommand+"."+format) } else { - filename = filepath.Join("output-cariddi", target+"."+format) + filename = filepath.Join(outputDir, target+"."+format) } _, err := os.Stat(filename) if os.IsNotExist(err) { - if _, err := os.Stat("output-cariddi/"); os.IsNotExist(err) { - CreateOutputFolder() + if _, err := os.Stat(outputDir + "/"); os.IsNotExist(err) { + CreateOutputFolder(outputDir) } // If the file doesn't exist, create it. f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, Permission0644) @@ -119,15 +128,19 @@ func CreateOutputFile(target string, subcommand string, format string) string { // It creates the output folder if needed, then checks if the index output file // already exists, if no cariddi creates it. // Whenever an instruction fails, it exits with an error message. -func CreateIndexOutputFile(filename string) { +func CreateIndexOutputFile(filename string, outputDir string) { + if outputDir == "" { + outputDir = CariddiOutputFolder + } + _, err := os.Stat(filename) if os.IsNotExist(err) { - if _, err := os.Stat("output-cariddi/"); os.IsNotExist(err) { - CreateOutputFolder() + if _, err := os.Stat(outputDir + "/"); os.IsNotExist(err) { + CreateOutputFolder(outputDir) } // If the file doesn't exist, create it. - filename = filepath.Join("output-cariddi", filename) + filename = filepath.Join(outputDir, filename) f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, Permission0644) if err != nil { diff --git a/pkg/crawler/colly.go b/pkg/crawler/colly.go index 4585f36..5ddcb06 100644 --- a/pkg/crawler/colly.go +++ b/pkg/crawler/colly.go @@ -134,8 +134,17 @@ func New(scan *Scan) *Results { fmt.Println(r.Request.URL) } - if scan.StoreResp { - err := output.StoreHTTPResponse(r) + var outputPath string + + if scan.StoreResp || len(scan.StoredRespPath) > 0 { + outputDir := scan.StoredRespPath + + if outputDir == "" { + outputDir = output.CariddiOutputFolder + } + + var err error + outputPath, err = output.StoreHTTPResponse(r, outputDir) if err != nil { log.Println(err) } @@ -193,7 +202,7 @@ func New(scan *Scan) *Results { if scan.JSON { jsonOutput, err := output.GetJSONString( - r, secrets, parameters, filetype, errors, infos, + r, secrets, parameters, filetype, errors, infos, outputPath, ) if err == nil { diff --git a/pkg/crawler/options.go b/pkg/crawler/options.go index 73ab694..31cb6a8 100644 --- a/pkg/crawler/options.go +++ b/pkg/crawler/options.go @@ -39,26 +39,27 @@ type Results struct { type Scan struct { // Flags - Cache bool - Debug bool - EndpointsFlag bool - ErrorsFlag bool - InfoFlag bool - Intensive bool - Plain bool - Rua bool - SecretsFlag bool - Ignore string - IgnoreTxt string - JSON bool - HTML string - Proxy string - Target string - Txt string - UserAgent string - FileType int - Headers map[string]string - StoreResp bool + Cache bool + Debug bool + EndpointsFlag bool + ErrorsFlag bool + InfoFlag bool + Intensive bool + Plain bool + Rua bool + SecretsFlag bool + Ignore string + IgnoreTxt string + JSON bool + HTML string + Proxy string + Target string + Txt string + UserAgent string + FileType int + Headers map[string]string + StoreResp bool + StoredRespPath string // Settings Concurrency int diff --git a/pkg/input/flags.go b/pkg/input/flags.go index 3848d7f..e9edb19 100644 --- a/pkg/input/flags.go +++ b/pkg/input/flags.go @@ -94,6 +94,8 @@ type Input struct { UserAgent string // StoreResp stores HTTP responses. StoreResp bool + // StoredRespDir stores HTTP responses to the directory provided. + StoredRespDir string } // ScanFlag defines all the options taken @@ -142,6 +144,8 @@ func ScanFlag() Input { storeRespPtr := flag.Bool("sr", false, "Store HTTP responses.") + storedRespDirPtr := flag.String("srd", "", "Stores HTTP responses to the directory provided.") + flag.Parse() result := Input{ @@ -173,6 +177,7 @@ func ScanFlag() Input { *debugPtr, *userAgentPtr, *storeRespPtr, + *storedRespDirPtr, } return result diff --git a/pkg/output/jsonl.go b/pkg/output/jsonl.go index e54d7d4..79b6ecf 100644 --- a/pkg/output/jsonl.go +++ b/pkg/output/jsonl.go @@ -44,6 +44,7 @@ type JSONData struct { ContentType string `json:"content_type,omitempty"` ContentLength int `json:"content_length,omitempty"` Matches *MatcherResults `json:"matches,omitempty"` + OutputPath string `json:"output_path,omitempty"` // Host string `json:"host"` # TODO: Available in Colly 2.x } @@ -67,6 +68,7 @@ func GetJSONString( filetype *scanner.FileType, errors []scanner.ErrorMatched, infos []scanner.InfoMatched, + outputPath string, ) ([]byte, error) { // Parse response headers headers := r.Headers @@ -136,6 +138,7 @@ func GetJSONString( ContentType: contentType, ContentLength: contentLength, Matches: matcherResults, + OutputPath: outputPath, // Host: "", // TODO } diff --git a/pkg/output/jsonl_test.go b/pkg/output/jsonl_test.go index 83a5683..fdee122 100644 --- a/pkg/output/jsonl_test.go +++ b/pkg/output/jsonl_test.go @@ -113,6 +113,7 @@ func TestJSONOutput(t *testing.T) { errors []scanner.ErrorMatched infos []scanner.InfoMatched want string + outputPath string }{ { name: "test_all_findings", @@ -123,6 +124,7 @@ func TestJSONOutput(t *testing.T) { errors: errors, infos: infos, want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"filetype":{"extension":"pdf","severity":7},"parameters":[{"name":"id","attacks":[]}],"errors":[{"name":"MySQL error","match":"it is a MySQL error happening"}],"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}],"secrets":[{"name":"mysecret","match":"it's a random day for my secret regex to be found"}]}}`, //nolint:lll + outputPath: "C:\\testDir1\\testDir2", }, { name: "test_all_findings_nocontent", @@ -133,6 +135,7 @@ func TestJSONOutput(t *testing.T) { errors: errors, infos: infos, want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"matches":{"filetype":{"extension":"pdf","severity":7},"parameters":[{"name":"id","attacks":[]}],"errors":[{"name":"MySQL error","match":"it is a MySQL error happening"}],"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}],"secrets":[{"name":"mysecret","match":"it's a random day for my secret regex to be found"}]}}`, //nolint:lll + outputPath: "C:\\testDir1\\testDir2", }, { name: "test_no_findings", @@ -143,6 +146,7 @@ func TestJSONOutput(t *testing.T) { errors: []scanner.ErrorMatched{}, infos: []scanner.InfoMatched{}, want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128}`, //nolint: all + outputPath: "C:\\testDir1\\testDir2", }, { name: "test_only_secrets", @@ -153,6 +157,7 @@ func TestJSONOutput(t *testing.T) { errors: []scanner.ErrorMatched{}, infos: []scanner.InfoMatched{}, want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"secrets":[{"name":"mysecret","match":"it's a random day for my secret regex to be found"}]}}`, //nolint:lll + outputPath: "C:\\testDir1\\testDir2", }, { name: "test_only_params", @@ -163,6 +168,7 @@ func TestJSONOutput(t *testing.T) { errors: []scanner.ErrorMatched{}, infos: []scanner.InfoMatched{}, want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"parameters":[{"name":"id","attacks":[]}]}}`, //nolint:lll + outputPath: "C:\\testDir1\\testDir2", }, { name: "test_only_errors", @@ -173,6 +179,7 @@ func TestJSONOutput(t *testing.T) { errors: errors, infos: []scanner.InfoMatched{}, want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"errors":[{"name":"MySQL error","match":"it is a MySQL error happening"}]}}`, //nolint:lll + outputPath: "C:\\testDir1\\testDir2", }, { name: "test_only_infos", @@ -183,12 +190,24 @@ func TestJSONOutput(t *testing.T) { errors: []scanner.ErrorMatched{}, infos: infos, want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}]}}`, //nolint:lll + outputPath: "C:\\testDir1\\testDir2", + }, + { + name: "test_no_outputPath", + r: resp, + secrets: []scanner.SecretMatched{}, + parameters: []scanner.Parameter{}, + filetype: &scanner.FileType{}, + errors: []scanner.ErrorMatched{}, + infos: infos, + want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}]}}`, //nolint:lll + outputPath: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got, _ := output.GetJSONString(tt.r, tt.secrets, tt.parameters, tt.filetype, tt.errors, tt.infos); !reflect.DeepEqual(string(got), tt.want) { //nolint:lll + if got, _ := output.GetJSONString(tt.r, tt.secrets, tt.parameters, tt.filetype, tt.errors, tt.infos, tt.outputPath); !reflect.DeepEqual(string(got), tt.want) { //nolint:lll t.Errorf("GetJSONString\n%v", string(got)) t.Errorf("want\n%v", tt.want) } diff --git a/pkg/output/output.go b/pkg/output/output.go index ba1b12f..76dd76b 100644 --- a/pkg/output/output.go +++ b/pkg/output/output.go @@ -36,6 +36,7 @@ import ( "github.com/edoardottt/cariddi/pkg/scanner" ) +// constant defined in file.go as well, for circular dependency const ( CariddiOutputFolder = "output-cariddi" ) @@ -52,24 +53,30 @@ func PrintSimpleOutput(out []string) { func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.SecretMatched, finalEndpoints []scanner.EndpointMatched, finalExtensions []scanner.FileTypeMatched, finalErrors []scanner.ErrorMatched, finalInfos []scanner.InfoMatched) { - exists, err := fileUtils.ElementExists(CariddiOutputFolder) + + outputDir := CariddiOutputFolder + if flags.StoredRespDir != "" { + outputDir = flags.StoredRespDir + } + + exists, err := fileUtils.ElementExists(outputDir) if err != nil { fmt.Println("Error while creating the output directory.") os.Exit(1) } if !exists { - fileUtils.CreateOutputFolder() + fileUtils.CreateOutputFolder(outputDir) } - ResultFilename := fileUtils.CreateOutputFile(flags.TXTout, "results", "txt") + ResultFilename := fileUtils.CreateOutputFile(flags.TXTout, "results", "txt", outputDir) for _, elem := range finalResults { AppendOutputToTxt(elem, ResultFilename) } // if secrets flag enabled save also secrets if flags.Secrets { - SecretFilename := fileUtils.CreateOutputFile(flags.TXTout, "secrets", "txt") + SecretFilename := fileUtils.CreateOutputFile(flags.TXTout, "secrets", "txt", outputDir) for _, elem := range finalSecret { AppendOutputToTxt(fmt.Sprintf("%s - %s in %s", elem.Secret.Name, elem.Match, elem.URL), SecretFilename) } @@ -77,7 +84,7 @@ func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.S // if endpoints flag enabled save also endpoints if flags.Endpoints { - EndpointFilename := fileUtils.CreateOutputFile(flags.TXTout, "endpoints", "txt") + EndpointFilename := fileUtils.CreateOutputFile(flags.TXTout, "endpoints", "txt", outputDir) for _, elem := range finalEndpoints { for _, parameter := range elem.Parameters { @@ -96,7 +103,7 @@ func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.S // if extensions flag enabled save also secrets if 1 <= flags.Extensions && flags.Extensions <= 7 { - ExtensionsFilename := fileUtils.CreateOutputFile(flags.TXTout, "extensions", "txt") + ExtensionsFilename := fileUtils.CreateOutputFile(flags.TXTout, "extensions", "txt", outputDir) for _, elem := range finalExtensions { AppendOutputToTxt(fmt.Sprintf("%s in %s", elem.Filetype.Extension, elem.URL), ExtensionsFilename) } @@ -104,7 +111,7 @@ func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.S // if errors flag enabled save also errors if flags.Errors { - ErrorsFilename := fileUtils.CreateOutputFile(flags.TXTout, "errors", "txt") + ErrorsFilename := fileUtils.CreateOutputFile(flags.TXTout, "errors", "txt", outputDir) for _, elem := range finalErrors { AppendOutputToTxt(fmt.Sprintf("%s - %s in %s", elem.Error.ErrorName, elem.Match, elem.URL), ErrorsFilename) } @@ -112,7 +119,7 @@ func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.S // if info flag enabled save also infos if flags.Info { - InfosFilename := fileUtils.CreateOutputFile(flags.TXTout, "info", "txt") + InfosFilename := fileUtils.CreateOutputFile(flags.TXTout, "info", "txt", outputDir) for _, elem := range finalInfos { AppendOutputToTxt(fmt.Sprintf("%s - %s in %s", elem.Info.Name, elem.Match, elem.URL), InfosFilename) } @@ -124,7 +131,13 @@ func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.S func HTMLOutput(flags input.Input, resultFilename string, finalResults []string, finalSecret []scanner.SecretMatched, finalEndpoints []scanner.EndpointMatched, finalExtensions []scanner.FileTypeMatched, finalErrors []scanner.ErrorMatched, finalInfos []scanner.InfoMatched) { - exists, err := fileUtils.ElementExists(CariddiOutputFolder) + + outputDir := CariddiOutputFolder + if flags.StoredRespDir != "" { + outputDir = flags.StoredRespDir + } + + exists, err := fileUtils.ElementExists(outputDir) if err != nil { fmt.Println("Error while creating the output directory.") @@ -132,7 +145,7 @@ func HTMLOutput(flags input.Input, resultFilename string, finalResults []string, } if !exists { - fileUtils.CreateOutputFolder() + fileUtils.CreateOutputFolder(outputDir) } HeaderHTML("Results found", resultFilename) diff --git a/pkg/output/responses.go b/pkg/output/responses.go index fc3decb..81efa40 100644 --- a/pkg/output/responses.go +++ b/pkg/output/responses.go @@ -118,8 +118,8 @@ func getResponseFileName(folder, url string) string { // UpdateIndex updates the index file with the // correct information linking to HTTP responses files. // If it fails returns an error. -func UpdateIndex(resp *colly.Response) error { - index, err := os.OpenFile(filepath.Join(CariddiOutputFolder, index), +func UpdateIndex(resp *colly.Response, outputDir string) error { + index, err := os.OpenFile(filepath.Join(outputDir, index), os.O_APPEND|os.O_WRONLY, fileUtils.Permission0644) if err != nil { @@ -130,7 +130,7 @@ func UpdateIndex(resp *colly.Response) error { builder := &bytes.Buffer{} - builder.WriteString(getResponseFileName(filepath.Join(CariddiOutputFolder, resp.Request.URL.Host), + builder.WriteString(getResponseFileName(filepath.Join(outputDir, resp.Request.URL.Host), resp.Request.URL.String())) builder.WriteRune(' ') builder.WriteString(resp.Request.URL.String()) @@ -148,27 +148,27 @@ func UpdateIndex(resp *colly.Response) error { // WriteHTTPResponse creates an HTTP response output file and // writes the HTTP response inside it. // If it fails returns an error. -func WriteHTTPResponse(inputURL *url.URL, response []byte) error { - file := getResponseFileName(filepath.Join(CariddiOutputFolder, inputURL.Host), inputURL.String()) +func WriteHTTPResponse(inputURL *url.URL, response []byte, outputDir string) (string, error) { + file := getResponseFileName(filepath.Join(outputDir, inputURL.Host), inputURL.String()) outFile, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY, fileUtils.Permission0644) if err != nil { - return err + return file, err } if _, writeErr := outFile.Write(response); writeErr != nil { - return ErrHTTPResp + return file, ErrHTTPResp } - return nil + return file, nil } // StoreHTTPResponse stores an HTTP response in a file. // If it fails returns an error. -func StoreHTTPResponse(r *colly.Response) error { - fileUtils.CreateHostOutputFolder(r.Request.URL.Host) +func StoreHTTPResponse(r *colly.Response, outputDir string) (string, error) { + fileUtils.CreateHostOutputFolder(r.Request.URL.Host, outputDir) - err := UpdateIndex(r) + err := UpdateIndex(r, outputDir) if err != nil { log.Println(err) } @@ -178,10 +178,10 @@ func StoreHTTPResponse(r *colly.Response) error { log.Println(err) } - err = WriteHTTPResponse(r.Request.URL, response) + outputPath, err := WriteHTTPResponse(r.Request.URL, response, outputDir) if err != nil { log.Println(err) } - return nil + return outputPath, nil } From 6a6bfb4ccfeee96196e79dd3da1e8da4bb3e4023 Mon Sep 17 00:00:00 2001 From: Kartikey Semwal Date: Sat, 17 Aug 2024 16:23:21 +0530 Subject: [PATCH 2/6] refactoring the code changes --- cmd/cariddi/main.go | 55 +++++++++++++++++++++++------------------- internal/file/file.go | 13 ---------- pkg/crawler/colly.go | 10 ++------ pkg/crawler/options.go | 42 ++++++++++++++++---------------- pkg/output/output.go | 14 ++--------- 5 files changed, 55 insertions(+), 79 deletions(-) diff --git a/cmd/cariddi/main.go b/cmd/cariddi/main.go index cff793e..5481860 100644 --- a/cmd/cariddi/main.go +++ b/cmd/cariddi/main.go @@ -69,26 +69,31 @@ func main() { // Setup the config according to the flags that were // passed via the CLI config := &crawler.Scan{ - Delay: flags.Delay, - Concurrency: flags.Concurrency, - Ignore: flags.Ignore, - IgnoreTxt: flags.IgnoreTXT, - Cache: flags.Cache, - JSON: flags.JSON, - Timeout: flags.Timeout, - Intensive: flags.Intensive, - Rua: flags.Rua, - Proxy: flags.Proxy, - SecretsFlag: flags.Secrets, - Plain: flags.Plain, - EndpointsFlag: flags.Endpoints, - FileType: flags.Extensions, - ErrorsFlag: flags.Errors, - InfoFlag: flags.Info, - Debug: flags.Debug, - UserAgent: flags.UserAgent, - StoreResp: flags.StoreResp, - StoredRespPath: flags.StoredRespDir, + Delay: flags.Delay, + Concurrency: flags.Concurrency, + Ignore: flags.Ignore, + IgnoreTxt: flags.IgnoreTXT, + Cache: flags.Cache, + JSON: flags.JSON, + Timeout: flags.Timeout, + Intensive: flags.Intensive, + Rua: flags.Rua, + Proxy: flags.Proxy, + SecretsFlag: flags.Secrets, + Plain: flags.Plain, + EndpointsFlag: flags.Endpoints, + FileType: flags.Extensions, + ErrorsFlag: flags.Errors, + InfoFlag: flags.Info, + Debug: flags.Debug, + UserAgent: flags.UserAgent, + StoreResp: flags.StoreResp, + } + + config.OutputDir = output.CariddiOutputFolder + if flags.StoredRespDir != "" { + config.OutputDir = flags.StoredRespDir + config.StoreResp = true } // Read the targets from standard input. @@ -119,18 +124,18 @@ func main() { // Create output files if needed (txt / html). config.Txt = "" if flags.TXTout != "" { - config.Txt = fileUtils.CreateOutputFile(flags.TXTout, "results", "txt", config.StoredRespPath) + config.Txt = fileUtils.CreateOutputFile(flags.TXTout, "results", "txt", config.OutputDir) } var ResultHTML = "" if flags.HTMLout != "" { - ResultHTML = fileUtils.CreateOutputFile(flags.HTMLout, "", "html", config.StoredRespPath) + ResultHTML = fileUtils.CreateOutputFile(flags.HTMLout, "", "html", config.OutputDir) output.BannerHTML(ResultHTML) output.HeaderHTML("Results", ResultHTML) } if config.StoreResp { - fileUtils.CreateIndexOutputFile("index.responses.txt", config.StoredRespPath) + fileUtils.CreateIndexOutputFile("index.responses.txt", config.OutputDir) } // Read headers if needed @@ -168,13 +173,13 @@ func main() { // IF TXT OUTPUT > if flags.TXTout != "" { output.TxtOutput(flags, finalResults, finalSecret, finalEndpoints, - finalExtensions, finalErrors, finalInfos) + finalExtensions, finalErrors, finalInfos, config.OutputDir) } // IF HTML OUTPUT > if flags.HTMLout != "" { output.HTMLOutput(flags, ResultHTML, finalResults, finalSecret, - finalEndpoints, finalExtensions, finalErrors, finalInfos) + finalEndpoints, finalExtensions, finalErrors, finalInfos, config.OutputDir) } // If needed print secrets. diff --git a/internal/file/file.go b/internal/file/file.go index 547a810..4c46cca 100644 --- a/internal/file/file.go +++ b/internal/file/file.go @@ -42,11 +42,6 @@ const ( Permission0644 = 0644 ) -// constant defined in output.go as well, for circular dependency -const ( - CariddiOutputFolder = "output-cariddi" -) - // CreateOutputFolder creates the output folder // If it fails exits with an error message. func CreateOutputFolder(outputDir string) { @@ -77,10 +72,6 @@ func CreateHostOutputFolder(host string, outputDir string) { // if no cariddi creates it. // Whenever an instruction fails, it exits with an error message. func CreateOutputFile(target string, subcommand string, format string, outputDir string) string { - if outputDir == "" { - outputDir = CariddiOutputFolder - } - target = ReplaceBadCharacterOutput(target) var filename string @@ -129,10 +120,6 @@ func CreateOutputFile(target string, subcommand string, format string, outputDir // already exists, if no cariddi creates it. // Whenever an instruction fails, it exits with an error message. func CreateIndexOutputFile(filename string, outputDir string) { - if outputDir == "" { - outputDir = CariddiOutputFolder - } - _, err := os.Stat(filename) if os.IsNotExist(err) { diff --git a/pkg/crawler/colly.go b/pkg/crawler/colly.go index 5ddcb06..8dd5b87 100644 --- a/pkg/crawler/colly.go +++ b/pkg/crawler/colly.go @@ -136,15 +136,9 @@ func New(scan *Scan) *Results { var outputPath string - if scan.StoreResp || len(scan.StoredRespPath) > 0 { - outputDir := scan.StoredRespPath - - if outputDir == "" { - outputDir = output.CariddiOutputFolder - } - + if scan.StoreResp { var err error - outputPath, err = output.StoreHTTPResponse(r, outputDir) + outputPath, err = output.StoreHTTPResponse(r, scan.OutputDir) if err != nil { log.Println(err) } diff --git a/pkg/crawler/options.go b/pkg/crawler/options.go index 31cb6a8..af636c9 100644 --- a/pkg/crawler/options.go +++ b/pkg/crawler/options.go @@ -39,27 +39,27 @@ type Results struct { type Scan struct { // Flags - Cache bool - Debug bool - EndpointsFlag bool - ErrorsFlag bool - InfoFlag bool - Intensive bool - Plain bool - Rua bool - SecretsFlag bool - Ignore string - IgnoreTxt string - JSON bool - HTML string - Proxy string - Target string - Txt string - UserAgent string - FileType int - Headers map[string]string - StoreResp bool - StoredRespPath string + Cache bool + Debug bool + EndpointsFlag bool + ErrorsFlag bool + InfoFlag bool + Intensive bool + Plain bool + Rua bool + SecretsFlag bool + Ignore string + IgnoreTxt string + JSON bool + HTML string + Proxy string + Target string + Txt string + UserAgent string + FileType int + Headers map[string]string + StoreResp bool + OutputDir string // Settings Concurrency int diff --git a/pkg/output/output.go b/pkg/output/output.go index 76dd76b..6e803e4 100644 --- a/pkg/output/output.go +++ b/pkg/output/output.go @@ -52,12 +52,7 @@ func PrintSimpleOutput(out []string) { // Actually it manages everything related to TXT output. func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.SecretMatched, finalEndpoints []scanner.EndpointMatched, finalExtensions []scanner.FileTypeMatched, - finalErrors []scanner.ErrorMatched, finalInfos []scanner.InfoMatched) { - - outputDir := CariddiOutputFolder - if flags.StoredRespDir != "" { - outputDir = flags.StoredRespDir - } + finalErrors []scanner.ErrorMatched, finalInfos []scanner.InfoMatched, outputDir string) { exists, err := fileUtils.ElementExists(outputDir) if err != nil { @@ -130,12 +125,7 @@ func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.S // Actually it manages everything related to HTML output. func HTMLOutput(flags input.Input, resultFilename string, finalResults []string, finalSecret []scanner.SecretMatched, finalEndpoints []scanner.EndpointMatched, finalExtensions []scanner.FileTypeMatched, - finalErrors []scanner.ErrorMatched, finalInfos []scanner.InfoMatched) { - - outputDir := CariddiOutputFolder - if flags.StoredRespDir != "" { - outputDir = flags.StoredRespDir - } + finalErrors []scanner.ErrorMatched, finalInfos []scanner.InfoMatched, outputDir string) { exists, err := fileUtils.ElementExists(outputDir) From 3ad877851854aec1c481e4247db859de92068d6b Mon Sep 17 00:00:00 2001 From: Kartikey Semwal Date: Tue, 27 Aug 2024 19:52:15 +0530 Subject: [PATCH 3/6] fix: resolve linter and test case errors in workflow --- internal/file/file.go | 1 + pkg/crawler/colly.go | 1 + pkg/crawler/useragents.go | 3 ++- pkg/output/jsonl_test.go | 14 +++++++------- pkg/output/output.go | 4 +--- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/internal/file/file.go b/internal/file/file.go index 4c46cca..8768e37 100644 --- a/internal/file/file.go +++ b/internal/file/file.go @@ -161,6 +161,7 @@ func ReadFile(inputFile string) []string { for scanner.Scan() { text = append(text, scanner.Text()) } + file.Close() return text diff --git a/pkg/crawler/colly.go b/pkg/crawler/colly.go index 8dd5b87..5319fb3 100644 --- a/pkg/crawler/colly.go +++ b/pkg/crawler/colly.go @@ -139,6 +139,7 @@ func New(scan *Scan) *Results { if scan.StoreResp { var err error outputPath, err = output.StoreHTTPResponse(r, scan.OutputDir) + if err != nil { log.Println(err) } diff --git a/pkg/crawler/useragents.go b/pkg/crawler/useragents.go index ada2079..54385b1 100644 --- a/pkg/crawler/useragents.go +++ b/pkg/crawler/useragents.go @@ -151,7 +151,8 @@ func GenerateRandomUserAgent() string { source := rand.NewSource(time.Now().UnixNano()) rng := rand.New(source) - decision := rng.Intn(100) + const maxRandomValue = 100 + decision := rng.Intn(maxRandomValue) var ua string if decision%2 == 0 { diff --git a/pkg/output/jsonl_test.go b/pkg/output/jsonl_test.go index fdee122..fd8c387 100644 --- a/pkg/output/jsonl_test.go +++ b/pkg/output/jsonl_test.go @@ -123,7 +123,7 @@ func TestJSONOutput(t *testing.T) { filetype: filetype, errors: errors, infos: infos, - want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"filetype":{"extension":"pdf","severity":7},"parameters":[{"name":"id","attacks":[]}],"errors":[{"name":"MySQL error","match":"it is a MySQL error happening"}],"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}],"secrets":[{"name":"mysecret","match":"it's a random day for my secret regex to be found"}]}}`, //nolint:lll + want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"filetype":{"extension":"pdf","severity":7},"parameters":[{"name":"id","attacks":[]}],"errors":[{"name":"MySQL error","match":"it is a MySQL error happening"}],"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}],"secrets":[{"name":"mysecret","match":"it's a random day for my secret regex to be found"}]},"output_path":"C:\\testDir1\\testDir2"}`, //nolint:lll outputPath: "C:\\testDir1\\testDir2", }, { @@ -134,7 +134,7 @@ func TestJSONOutput(t *testing.T) { filetype: filetype, errors: errors, infos: infos, - want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"matches":{"filetype":{"extension":"pdf","severity":7},"parameters":[{"name":"id","attacks":[]}],"errors":[{"name":"MySQL error","match":"it is a MySQL error happening"}],"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}],"secrets":[{"name":"mysecret","match":"it's a random day for my secret regex to be found"}]}}`, //nolint:lll + want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"matches":{"filetype":{"extension":"pdf","severity":7},"parameters":[{"name":"id","attacks":[]}],"errors":[{"name":"MySQL error","match":"it is a MySQL error happening"}],"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}],"secrets":[{"name":"mysecret","match":"it's a random day for my secret regex to be found"}]},"output_path":"C:\\testDir1\\testDir2"}`, //nolint:lll outputPath: "C:\\testDir1\\testDir2", }, { @@ -145,7 +145,7 @@ func TestJSONOutput(t *testing.T) { filetype: &scanner.FileType{}, errors: []scanner.ErrorMatched{}, infos: []scanner.InfoMatched{}, - want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128}`, //nolint: all + want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"output_path":"C:\\testDir1\\testDir2"}`, //nolint: all outputPath: "C:\\testDir1\\testDir2", }, { @@ -156,7 +156,7 @@ func TestJSONOutput(t *testing.T) { filetype: &scanner.FileType{}, errors: []scanner.ErrorMatched{}, infos: []scanner.InfoMatched{}, - want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"secrets":[{"name":"mysecret","match":"it's a random day for my secret regex to be found"}]}}`, //nolint:lll + want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"secrets":[{"name":"mysecret","match":"it's a random day for my secret regex to be found"}]},"output_path":"C:\\testDir1\\testDir2"}`, //nolint:lll outputPath: "C:\\testDir1\\testDir2", }, { @@ -167,7 +167,7 @@ func TestJSONOutput(t *testing.T) { filetype: &scanner.FileType{}, errors: []scanner.ErrorMatched{}, infos: []scanner.InfoMatched{}, - want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"parameters":[{"name":"id","attacks":[]}]}}`, //nolint:lll + want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"parameters":[{"name":"id","attacks":[]}]},"output_path":"C:\\testDir1\\testDir2"}`, //nolint:lll outputPath: "C:\\testDir1\\testDir2", }, { @@ -178,7 +178,7 @@ func TestJSONOutput(t *testing.T) { filetype: &scanner.FileType{}, errors: errors, infos: []scanner.InfoMatched{}, - want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"errors":[{"name":"MySQL error","match":"it is a MySQL error happening"}]}}`, //nolint:lll + want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"errors":[{"name":"MySQL error","match":"it is a MySQL error happening"}]},"output_path":"C:\\testDir1\\testDir2"}`, //nolint:lll outputPath: "C:\\testDir1\\testDir2", }, { @@ -189,7 +189,7 @@ func TestJSONOutput(t *testing.T) { filetype: &scanner.FileType{}, errors: []scanner.ErrorMatched{}, infos: infos, - want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}]}}`, //nolint:lll + want: `{"url":"http://test.com.pdf?id=5","method":"GET","status_code":200,"words":1,"lines":1,"content_type":"application/pdf","content_length":128,"matches":{"infos":[{"name":"info1","match":"its my pleasure to inform you on this great day"}]},"output_path":"C:\\testDir1\\testDir2"}`, //nolint:lll outputPath: "C:\\testDir1\\testDir2", }, { diff --git a/pkg/output/output.go b/pkg/output/output.go index 6e803e4..92f553f 100644 --- a/pkg/output/output.go +++ b/pkg/output/output.go @@ -36,7 +36,7 @@ import ( "github.com/edoardottt/cariddi/pkg/scanner" ) -// constant defined in file.go as well, for circular dependency +// constant defined in file.go as well, redefining here for circular dependency. const ( CariddiOutputFolder = "output-cariddi" ) @@ -53,7 +53,6 @@ func PrintSimpleOutput(out []string) { func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.SecretMatched, finalEndpoints []scanner.EndpointMatched, finalExtensions []scanner.FileTypeMatched, finalErrors []scanner.ErrorMatched, finalInfos []scanner.InfoMatched, outputDir string) { - exists, err := fileUtils.ElementExists(outputDir) if err != nil { fmt.Println("Error while creating the output directory.") @@ -126,7 +125,6 @@ func TxtOutput(flags input.Input, finalResults []string, finalSecret []scanner.S func HTMLOutput(flags input.Input, resultFilename string, finalResults []string, finalSecret []scanner.SecretMatched, finalEndpoints []scanner.EndpointMatched, finalExtensions []scanner.FileTypeMatched, finalErrors []scanner.ErrorMatched, finalInfos []scanner.InfoMatched, outputDir string) { - exists, err := fileUtils.ElementExists(outputDir) if err != nil { From 2bd3ae4de25c17b277f8a81ce07af1e3fcb13bba Mon Sep 17 00:00:00 2001 From: Kartikey Semwal Date: Sun, 8 Sep 2024 15:26:29 +0530 Subject: [PATCH 4/6] code review 1 changes --- internal/file/file.go | 4 ++-- pkg/crawler/useragents.go | 5 ++++- pkg/output/output.go | 1 - 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/file/file.go b/internal/file/file.go index 8768e37..498b131 100644 --- a/internal/file/file.go +++ b/internal/file/file.go @@ -84,7 +84,7 @@ func CreateOutputFile(target string, subcommand string, format string, outputDir _, err := os.Stat(filename) if os.IsNotExist(err) { - if _, err := os.Stat(outputDir + "/"); os.IsNotExist(err) { + if _, err := os.Stat(fmt.Sprintf("%s/", outputDir)); os.IsNotExist(err) { CreateOutputFolder(outputDir) } // If the file doesn't exist, create it. @@ -123,7 +123,7 @@ func CreateIndexOutputFile(filename string, outputDir string) { _, err := os.Stat(filename) if os.IsNotExist(err) { - if _, err := os.Stat(outputDir + "/"); os.IsNotExist(err) { + if _, err := os.Stat(fmt.Sprintf("%s/", outputDir)); os.IsNotExist(err) { CreateOutputFolder(outputDir) } // If the file doesn't exist, create it. diff --git a/pkg/crawler/useragents.go b/pkg/crawler/useragents.go index 54385b1..9d02ab6 100644 --- a/pkg/crawler/useragents.go +++ b/pkg/crawler/useragents.go @@ -35,6 +35,10 @@ import ( "time" ) +const ( + maxRandomValue = 100 +) + // genOsString generates a random OS string for a User Agent. func genOsString() string { source := rand.NewSource(time.Now().UnixNano()) @@ -151,7 +155,6 @@ func GenerateRandomUserAgent() string { source := rand.NewSource(time.Now().UnixNano()) rng := rand.New(source) - const maxRandomValue = 100 decision := rng.Intn(maxRandomValue) var ua string diff --git a/pkg/output/output.go b/pkg/output/output.go index 92f553f..619703b 100644 --- a/pkg/output/output.go +++ b/pkg/output/output.go @@ -36,7 +36,6 @@ import ( "github.com/edoardottt/cariddi/pkg/scanner" ) -// constant defined in file.go as well, redefining here for circular dependency. const ( CariddiOutputFolder = "output-cariddi" ) From 0bfbd9033f1f7bdab03e54837e85d63b4579bfe3 Mon Sep 17 00:00:00 2001 From: Kartikey Semwal Date: Wed, 18 Sep 2024 21:50:52 +0530 Subject: [PATCH 5/6] Add validation for output folder and enhance unit tests for edge cases --- pkg/input/check.go | 35 +++++++++++++++++++++++++ pkg/input/check_test.go | 58 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 pkg/input/check_test.go diff --git a/pkg/input/check.go b/pkg/input/check.go index e5f6f08..38be87b 100644 --- a/pkg/input/check.go +++ b/pkg/input/check.go @@ -29,6 +29,7 @@ package input import ( "fmt" "os" + "path/filepath" "strings" fileUtils "github.com/edoardottt/cariddi/internal/file" @@ -47,6 +48,33 @@ func CheckOutputFile(input string) bool { return true } +// IsValidOutputPath checks if the directory is valid and, if created, cleans it up. +func CheckOutputPath(outputPath string) bool { + // Convert to absolute path if necessary + absPath, err := filepath.Abs(outputPath) + if err != nil { + return false + } + + // Check if the directory already exists + _, err = os.Stat(absPath) + if err == nil { + // Directory exists, so it's valid, no need to delete + return true + } + + // If the directory does not exist, try to create it + err = os.MkdirAll(absPath, os.ModePerm) + if err != nil { + return false + } + + // Since we created the directory, clean it up + defer os.RemoveAll(absPath) + + return true +} + // CheckFlags checks the flags taken as input. func CheckFlags(flags Input) { if flags.TXTout != "" { @@ -127,4 +155,11 @@ func CheckFlags(flags Input) { fmt.Println(" - cat urls | cariddi -headersfile headers.txt") os.Exit(1) } + + if flags.StoredRespDir != "" { + if !CheckOutputPath(flags.StoredRespDir) { + fmt.Println("Validation failed for srd flag; there may be errors creating the output directory.") + os.Exit(1) + } + } } diff --git a/pkg/input/check_test.go b/pkg/input/check_test.go new file mode 100644 index 0000000..641fc4e --- /dev/null +++ b/pkg/input/check_test.go @@ -0,0 +1,58 @@ +package input_test + +import ( + "os" + "path/filepath" + "testing" + + "github.com/edoardottt/cariddi/pkg/input" +) + +// TestCheckOutputPath tests the CheckOutputPath function for valid and invalid cases. +func TestCheckOutputPath(t *testing.T) { + // Create a temporary directory for testing + tmpDir, err := os.MkdirTemp("", "testdir") + if err != nil { + t.Fatalf("Failed to create temporary directory: %v", err) + } + defer os.RemoveAll(tmpDir) // Cleanup after test + + // Valid case: Existing directory + if !input.CheckOutputPath(tmpDir) { + t.Errorf("CheckOutputPath(%s) = false; want true", tmpDir) + } + + // Verify that the existing directory is still present after check + _, err = os.Stat(tmpDir) + if err != nil { + t.Errorf("Existing directory %s should still be present after CheckOutputPath, but got error: %v", tmpDir, err) + } + + // Cross-platform invalid cases + invalidPaths := []string{ + // Null character is invalid on all platforms + filepath.Join(tmpDir, "invalid\000path"), + // Reserved names (common issues across various OS) + filepath.Join(tmpDir, "CON"), + // Paths with excessively long names (common path length issues) + filepath.Join(tmpDir, string(make([]byte, 260))), + } + + for _, invalidPath := range invalidPaths { + if input.CheckOutputPath(invalidPath) { + t.Errorf("CheckOutputPath(%s) = true; want false", invalidPath) + } + } + + // Valid case: New directory creation and cleanup + newDir := filepath.Join(tmpDir, "newdir") + if !input.CheckOutputPath(newDir) { + t.Errorf("CheckOutputPath(%s) = false; want true", newDir) + } + + // After check, the directory should be removed + _, err = os.Stat(newDir) + if err == nil || !os.IsNotExist(err) { + t.Errorf("CheckOutputPath should remove the directory, but it still exists: %s", newDir) + } +} From 34a15fff6a1ab07ca9b6871955de913cd597d764 Mon Sep 17 00:00:00 2001 From: Kartikey Semwal Date: Fri, 20 Sep 2024 21:23:46 +0530 Subject: [PATCH 6/6] linux OS build failure fixes --- pkg/input/check_test.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pkg/input/check_test.go b/pkg/input/check_test.go index 641fc4e..a497b01 100644 --- a/pkg/input/check_test.go +++ b/pkg/input/check_test.go @@ -12,10 +12,11 @@ import ( func TestCheckOutputPath(t *testing.T) { // Create a temporary directory for testing tmpDir, err := os.MkdirTemp("", "testdir") + defer os.RemoveAll(tmpDir) // Cleanup after test + if err != nil { t.Fatalf("Failed to create temporary directory: %v", err) } - defer os.RemoveAll(tmpDir) // Cleanup after test // Valid case: Existing directory if !input.CheckOutputPath(tmpDir) { @@ -32,10 +33,6 @@ func TestCheckOutputPath(t *testing.T) { invalidPaths := []string{ // Null character is invalid on all platforms filepath.Join(tmpDir, "invalid\000path"), - // Reserved names (common issues across various OS) - filepath.Join(tmpDir, "CON"), - // Paths with excessively long names (common path length issues) - filepath.Join(tmpDir, string(make([]byte, 260))), } for _, invalidPath := range invalidPaths {