From 077d21bd195b65502713073f18f811a400f1d33a Mon Sep 17 00:00:00 2001 From: Wilian Gabriel Date: Thu, 20 Jan 2022 14:48:11 -0300 Subject: [PATCH] phpcs:chore - Update PHP_CodeSniffer to show severity and code (#935) I update the PHP_CodeSniffer tool to have a little more information such as: - All warnings can be shown as long as their severity is above 5 - All vulnerabilities pointed out have a correct level of severity based on the tool - We now demonstrate the vulnerable code in the analysis output Signed-off-by: wilian (cherry picked from commit 5d8b435b8298ea37c82e4139f26a9fbb58b942c5) --- e2e/analysis/test_case.go | 6 +- examples | 2 +- .../language_detect/language_detect_test.go | 27 +- .../formatters/php/phpcs/entities/message.go | 60 +- .../php/phpcs/entities/message_test.go | 25 +- .../formatters/php/phpcs/formatter.go | 15 +- .../formatters/php/phpcs/formatter_test.go | 1193 ++++++++++++++++- internal/utils/testutil/examples.go | 1 + 8 files changed, 1299 insertions(+), 30 deletions(-) diff --git a/e2e/analysis/test_case.go b/e2e/analysis/test_case.go index fe97982a3..5a7985578 100644 --- a/e2e/analysis/test_case.go +++ b/e2e/analysis/test_case.go @@ -77,9 +77,9 @@ func NewTestCase() []*TestCase { fmt.Sprintf(messages.MsgPrintFinishAnalysisWithStatus, analysis.Success), messages.MsgDebugVulnHashToFix, messages.MsgWarnAnalysisFoundVulns[16:], - "In this analysis, a total of 66 possible vulnerabilities were found and we classified them into:", - "Total of Vulnerability CRITICAL is: 17", - "Total of Vulnerability HIGH is: 22", + "In this analysis, a total of 69 possible vulnerabilities were found and we classified them into:", + "Total of Vulnerability CRITICAL is: 18", + "Total of Vulnerability HIGH is: 24", "Total of Vulnerability MEDIUM is: 24", "Total of Vulnerability LOW is: 3", fmt.Sprintf("{HORUSEC_CLI} Running %s - %s", tools.HorusecEngine, languages.CSharp), diff --git a/examples b/examples index 4426ce365..30450594d 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit 4426ce36543789eea56e14207a84bd780e602f62 +Subproject commit 30450594db0f727fc95a4150439e9950d32ca8fe diff --git a/internal/controllers/language_detect/language_detect_test.go b/internal/controllers/language_detect/language_detect_test.go index b4336fde7..df0f6473d 100644 --- a/internal/controllers/language_detect/language_detect_test.go +++ b/internal/controllers/language_detect/language_detect_test.go @@ -184,7 +184,8 @@ func TestLanguageDetect(t *testing.T) { assert.Contains(t, langs, languages.Leaks) assert.Contains(t, langs, languages.Java) assert.Contains(t, langs, languages.Generic) - assert.Len(t, langs, 3) + assert.Contains(t, langs, languages.Shell) + assert.Len(t, langs, 4) }) t.Run("Should run language detect and return JAVASCRIPT and GITLEAKS", func(t *testing.T) { @@ -212,6 +213,30 @@ func TestLanguageDetect(t *testing.T) { assert.Len(t, langs, 4) }) + t.Run("Should run language detect and return PHP, LEAKS, GENERIC in example2", func(t *testing.T) { + controller := NewLanguageDetect(config.New(), uuid.New()) + + langs, err := controller.Detect(testutil.PHPExample2) + + assert.NoError(t, err) + assert.Contains(t, langs, languages.Leaks) + assert.Contains(t, langs, languages.Generic) + assert.Contains(t, langs, languages.PHP) + assert.Len(t, langs, 3) + }) + + t.Run("Should run language detect and return PHP, LEAKS, GENERIC in example1", func(t *testing.T) { + controller := NewLanguageDetect(config.New(), uuid.New()) + + langs, err := controller.Detect(testutil.PHPExample1) + + assert.NoError(t, err) + assert.Contains(t, langs, languages.Leaks) + assert.Contains(t, langs, languages.Generic) + assert.Contains(t, langs, languages.PHP) + assert.Len(t, langs, 3) + }) + t.Run("Should run language detect and return KOTLIN and GITLEAKS", func(t *testing.T) { controller := NewLanguageDetect(config.New(), uuid.New()) diff --git a/internal/services/formatters/php/phpcs/entities/message.go b/internal/services/formatters/php/phpcs/entities/message.go index af3299c2f..713614303 100644 --- a/internal/services/formatters/php/phpcs/entities/message.go +++ b/internal/services/formatters/php/phpcs/entities/message.go @@ -17,13 +17,29 @@ package entities import ( "strconv" "strings" + + "github.com/ZupIT/horusec-devkit/pkg/enums/severities" +) + +const ( + MessageError = "ERROR" + MessageWarning = "WARNING" +) + +const ( + SeverityLevelLow = 2 + SeverityLevelMedium = 3 + SeverityLevelHigh = 4 + SeverityLevelCritical = 5 ) type Message struct { - Message string `json:"message"` - Line int `json:"line"` - Column int `json:"column"` - Type string `json:"type"` + Severity int `json:"severity"` + Source string `json:"source"` + Message string `json:"message"` + Line int `json:"line"` + Column int `json:"column"` + Type string `json:"type"` } func (m *Message) GetLine() string { @@ -34,7 +50,37 @@ func (m *Message) GetColumn() string { return strconv.Itoa(m.Column) } -func (m *Message) IsValidMessage() bool { - return m.Type == "ERROR" && - !strings.Contains(m.Message, "This implies that some PHP code is not scanned by PHPCS") +func (m *Message) IsAllowedMessage() bool { + return m.isWarningMessage() || m.isErrorMessage() +} + +func (m *Message) isErrorMessage() bool { + return m.Type == MessageError +} + +func (m *Message) isWarningMessage() bool { + return m.Type == MessageWarning +} + +func (m *Message) IsNotFailedToScan() bool { + return !strings.Contains(strings.ToLower(m.Message), + "this implies that some php code is not scanned by phpcs") +} + +// nolint:funlen,gocyclo // method of validation +func (m *Message) GetSeverity() severities.Severity { + switch { + case m.isWarningMessage() && m.Severity >= SeverityLevelCritical: + return severities.Info + case m.Severity < SeverityLevelLow: + return severities.Low + case m.Severity >= SeverityLevelLow && m.Severity <= SeverityLevelMedium: + return severities.Medium + case m.Severity == SeverityLevelHigh: + return severities.High + case m.Severity >= SeverityLevelCritical: + return severities.Critical + default: + return severities.Unknown + } } diff --git a/internal/services/formatters/php/phpcs/entities/message_test.go b/internal/services/formatters/php/phpcs/entities/message_test.go index a63ece344..0abc0ed8e 100644 --- a/internal/services/formatters/php/phpcs/entities/message_test.go +++ b/internal/services/formatters/php/phpcs/entities/message_test.go @@ -47,21 +47,30 @@ func TestGetColumn(t *testing.T) { } func TestIsValidMessage(t *testing.T) { - t.Run("should return false if invalid message", func(t *testing.T) { + t.Run("should return true if valid error message", func(t *testing.T) { message := &Message{ - Message: "This implies that some PHP code is not scanned by PHPCS", - Type: "ERROR", + Type: "ERROR", } - assert.False(t, message.IsValidMessage()) + assert.True(t, message.isErrorMessage()) + assert.True(t, message.IsAllowedMessage()) }) - t.Run("should return true if valid message", func(t *testing.T) { + t.Run("should return true if valid warning message", func(t *testing.T) { message := &Message{ - Message: "", - Type: "ERROR", + Type: "WARNING", } - assert.True(t, message.IsValidMessage()) + assert.True(t, message.isWarningMessage()) + assert.True(t, message.IsAllowedMessage()) + }) + t.Run("should return false if invalid type message", func(t *testing.T) { + message := &Message{ + Type: "other", + } + + assert.False(t, message.isErrorMessage()) + assert.False(t, message.isWarningMessage()) + assert.False(t, message.IsAllowedMessage()) }) } diff --git a/internal/services/formatters/php/phpcs/formatter.go b/internal/services/formatters/php/phpcs/formatter.go index aeb7f4201..ca4e73182 100644 --- a/internal/services/formatters/php/phpcs/formatter.go +++ b/internal/services/formatters/php/phpcs/formatter.go @@ -16,10 +16,10 @@ package phpcs import ( "encoding/json" + "fmt" "github.com/ZupIT/horusec-devkit/pkg/entities/vulnerability" "github.com/ZupIT/horusec-devkit/pkg/enums/languages" - "github.com/ZupIT/horusec-devkit/pkg/enums/severities" "github.com/ZupIT/horusec-devkit/pkg/enums/tools" "github.com/ZupIT/horusec-devkit/pkg/utils/logger" @@ -28,6 +28,7 @@ import ( "github.com/ZupIT/horusec/internal/helpers/messages" "github.com/ZupIT/horusec/internal/services/formatters" "github.com/ZupIT/horusec/internal/services/formatters/php/phpcs/entities" + fileutils "github.com/ZupIT/horusec/internal/utils/file" vulnhash "github.com/ZupIT/horusec/internal/utils/vuln_hash" ) @@ -94,20 +95,26 @@ func (f *Formatter) parseResults(results map[string]interface{}) { func (f *Formatter) parseMessages(filepath string, result interface{}) { for _, message := range f.parseToResult(result).Messages { - if message.IsValidMessage() { - f.AddNewVulnerabilityIntoAnalysis(f.setVulnerabilityData(filepath, message)) + if message.IsAllowedMessage() && message.IsNotFailedToScan() { + vuln := f.setVulnerabilityData(filepath, message) + f.AddNewVulnerabilityIntoAnalysis(vuln) } } } func (f *Formatter) setVulnerabilityData(filepath string, result entities.Message) *vulnerability.Vulnerability { vuln := f.getDefaultVulnerabilitySeverity() - vuln.Severity = severities.Unknown + vuln.Severity = result.GetSeverity() vuln.Details = result.Message vuln.Line = result.GetLine() vuln.Column = result.GetColumn() vuln.File = f.RemoveSrcFolderFromPath(filepath) vuln = vulnhash.Bind(vuln) + + // NOTE: code and details were set after the vulnhash.Bind to avoid changes in the hash generation + vuln.Code, _ = fileutils.GetCode(f.GetConfigProjectPath(), vuln.File, result.GetLine()) + vuln.Details += fmt.Sprintf("\n %s", result.Source) + return f.SetCommitAuthor(vuln) } diff --git a/internal/services/formatters/php/phpcs/formatter_test.go b/internal/services/formatters/php/phpcs/formatter_test.go index e733e945b..f0020b367 100644 --- a/internal/services/formatters/php/phpcs/formatter_test.go +++ b/internal/services/formatters/php/phpcs/formatter_test.go @@ -19,6 +19,7 @@ import ( "testing" entitiesAnalysis "github.com/ZupIT/horusec-devkit/pkg/entities/analysis" + "github.com/ZupIT/horusec-devkit/pkg/enums/severities" "github.com/ZupIT/horusec-devkit/pkg/enums/tools" "github.com/stretchr/testify/assert" @@ -29,24 +30,43 @@ import ( "github.com/ZupIT/horusec/internal/utils/testutil" ) -func TestStartCFlawfinder(t *testing.T) { +func TestStartPHPCodeSniffer(t *testing.T) { t.Run("should success execute container and process output", func(t *testing.T) { dockerAPIControllerMock := testutil.NewDockerMock() analysis := &entitiesAnalysis.Analysis{} config := &cliConfig.Config{} config.WorkDir = &workdir.WorkDir{} - output := "{ \"files\":{ \"\\/src\\/XSS\\/XSS_level5.php\":{ \"errors\":1, \"warnings\":4, \"messages\":[ { \"message\":\"User input detetected with $_SERVER.\", \"source\":\"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn\", \"severity\":5, \"fixable\":false, \"type\":\"WARNING\", \"line\":14, \"column\":39 }, { \"message\":\"Easy XSS detected because of direct user input with $_SERVER on echo\", \"source\":\"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr\", \"severity\":5, \"fixable\":false, \"type\":\"ERROR\", \"line\":14, \"column\":39 } ] } } }" - - dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(output, nil) + dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(outputAnalysis, nil) service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config) formatter := NewFormatter(service) formatter.StartAnalysis("") - assert.NotEmpty(t, analysis) - assert.Len(t, analysis.AnalysisVulnerabilities, 1) + totalBySeverity := map[severities.Severity]int{} + for _, v := range analysis.AnalysisVulnerabilities { + totalBySeverity[v.Vulnerability.Severity]++ + } + assert.Equal(t, 0, totalBySeverity[severities.Unknown]) + assert.Equal(t, 96, totalBySeverity[severities.Info]) + assert.Equal(t, 23, totalBySeverity[severities.Critical]) + assert.Equal(t, 0, totalBySeverity[severities.Low]) + assert.Equal(t, 0, totalBySeverity[severities.Medium]) + assert.Equal(t, 0, totalBySeverity[severities.High]) + }) + t.Run("should ignore the problems with contains fail in your scan", func(t *testing.T) { + dockerAPIControllerMock := testutil.NewDockerMock() + analysis := &entitiesAnalysis.Analysis{} + config := cliConfig.New() + + dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(outputToIgnoreInAnalysis, nil) + + service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config) + formatter := NewFormatter(service) + + formatter.StartAnalysis("") + assert.Len(t, analysis.AnalysisVulnerabilities, 0) }) t.Run("should return error when invalid output", func(t *testing.T) { @@ -98,3 +118,1164 @@ func TestStartCFlawfinder(t *testing.T) { formatter.StartAnalysis("") }) } + +const outputToIgnoreInAnalysis = ` +{ + "totals":{ + "errors":0, + "warnings":1, + "fixable":0 + }, + "files":{ + "\/src\/src\/tool-examples\/phpcs-security-audit.php":{ + "errors":23, + "warnings":73, + "messages":[ + { + "message":"No file extension has been found in a include\/require function. This implies that some PHP code is not scanned by PHPCS.", + "source":"PHPCS_SecurityAudit.Misc.IncludeMismatch.ErrMiscIncludeMismatchNoExt", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":25, + "column":1 + } + ] + } + } +} +` + +const outputAnalysis = ` +{ + "totals":{ + "errors":24, + "warnings":96, + "fixable":0 + }, + "files":{ + "\/src\/src\/sql-injection_2.php":{ + "errors":0, + "warnings":3, + "messages":[ + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":4, + "column":52 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":7, + "column":7 + }, + { + "message":"Possible XSS detected with $customer on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":14, + "column":10 + } + ] + }, + "\/src\/src\/basic-collection.php":{ + "errors":0, + "warnings":6, + "messages":[ + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":4, + "column":9 + }, + { + "message":"Possible XSS detected with . on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":5, + "column":15 + }, + { + "message":"User input detetected with $_POST.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":8, + "column":7 + }, + { + "message":"SQL function mysql_query() detected with dynamic parameter ", + "source":"PHPCS_SecurityAudit.BadFunctions.SQLFunctions.WarnSQLFunction", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":9, + "column":1 + }, + { + "message":"User input detetected with $_COOKIE.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":12, + "column":8 + }, + { + "message":"System program execution function exec() detected with dynamic parameter", + "source":"PHPCS_SecurityAudit.BadFunctions.SystemExecFunctions.WarnSystemExec", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":13, + "column":1 + } + ] + }, + "\/src\/src\/tool-examples\/progpilot.php":{ + "errors":0, + "warnings":2, + "messages":[ + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":3, + "column":9 + }, + { + "message":"Possible XSS detected with \"$var4\" on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":5, + "column":6 + } + ] + }, + "\/src\/src\/tool-examples\/phpcs-security-audit.php":{ + "errors":23, + "warnings":73, + "messages":[ + { + "message":"Possible XSS detected with . on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":6, + "column":13 + }, + { + "message":"User input detetected with $_POST.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":6, + "column":15 + }, + { + "message":"Easy XSS detected because of direct user input with $_POST on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":6, + "column":15 + }, + { + "message":"db_query() is deprecated except when doing a static query", + "source":"PHPCS_SecurityAudit.Drupal7.SQLi.D7NoDbQuery", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":8, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":8, + "column":10 + }, + { + "message":"Potential SQL injection found in db_query()", + "source":"PHPCS_SecurityAudit.Drupal7.SQLi.D7DbQuerySQLi", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":8, + "column":10 + }, + { + "message":"Usage of preg_replace with \/e modifier is not recommended.", + "source":"PHPCS_SecurityAudit.BadFunctions.PregReplace.PregReplaceE", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":9, + "column":1 + }, + { + "message":"Usage of preg_replace with \/e modifier is not recommended.", + "source":"PHPCS_SecurityAudit.BadFunctions.PregReplace.PregReplaceE", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":10, + "column":1 + }, + { + "message":"User input and \/e modifier found in preg_replace, remote code execution possible.", + "source":"PHPCS_SecurityAudit.BadFunctions.PregReplace.PregReplaceUserInputE", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":10, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":10, + "column":24 + }, + { + "message":"User input found in preg_replace, \/e modifier could be used for malicious intent.", + "source":"PHPCS_SecurityAudit.BadFunctions.PregReplace.PregReplaceUserInput", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":11, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":11, + "column":14 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":11, + "column":26 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":11, + "column":38 + }, + { + "message":"Dynamic usage of preg_replace, please check manually for \/e modifier or user input.", + "source":"PHPCS_SecurityAudit.BadFunctions.PregReplace.PregReplaceDyn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":12, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":12, + "column":18 + }, + { + "message":"Weird usage of preg_replace, please check manually for \/e modifier.", + "source":"PHPCS_SecurityAudit.BadFunctions.PregReplace.PregReplaceWeird", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":13, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":13, + "column":21 + }, + { + "message":"Crypto function md5 used.", + "source":"PHPCS_SecurityAudit.BadFunctions.CryptoFunctions.WarnCryptoFunc", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":17, + "column":1 + }, + { + "message":"phpinfo() function detected", + "source":"PHPCS_SecurityAudit.BadFunctions.Phpinfos.WarnPhpinfo", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":18, + "column":1 + }, + { + "message":"Function handling function create_function() detected with dynamic parameter", + "source":"PHPCS_SecurityAudit.BadFunctions.FunctionHandlingFunctions.WarnFunctionHandling", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":19, + "column":1 + }, + { + "message":"Unusual function ftp_exec() detected", + "source":"PHPCS_SecurityAudit.BadFunctions.FringeFunctions.WarnFringestuff", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":20, + "column":1 + }, + { + "message":"Filesystem function fread() detected with dynamic parameter", + "source":"PHPCS_SecurityAudit.BadFunctions.FilesystemFunctions.WarnFilesystem", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":21, + "column":1 + }, + { + "message":"Function array_map() that supports callback detected", + "source":"PHPCS_SecurityAudit.BadFunctions.CallbackFunctions.WarnCallbackFunctions", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":22, + "column":1 + }, + { + "message":"System execution with backticks detected with dynamic parameter", + "source":"PHPCS_SecurityAudit.BadFunctions.Backticks.WarnSystemExec", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":23, + "column":1 + }, + { + "message":"System execution with backticks detected with dynamic parameter directly from user input", + "source":"PHPCS_SecurityAudit.BadFunctions.Backticks.ErrSystemExec", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":24, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":24, + "column":2 + }, + { + "message":"No file extension has been found in a include\/require function. This implies that some PHP code is not scanned by PHPCS.", + "source":"PHPCS_SecurityAudit.Misc.IncludeMismatch.ErrMiscIncludeMismatchNoExt", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":25, + "column":1 + }, + { + "message":"Possible RFI detected with $a on include", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyRFI.WarnEasyRFI", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":25, + "column":9 + }, + { + "message":"Assert eval function assert() detected with dynamic parameter", + "source":"PHPCS_SecurityAudit.BadFunctions.Asserts.WarnFunctionHandling", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":26, + "column":1 + }, + { + "message":"Assert eval function assert() detected with dynamic parameter directly from user input", + "source":"PHPCS_SecurityAudit.BadFunctions.Asserts.ErrFunctionHandling", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":27, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":27, + "column":8 + }, + { + "message":"System program execution function exec() detected with dynamic parameter", + "source":"PHPCS_SecurityAudit.BadFunctions.SystemExecFunctions.WarnSystemExec", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":28, + "column":1 + }, + { + "message":"System program execution function exec() detected with dynamic parameter directly from user input", + "source":"PHPCS_SecurityAudit.BadFunctions.SystemExecFunctions.ErrSystemExec", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":29, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":29, + "column":6 + }, + { + "message":"SQL function mysql_query() detected with dynamic parameter ", + "source":"PHPCS_SecurityAudit.BadFunctions.SQLFunctions.WarnSQLFunction", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":30, + "column":1 + }, + { + "message":"SQL function mysql_query() detected with dynamic parameter directly from user input", + "source":"PHPCS_SecurityAudit.BadFunctions.SQLFunctions.ErrSQLFunction", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":31, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":31, + "column":13 + }, + { + "message":"Crypto function mcrypt_encrypt used.", + "source":"PHPCS_SecurityAudit.BadFunctions.CryptoFunctions.WarnCryptoFunc", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":35, + "column":1 + }, + { + "message":"Bad use of openssl_public_encrypt without OPENSSL_PKCS1_OAEP_PADDING", + "source":"PHPCS_SecurityAudit.BadFunctions.CryptoFunctions.ErrPCKS1Crypto", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":36, + "column":36 + }, + { + "message":"CVE-2013-4113 ext\/xml\/xml.c in PHP before 5.3.27 does not properly consider parsing depth, which allows remote attackers to cause a denial of service (heap memory corruption) or possibly have unspecified other impact via a crafted document that is processed by the xml_parse_into_struct function.", + "source":"PHPCS_SecurityAudit.Drupal8.CVE20134113.CVE-2013-4113", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":39, + "column":1 + }, + { + "message":"CVE-2013-2110 Heap-based buffer overflow in the php_quot_print_encode function in ext\/standard\/quot_print.c in PHP before 5.3.26 and 5.4.x before 5.4.16 allows remote attackers to cause a denial of service (application crash) or possibly have unspecified other impact via a crafted argument to the quoted_printable_encode function.", + "source":"PHPCS_SecurityAudit.Drupal8.CVE20132110.CVE-2013-2110", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":40, + "column":1 + }, + { + "message":"Bad CORS header detected.", + "source":"PHPCS_SecurityAudit.Misc.BadCorsHeader.WarnPCKS1Crypto", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":43, + "column":16 + }, + { + "message":"The file extension '.xyz' that is not specified by --extensions has been used in a include\/require function. Please add it to the scan process.", + "source":"PHPCS_SecurityAudit.Misc.IncludeMismatch.ErrMiscIncludeMismatch", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":44, + "column":1 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":47, + "column":1 + }, + { + "message":"Possible XSS detected with . on print", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":48, + "column":13 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":48, + "column":15 + }, + { + "message":"Easy XSS detected because of direct user input with $_GET on print", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":48, + "column":15 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":49, + "column":6 + }, + { + "message":"Easy XSS detected because of direct user input with $_GET on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":49, + "column":6 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":50, + "column":6 + }, + { + "message":"Easy XSS detected because of direct user input with $_GET on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":50, + "column":6 + }, + { + "message":"Possible XSS detected with \"{$_GET['a']}\" on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":51, + "column":6 + }, + { + "message":"Possible XSS detected with \"${_GET['a']}\" on print", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":52, + "column":7 + }, + { + "message":"Possible XSS detected with a on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":53, + "column":6 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":53, + "column":8 + }, + { + "message":"Easy XSS detected because of direct user input with $_GET on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":53, + "column":8 + }, + { + "message":"Possible XSS detected with allo on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":54, + "column":6 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":54, + "column":13 + }, + { + "message":"Easy XSS detected because of direct user input with $_GET on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":54, + "column":13 + }, + { + "message":"User input detetected with arg.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":55, + "column":6 + }, + { + "message":"Easy XSS detected because of direct user input with arg on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":55, + "column":6 + }, + { + "message":"Possible XSS detected with . on die", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":56, + "column":8 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":56, + "column":10 + }, + { + "message":"Easy XSS detected because of direct user input with $_GET on die", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":56, + "column":10 + }, + { + "message":"Possible XSS detected with . on exit", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":57, + "column":13 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":57, + "column":15 + }, + { + "message":"Easy XSS detected because of direct user input with $_GET on exit", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":57, + "column":15 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":59, + "column":5 + }, + { + "message":"Easy XSS detected because of direct user input with $_GET on = 0.9.6", + "source":"PHPCS_SecurityAudit.BadFunctions.FilesystemFunctions.WarnSymlink", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":64, + "column":1 + }, + { + "message":"Filesystem function symlink() detected with dynamic parameter", + "source":"PHPCS_SecurityAudit.BadFunctions.FilesystemFunctions.WarnFilesystem", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":64, + "column":1 + }, + { + "message":"Filesystem function delete() detected with dynamic parameter", + "source":"PHPCS_SecurityAudit.BadFunctions.FilesystemFunctions.WarnFilesystem", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":65, + "column":1 + }, + { + "message":"Potential SQL injection with direct variable usage in join with param #3", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":69, + "column":27 + }, + { + "message":"Potential SQL injection with direct variable usage in innerJoin with param #3", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":70, + "column":32 + }, + { + "message":"Potential SQL injection with direct variable usage in leftJoin with param #3", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":71, + "column":31 + }, + { + "message":"Potential SQL injection with direct variable usage in rightJoin with param #3", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":72, + "column":32 + }, + { + "message":"Potential SQL injection with direct variable usage in addExpression with param #1", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":73, + "column":23 + }, + { + "message":"Potential SQL injection with direct variable usage in groupBy with param #1", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":74, + "column":17 + }, + { + "message":"Potential SQL injection with direct variable usage in orderBy with param #1", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":76, + "column":17 + }, + { + "message":"Potential SQL injection with direct variable usage in orderBy with param #2", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":76, + "column":21 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":81, + "column":31 + }, + { + "message":"SQL injection found in condition with param #3", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesSQLi", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":81, + "column":31 + }, + { + "message":"Potential SQL injection with direct variable usage in where with param #1", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":83, + "column":13 + }, + { + "message":"Potential SQL injection with direct variable usage in havingCondition with param #3", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":84, + "column":36 + }, + { + "message":"Potential SQL injection with direct variable usage in having with param #1", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":85, + "column":14 + }, + { + "message":"Possible XSS detected with $count on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":88, + "column":6 + }, + { + "message":"Potential SQL injection with direct variable usage in expression with param #1", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":91, + "column":18 + }, + { + "message":"Potential SQL injection with direct variable usage in expression with param #2", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":91, + "column":22 + }, + { + "message":"Potential SQL injection with direct variable usage in fields with param #1 with array key value", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":96, + "column":9 + }, + { + "message":"Potential SQL injection with direct variable usage in fields with param #1 with array key value", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesDirectVar", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":97, + "column":9 + }, + { + "message":"Dynamic query with db_select on table node should be tagged for access restrictions", + "source":"PHPCS_SecurityAudit.Drupal7.DbQueryAC.D7DbQueryACErr", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":106, + "column":10 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":108, + "column":14 + }, + { + "message":"SQL injection found in fields with param #1", + "source":"PHPCS_SecurityAudit.Drupal7.DynQueries.D7DynQueriesSQLi", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":108, + "column":14 + } + ] + }, + "\/src\/src\/tool-examples\/php-security-scanner.php":{ + "errors":0, + "warnings":2, + "messages":[ + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":4, + "column":9 + }, + { + "message":"SQL function mysql_query() detected with dynamic parameter ", + "source":"PHPCS_SecurityAudit.BadFunctions.SQLFunctions.WarnSQLFunction", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":8, + "column":5 + } + ] + }, + "\/src\/src\/cross-site-scripting-xss.php":{ + "errors":1, + "warnings":5, + "messages":[ + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":4, + "column":52 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":7, + "column":13 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":7, + "column":28 + }, + { + "message":"Possible XSS detected with . on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":9, + "column":24 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":9, + "column":26 + }, + { + "message":"Easy XSS detected because of direct user input with $_GET on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSerr", + "severity":5, + "fixable":false, + "type":"ERROR", + "line":9, + "column":26 + } + ] + }, + "\/src\/src\/sql-injection.php":{ + "errors":0, + "warnings":5, + "messages":[ + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":4, + "column":52 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":9, + "column":13 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":9, + "column":26 + }, + { + "message":"User input detetected with $_GET.", + "source":"PHPCS_SecurityAudit.Drupal7.UserInputWatch.D7UserInWaWarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":11, + "column":56 + }, + { + "message":"Possible XSS detected with $employee on echo", + "source":"PHPCS_SecurityAudit.BadFunctions.EasyXSS.EasyXSSwarn", + "severity":5, + "fixable":false, + "type":"WARNING", + "line":16, + "column":10 + } + ] + } + } +} +` diff --git a/internal/utils/testutil/examples.go b/internal/utils/testutil/examples.go index bdec6644a..6a11a5bd3 100644 --- a/internal/utils/testutil/examples.go +++ b/internal/utils/testutil/examples.go @@ -100,6 +100,7 @@ var ( // PHPExample represents the entire PHP examples directory. PHPExample = filepath.Join(ExamplesPath, "php") PHPExample1 = filepath.Join(PHPExample, "example1") + PHPExample2 = filepath.Join(PHPExample, "example2") // PythonExample represents the entire Python examples directory. PythonExample = filepath.Join(ExamplesPath, "python")