public void ProcRunner_ArgumentQuotingForwardedByBatchScript() { // Checks arguments passed to a batch script which itself passes them on are correctly escaped // Arrange var testDir = CreateTestSpecificFolder(TestContext); // Create a dummy exe that will produce a log file showing any input args var exeName = DummyExeHelper.CreateDummyExe(testDir, 0); var batchName = WriteBatchFileForTest(TestContext, "\"" + exeName + "\" %*"); var logger = new TestLogger(); var args = new ProcessRunnerArguments(batchName, true); var expected = new[] { "unquoted", "\"quoted\"", "\"quoted with spaces\"", "/test:\"quoted arg\"", "unquoted with spaces", "quote in \"the middle", "quotes \"& ampersands", "\"multiple \"\"\" quotes \" ", "trailing backslash \\", "all special chars: \\ / : * ? \" < > | %", "injection \" > foo.txt", "injection \" & echo haha", "double escaping \\\" > foo.txt" }; args.CmdLineArgs = expected; var runner = CreateProcessRunner(logger); // Act var success = runner.Execute(args); // Assert success.Should().BeTrue("Expecting the process to have succeeded"); runner.ExitCode.Should().Be(0, "Unexpected exit code"); // Check that the public and private arguments are passed to the child process var exeLogFile = DummyExeHelper.AssertDummyExeLogExists(testDir, TestContext); DummyExeHelper.AssertExpectedLogContents(exeLogFile, expected); }
[WorkItem(126)] // Exclude secrets from log data: http://jira.sonarsource.com/browse/SONARMSBRU-126 public void ProcRunner_DoNotLogSensitiveData() { // Arrange var testDir = CreateTestSpecificFolder(TestContext); // Create a dummy exe that will produce a log file showing any input args var exeName = DummyExeHelper.CreateDummyExe(testDir, 0); var logger = new TestLogger(); // Public args - should appear in the log var publicArgs = new string[] { "public1", "public2", "/d:sonar.projectKey=my.key" }; var sensitiveArgs = new string[] { // Public args - should appear in the log "public1", "public2", "/dmy.key=value", // Sensitive args - should not appear in the log "/d:sonar.password=secret data password", "/d:sonar.login=secret data login", "/d:sonar.jdbc.password=secret data db password", "/d:sonar.jdbc.username=secret data db user name", // Sensitive args - different cases -> exclude to be on the safe side "/d:SONAR.jdbc.password=secret data db password upper", "/d:sonar.PASSWORD=secret data password upper", // Sensitive args - parameter format is slightly incorrect -> exclude to be on the safe side "/dsonar.login =secret data key typo", "sonar.password=secret data password typo" }; var allArgs = sensitiveArgs.Union(publicArgs).ToArray(); var runnerArgs = new ProcessRunnerArguments(exeName, false) { CmdLineArgs = allArgs, // Specify the arguments we consider to be sensitive. // Note: this is a change from the S4MSB which has a hard-coded set of sensitive keys. SensitivePropertyKeys = new string[] { "sonar.password", "sonar.login", "sonar.jdbc.password", "sonar.jdbc.username" } }; var runner = CreateProcessRunner(logger); // Act var success = runner.Execute(runnerArgs); // Assert success.Should().BeTrue("Expecting the process to have succeeded"); runner.ExitCode.Should().Be(0, "Unexpected exit code"); // Check public arguments are logged but private ones are not foreach (var arg in publicArgs) { logger.AssertSingleDebugMessageExists(arg); } logger.AssertSingleDebugMessageExists("<sensitive data removed>"); AssertTextDoesNotAppearInLog("secret", logger); // Check that the public and private arguments are passed to the child process var exeLogFile = DummyExeHelper.AssertDummyExeLogExists(testDir, TestContext); DummyExeHelper.AssertExpectedLogContents(exeLogFile, allArgs); }