diff --git a/audit_test.go b/audit_test.go index 8a5b4780a..1eb3c44f1 100644 --- a/audit_test.go +++ b/audit_test.go @@ -544,7 +544,16 @@ func addDummyPackageDescriptor(t *testing.T, hasPackageJson bool) { // JAS func TestXrayAuditSastCppFlagSimpleJson(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "c"), "3", false, true) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "c"), "3", false, true, false, "") + validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{ + Vulnerabilities: 1, + Sast: 1, + }) +} +func TestXrayAuditSastCSharpFlagSimpleJson(t *testing.T) { + // Placeholder until C# Sast is implemented + t.Skip() + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "dotnet", "dotnet-single"), "3", false, false, true, "") validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{ Vulnerabilities: 1, Sast: 1, @@ -552,13 +561,13 @@ func TestXrayAuditSastCppFlagSimpleJson(t *testing.T) { } func TestXrayAuditWithoutSastCppFlagSimpleJson(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "c"), "3", false, false) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "c"), "3", false, false, false, "") // verify no results for Sast validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{}) } func TestXrayAuditJasMissingContextSimpleJson(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "maven", "missing-context"), "3", false, false) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "maven", "missing-context"), "3", false, false, false, "") validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{MissingContext: 1}) } @@ -566,7 +575,7 @@ func TestXrayAuditNotEntitledForJas(t *testing.T) { integration.InitAuditGeneralTests(t, scangraph.GraphScanMinXrayVersion) cliToRun, cleanUp := integration.InitTestWithMockCommandOrParams(t, false, getNoJasAuditMockCommand) defer cleanUp() - output := testXrayAuditJas(t, cliToRun, filepath.Join("jas", "jas"), "3", false, false) + output := testXrayAuditJas(t, cliToRun, filepath.Join("jas", "jas"), "3", false, false, false, "") validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{Vulnerabilities: 8}) } @@ -587,7 +596,7 @@ func getNoJasAuditMockCommand() components.Command { } func TestXrayAuditJasSimpleJson(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3", false, false) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3", false, false, false, "") validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{ Sast: 1, Iac: 9, @@ -603,12 +612,12 @@ func TestXrayAuditJasSimpleJson(t *testing.T) { func TestXrayAuditJasSimpleJsonWithTokenValidation(t *testing.T) { integration.InitAuditGeneralTests(t, jasutils.DynamicTokenValidationMinXrayVersion) - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3", true, false) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3", true, false, false, "") validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{Vulnerabilities: 5, Inactive: 5}) } func TestXrayAuditJasSimpleJsonWithOneThread(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "1", false, false) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "1", false, false, false, "") validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{ Sast: 1, Iac: 9, @@ -623,7 +632,7 @@ func TestXrayAuditJasSimpleJsonWithOneThread(t *testing.T) { } func TestXrayAuditJasSimpleJsonWithConfig(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas-config"), "3", false, false) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas-config"), "3", false, false, false, "") validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{ Secrets: 1, @@ -636,11 +645,11 @@ func TestXrayAuditJasSimpleJsonWithConfig(t *testing.T) { } func TestXrayAuditJasNoViolationsSimpleJson(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "npm", "npm"), "3", false, false) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "npm", "npm"), "3", false, false, false, "") validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{Vulnerabilities: 1, NotApplicable: 1}) } -func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string, validateSecrets, validateSastCpp bool) string { +func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string, validateSecrets bool, validateSastCpp bool, validateSastCSharp bool, customExclusion string) string { integration.InitAuditGeneralTests(t, scangraph.GraphScanMinXrayVersion) _, cleanUp := securityTestUtils.CreateTestProjectEnvAndChdir(t, filepath.Join(filepath.FromSlash(securityTests.GetTestResourcesPath()), filepath.Join("projects", project))) defer cleanUp() @@ -655,6 +664,13 @@ func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, unsetEnv := clientTests.SetEnvWithCallbackAndAssert(t, "JFROG_SAST_ENABLE_CPP", "1") defer unsetEnv() } + if validateSastCSharp { + unsetEnv := clientTests.SetEnvWithCallbackAndAssert(t, "JFROG_SAST_ENABLE_CS", "1") + defer unsetEnv() + } + if len(customExclusion) != 0 { + args = append(args, "--exclusions", customExclusion) + } return testCli.WithoutCredentials().RunCliCmdWithOutput(t, args...) } @@ -714,7 +730,7 @@ func TestAuditOnEmptyProject(t *testing.T) { func TestXrayAuditNotEntitledForJasWithXrayUrl(t *testing.T) { cliToRun, cleanUp := integration.InitTestWithMockCommandOrParams(t, true, getNoJasAuditMockCommand) defer cleanUp() - output := testXrayAuditJas(t, cliToRun, filepath.Join("jas", "jas"), "3", false, false) + output := testXrayAuditJas(t, cliToRun, filepath.Join("jas", "jas"), "3", false, false, false, "") // Verify that scan results are printed validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{Vulnerabilities: 8}) // Verify that JAS results are not printed @@ -723,7 +739,7 @@ func TestXrayAuditNotEntitledForJasWithXrayUrl(t *testing.T) { func TestXrayAuditJasSimpleJsonWithXrayUrl(t *testing.T) { cliToRun := integration.GetTestCli(cli.GetJfrogCliSecurityApp(), true) - output := testXrayAuditJas(t, cliToRun, filepath.Join("jas", "jas"), "3", false, false) + output := testXrayAuditJas(t, cliToRun, filepath.Join("jas", "jas"), "3", false, false, false, "") validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{ Sast: 1, Iac: 9, @@ -736,3 +752,22 @@ func TestXrayAuditJasSimpleJsonWithXrayUrl(t *testing.T) { NotApplicable: 2, }) } + +// custom excluded folders + +func TestXrayAuditJasSimpleJsonWithCustomExclusions(t *testing.T) { + cliToRun := integration.GetTestCli(cli.GetJfrogCliSecurityApp(), true) + + output := testXrayAuditJas(t, cliToRun, filepath.Join("jas", "jas"), "3", false, false, false, "non_existing_folder") + validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{ + Sast: 2, + Iac: 9, + Secrets: 6, + + Vulnerabilities: 8, + Applicable: 3, + Undetermined: 1, + NotCovered: 1, + NotApplicable: 2, + }) +} diff --git a/commands/audit/sca/common_test.go b/commands/audit/sca/common_test.go index e04f713fa..0d97c5f45 100644 --- a/commands/audit/sca/common_test.go +++ b/commands/audit/sca/common_test.go @@ -36,7 +36,7 @@ func TestGetExcludePattern(t *testing.T) { { name: "Test no exclude pattern recursive", params: func() *utils.AuditBasicParams { return (&utils.AuditBasicParams{}).SetIsRecursiveScan(true) }, - expected: "(^.*\\.git.*$)|(^.*node_modules.*$)|(^.*target.*$)|(^.*venv.*$)|(^.*test.*$)", + expected: "(^.*\\.git.*$)|(^.*node_modules.*$)|(^.*target.*$)|(^.*venv.*$)|(^.*test.*$)|(^dist$)", }, { name: "Test exclude pattern not recursive", @@ -50,7 +50,7 @@ func TestGetExcludePattern(t *testing.T) { { name: "Test no exclude pattern", params: func() *utils.AuditBasicParams { return &utils.AuditBasicParams{} }, - expected: "(^.*\\.git.*$)|(^.*node_modules.*$)|(^.*target.*$)|(^.*venv.*$)|(^.*test.*$)", + expected: "(^.*\\.git.*$)|(^.*node_modules.*$)|(^.*target.*$)|(^.*venv.*$)|(^.*test.*$)|(^dist$)", }, } diff --git a/tests/testdata/projects/jas/jas/sast/flask_webgoat/dist/init_file_to_ignore.py b/tests/testdata/projects/jas/jas/sast/flask_webgoat/dist/init_file_to_ignore.py new file mode 100644 index 000000000..c9edb3ff9 --- /dev/null +++ b/tests/testdata/projects/jas/jas/sast/flask_webgoat/dist/init_file_to_ignore.py @@ -0,0 +1,54 @@ +# Copy of __init__ - inside the dist folder - which we expect not to be scanned + +import os +import sqlite3 +from pathlib import Path + +from flask import Flask, g + +DB_FILENAME = "database.db" + + +def query_db(query, args=(), one=False, commit=False): + with sqlite3.connect(DB_FILENAME) as conn: + # vulnerability: Sensitive Data Exposure + conn.set_trace_callback(print) + cur = conn.cursor().execute(query, args) + if commit: + conn.commit() + return cur.fetchone() if one else cur.fetchall() + + +def create_app(): + app = Flask(__name__) + # jfrog-ignore - disable secrets scan findings + app.secret_key = "aeZ1iwoh2ree2mo0Eereireong4baitixaixu5Ee" + + db_path = Path(DB_FILENAME) + if db_path.exists(): + db_path.unlink() + + conn = sqlite3.connect(DB_FILENAME) + create_table_query = """CREATE TABLE IF NOT EXISTS user + (id INTEGER PRIMARY KEY, username TEXT, password TEXT, access_level INTEGER)""" + conn.execute(create_table_query) + + insert_admin_query = """INSERT INTO user (id, username, password, access_level) + VALUES (1, 'admin', 'admin', 0)""" + conn.execute(insert_admin_query) + conn.commit() + conn.close() + + with app.app_context(): + from . import actions + from . import auth + from . import status + from . import ui + from . import users + + app.register_blueprint(actions.bp) + app.register_blueprint(auth.bp) + app.register_blueprint(status.bp) + app.register_blueprint(ui.bp) + app.register_blueprint(users.bp) + return app diff --git a/tests/testdata/projects/package-managers/dotnet/dotnet-single/sample_sast_vulnerability.cs b/tests/testdata/projects/package-managers/dotnet/dotnet-single/sample_sast_vulnerability.cs new file mode 100644 index 000000000..fc7fe0f4a --- /dev/null +++ b/tests/testdata/projects/package-managers/dotnet/dotnet-single/sample_sast_vulnerability.cs @@ -0,0 +1,20 @@ +using System; +using System.IO; +using System.Web; + +public class TaintedPathHandler : IHttpHandler +{ + public void ProcessRequest(HttpContext ctx) + { + String path = ctx.Request.QueryString["path"]; + // BAD: This could read any file on the filesystem. + ctx.Response.Write(File.ReadAllText(path)); + + // BAD: This could still read any file on the filesystem. + ctx.Response.Write(File.ReadAllText("/home/user/" + path)); + + // GOOD: MapPath ensures the path is safe to read from. + string safePath = ctx.Request.MapPath(path, ctx.Request.ApplicationPath, false); + ctx.Response.Write(File.ReadAllText(safePath)); + } +} \ No newline at end of file diff --git a/utils/utils.go b/utils/utils.go index cc72bd0cb..aa5f5d2b0 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -33,7 +33,7 @@ var ( // Exclude pattern for files. DefaultJasExcludePatterns = []string{"**/.git/**", "**/*test*/**", "**/*venv*/**", NodeModulesPattern, "**/target/**", "**/dist/**"} // Exclude pattern for directories. - DefaultScaExcludePatterns = []string{"*.git*", "*node_modules*", "*target*", "*venv*", "*test*"} + DefaultScaExcludePatterns = []string{"*.git*", "*node_modules*", "*target*", "*venv*", "*test*", "dist"} ) const (