From d287a0a2bec4ff53110ee328d632438f197af346 Mon Sep 17 00:00:00 2001 From: andrecs <12188364+andrecsilva@users.noreply.github.com> Date: Fri, 24 Jan 2025 10:24:52 -0300 Subject: [PATCH] Integration tests for use-secure-protocols --- .../sonar/test_sonar_use_secure_protocols.py | 30 +++++++++++++++++++ .../codemods/test/integration_utils.py | 11 ++++--- .../sonar/sonar_use_secure_protocols.py | 14 +++++++-- tests/samples/sonar_hotspots.json | 20 +++++++++++++ tests/samples/use_secure_protocols.py | 5 ++++ 5 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 integration_tests/sonar/test_sonar_use_secure_protocols.py create mode 100644 tests/samples/use_secure_protocols.py diff --git a/integration_tests/sonar/test_sonar_use_secure_protocols.py b/integration_tests/sonar/test_sonar_use_secure_protocols.py new file mode 100644 index 00000000..e7acef9a --- /dev/null +++ b/integration_tests/sonar/test_sonar_use_secure_protocols.py @@ -0,0 +1,30 @@ +from codemodder.codemods.test import SonarIntegrationTest +from core_codemods.sonar.sonar_use_secure_protocols import ( + SonarUseSecureProtocols, + SonarUseSecureProtocolsTransformer, +) + + +class TestSonarUseSecureProtocols(SonarIntegrationTest): + codemod = SonarUseSecureProtocols + code_path = "tests/samples/use_secure_protocols.py" + replacement_lines = [ + ( + 5, + """url = "https://example.com"\n""", + ), + ] + # fmt: off + expected_diff = ( + """--- \n""" + """+++ \n""" + """@@ -2,4 +2,4 @@\n""" + ''' import smtplib\n''' + ''' import telnetlib\n''' + ''' \n''' + '''-url = "http://example.com"\n''' + '''+url = "https://example.com"\n''' + ) + # fmt: on + expected_line_change = "5" + change_description = SonarUseSecureProtocolsTransformer.change_description diff --git a/src/codemodder/codemods/test/integration_utils.py b/src/codemodder/codemods/test/integration_utils.py index ae191227..4883d8c6 100644 --- a/src/codemodder/codemods/test/integration_utils.py +++ b/src/codemodder/codemods/test/integration_utils.py @@ -99,11 +99,9 @@ def _assert_run_fields(self, run, output_path): assert run[ "commandLine" ] == f'codemodder {self.code_dir} --output {output_path} --codemod-include={self.codemod_instance.id} --path-include={self.code_filename} --path-exclude=""' + ( - f" --sonar-issues-json={self.sonar_issues_json}" - if self.sonar_issues_json - else "" + f" --sonar-json={self.sonar_issues_json}" if self.sonar_issues_json else "" ) + ( - f" --sonar-hotspots-json={self.sonar_hotspots_json}" + f" --sonar-json={self.sonar_hotspots_json}" if self.sonar_hotspots_json else "" ) @@ -142,6 +140,7 @@ def _assert_results_fields(self, results, output_path): change = [ result for result in result["changeset"] if result["path"] == output_path ][0] + print(change["diff"]) assert change["path"] == output_path assert change["diff"] == self.expected_diff @@ -197,9 +196,9 @@ def test_file_rewritten(self, codetf_schema): ] if self.sonar_issues_json: - command.append(f"--sonar-issues-json={self.sonar_issues_json}") + command.append(f"--sonar-json={self.sonar_issues_json}") if self.sonar_hotspots_json: - command.append(f"--sonar-hotspots-json={self.sonar_hotspots_json}") + command.append(f"--sonar-json={self.sonar_hotspots_json}") self.write_original_code() self.write_original_dependencies() diff --git a/src/core_codemods/sonar/sonar_use_secure_protocols.py b/src/core_codemods/sonar/sonar_use_secure_protocols.py index 20a12411..869be3e4 100644 --- a/src/core_codemods/sonar/sonar_use_secure_protocols.py +++ b/src/core_codemods/sonar/sonar_use_secure_protocols.py @@ -1,7 +1,12 @@ import libcst as cst from libcst.codemod import CodemodContext -from codemodder.codemods.base_codemod import Metadata, ReviewGuidance, ToolRule +from codemodder.codemods.base_codemod import ( + Metadata, + ReviewGuidance, + ToolMetadata, + ToolRule, +) from codemodder.codemods.libcst_transformer import ( LibcstResultTransformer, LibcstTransformerPipeline, @@ -188,7 +193,12 @@ def leave_SimpleString( ), Reference(url="https://cwe.mitre.org/data/definitions/200"), Reference(url="https://cwe.mitre.org/data/definitions/319"), - ], + ] + + [Reference(url=tr.url or "", description=tr.name) for tr in rules], + tool=ToolMetadata( + name="Sonar", + rules=rules, + ), ), transformer=LibcstTransformerPipeline(SonarUseSecureProtocolsTransformer), default_extensions=[".py"], diff --git a/tests/samples/sonar_hotspots.json b/tests/samples/sonar_hotspots.json index 897220e9..cf79c044 100644 --- a/tests/samples/sonar_hotspots.json +++ b/tests/samples/sonar_hotspots.json @@ -128,6 +128,26 @@ }, "flows": [], "ruleKey": "python:S5247" + }, + { + "key": "AZSN_hIp0UcGAUz9sZqH", + "component": "pixee_codemodder-python:use_secure_protocols.py", + "project": "pixee_codemodder-python", + "securityCategory": "encrypt-data", + "vulnerabilityProbability": "LOW", + "status": "TO_REVIEW", + "line": 5, + "message": "Using http protocol is insecure. Use https instead", + "creationDate": "2025-01-22T13:20:10+0100", + "updateDate": "2025-01-22T13:29:45+0100", + "textRange": { + "startLine": 5, + "endLine": 5, + "startOffset": 6, + "endOffset": 26 + }, + "flows": [], + "ruleKey": "python:S5332" } ], "components": [ diff --git a/tests/samples/use_secure_protocols.py b/tests/samples/use_secure_protocols.py new file mode 100644 index 00000000..9d0f3511 --- /dev/null +++ b/tests/samples/use_secure_protocols.py @@ -0,0 +1,5 @@ +import ftplib +import smtplib +import telnetlib + +url = "http://example.com"