{"id":60489,"date":"2024-03-08T15:42:47","date_gmt":"2024-03-08T10:12:47","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=60489"},"modified":"2024-03-12T15:46:48","modified_gmt":"2024-03-12T10:16:48","slug":"clamav-antivirus-scanner-for-file-uploads-for-python-applications","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/clamav-antivirus-scanner-for-file-uploads-for-python-applications\/","title":{"rendered":"ClamAV Antivirus scanner for file uploads for Python applications"},"content":{"rendered":"<h2><b>Introduction<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">ClamAV is an open-source antivirus engine designed for detecting trojans, viruses, malware, and other malicious threats on Unix-based systems. Initially developed for email scanning on Unix-based systems like Linux, it has evolved into a comprehensive antivirus solution for a variety of platforms, including Windows and macOS. Known for its reliability, ease of use, and frequent updates, ClamAV has become a popular choice for both individual users and organizations seeking effective protection against cyber threats.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Clamd is a portable Python module to uses the ClamAV anti-virus engine on Windows, Linux, MacOSX, and other platforms. It requires a running instance of the clamd daemon. The below steps will provide details on how to install ClamAV and how it can be used with Python applications.<\/span><\/p>\n<h2><strong>Technical implementation<\/strong><\/h2>\n<p><strong>Step 1.<\/strong>\u00a0<span style=\"font-weight: 400;\">Open the terminal and <\/span><span style=\"font-weight: 400;\">install ClamAV in Local using cmd for macOS <\/span><span style=\"font-weight: 400;\">brew install ClamAV<\/span><\/p>\n<p><b>Step 2:<\/b> <span style=\"font-weight: 400;\">Go to the path in macOS <\/span><span style=\"font-weight: 400;\">cd \/opt\/homebrew\/etc\/clamav\/<\/span><span style=\"font-weight: 400;\"> , which will have two sample files\u00a0<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">clamd.conf.sample<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">freshclam.conf.sample<\/span><\/li>\n<\/ol>\n<p><b>Step 3:<\/b><span style=\"font-weight: 400;\"> Run cmd. &#8220;<\/span><span style=\"font-weight: 400;\">cp freshclam.conf.sample freshclam.conf&#8221;<\/span><span style=\"font-weight: 400;\"> to copy and open the file that was just created and comment out Example -&gt; #Example.<\/span><\/p>\n<p><b>Step 4:<\/b><span style=\"font-weight: 400;\"> Open the terminal <\/span><span style=\"font-weight: 400;\">and update the ClamAV database using &#8220;<\/span><span style=\"font-weight: 400;\">freshclam -v&#8221;<\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>Step 5:<\/b><span style=\"font-weight: 400;\"> Run cmd. &#8220;<\/span><span style=\"font-weight: 400;\">cp clamd.conf.sample\u00a0 clamd.conf&#8221;\u00a0 <\/span><span style=\"font-weight: 400;\">to copy and open the file that was just created and apply the below changes<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Comment out Example -&gt; #Example<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Uncomment TCPSocket<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Uncomment TCPAddr<\/span><\/li>\n<\/ol>\n<p><b>Step 6:<\/b><span style=\"font-weight: 400;\"> Now that we have installed and setup ClamAV and to run ClamAV in local <\/span><span style=\"font-weight: 400;\">clamd \u2013foreground<\/span><span style=\"font-weight: 400;\">, this will run the ClamAV service on\u00a0<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">HOST = localhost\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">PORT = 3310<\/span><\/li>\n<\/ul>\n<p><b>Step 7:<\/b><span style=\"font-weight: 400;\"> Now, in your application, install ClamAV python package using the below command.\u00a0 <\/span><\/p>\n<pre><span style=\"font-weight: 400;\">pip install clamd==1.0.2<\/span><\/pre>\n<p><strong>Step 8:<\/strong> Once installed, import the package in your app as below to scan files in a specific path.<\/p>\n<blockquote>\n<pre>import clamd\r\n\r\ndef scan_file_using_file_path():\r\n    cd = clamd.ClamdNetworkSocket()\r\n    cd.__init__(host='127.0.0.1', port=3310, timeout=100)\r\n    cwd = os.getcwd()\r\n    for file in os.listdir(\"files\"):\r\n        directory = os.path.join(cwd, f\"files\/{file}\")\r\n        res = cd.scan(file=directory)\r\n        print(res)\r\n\r\nscan_file_using_file_path()\r\n\r\nResults:<\/pre>\n<pre>{'\/Users\/PycharmProjects\/ClamAVAntivirus\/files\/test_xls.xlsx': ('OK', None)}\r\n{'\/Users\/\/PycharmProjects\/ClamAVAntivirus\/files\/users.txt': ('OK', None)}\r\n{'\/Users\/PycharmProjects\/ClamAVAntivirus\/files\/testfile.txt': ('FOUND', 'Win.Test.EICAR_HDB-1')}\r\n{'\/Users\/PycharmProjects\/ClamAVAntivirus\/files\/test_pdf.pdf': ('OK', None)}\r\n{'\/Users\/PycharmProjects\/ClamAVAntivirus\/files\/image.jpg': ('OK', None)}\r\n\r\nProcess finished with exit code 0<\/pre>\n<\/blockquote>\n<p>After scanning through the files, it will report if any malicious item is found. Below is an example to scan a file if the input is in the form of a stream.<\/p>\n<blockquote>\n<pre>from io import BytesIO\r\n\r\ndef scan_file_using_byte_stream():\r\n    with open(\"files\/testfile.txt\", \"rb\") as fh:\r\n        buf = BytesIO(fh.read())\r\n        try:\r\n            res = antivirus_scanner.scan_stream(stream=buf)\r\n        except (AntivirusScannerException, MaliciousContentException) as e:\r\n            print(e)\r\n        else:\r\n            if res == \"OK\":\r\n                print(\"File scanned successfully, no potential malware found\")\r\n            else:\r\n                print(\"Something went wrong!!!\")\r\n\r\n\r\nscan_file_using_byte_stream()\r\n\r\nResults:<\/pre>\n<p>***** Malicious content found in file scanning, reason: Win.Test.EICAR_HDB-1 *****<\/p>\n<p>Process finished with exit code 0<\/p><\/blockquote>\n<p><strong><span style=\"font-size: 1rem;\">Class to connect to ClamAV service<\/span><\/strong><\/p>\n<blockquote>\n<pre>from io import BytesIO\r\nfrom typing import Optional, Tuple\r\nimport clamd\r\n\r\n\r\nclass AntivirusScannerException(Exception):\r\n    pass\r\n\r\n\r\nclass MaliciousContentException(AntivirusScannerException):\r\n    def __init__(self, reason: str):\r\n        super().__init__(f\"Malicious content found in file scanning, reason: {reason}\")\r\n\r\n\r\nclass InvalidScanResultStatus(AntivirusScannerException):\r\n    def __init__(self, status: str):\r\n        super().__init__(f\"Undefined status returned from antivirus scanner: {status}\")\r\n\r\n\r\nclass ClamAvScanner:\r\n    _CONNECTION_TIMEOUT = 60\r\n    _DEFAULT_PORT = 3310\r\n    _MALICIOUS_STATUSES = frozenset((\"ERROR\", \"FOUND\"))\r\n\r\n    def __init__(self, hostname: str, port: Optional[int]):\r\n        self._hostname = hostname\r\n        self._port = port or self._DEFAULT_PORT\r\n\r\n    def scan_stream(self, stream: BytesIO):\r\n        connection = self._init_connection()\r\n        try:\r\n            output = connection.instream(stream)\r\n        except (clamd.BufferTooLongError, clamd.ConnectionError) as exc:\r\n            raise AntivirusScannerException(\r\n                \"Unable to scan stream due to internal issues\"\r\n            ) from exc\r\n\r\n        return self._output(output[\"stream\"])\r\n\r\n    def _init_connection(self) -&gt; clamd.ClamdNetworkSocket:\r\n        return clamd.ClamdNetworkSocket(\r\n            host=self._hostname,\r\n            port=self._port,\r\n            timeout=self._CONNECTION_TIMEOUT,\r\n        )\r\n\r\n    def _output(self, output: Tuple[str, str]):\r\n        status, reason = output\r\n        if status in self._MALICIOUS_STATUSES:\r\n            raise MaliciousContentException(reason)\r\n        if status != \"OK\":\r\n            raise InvalidScanResultStatus(status)\r\n        if status == \"OK\":\r\n            return \"OK\"\r\n\r\n\r\nantivirus_scanner = ClamAvScanner(hostname=\"127.0.0.1\", port=3310)<\/pre>\n<\/blockquote>\n<p><span style=\"font-weight: 400;\">To determine what virus is associated with a file detected by ClamAV, you can usually check the scan report generated by ClamAV after it completes a scan. The report should list the name or identifier of the detected virus or malware and information about the affected file. Additionally, you can search for the specific virus name or identifier online to find more information about its characteristics and potential impact.<\/span><\/p>\n<p><strong>Links:<\/strong><\/p>\n<ul>\n<li>https:\/\/pypi.org\/project\/clamd\/<\/li>\n<\/ul>\n<p><b>Some best practices:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Filtering or allowing only required file formats while uploading.(ex: .pdf, .jpeg, .xlsx)<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Scanning files for potential malware before storing.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Limiting max file size.<\/span><\/li>\n<\/ul>\n<h2><b>Conclusion<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">In conclusion, ClamAV continues to be a trusted antivirus solution, providing essential protection against a wide range of malicious threats across multiple platforms. With its open-source nature, frequent updates, and robust detection capabilities, ClamAV remains a valuable tool in the fight against malware. Whether you&#8217;re an individual user or a large organization, integrating ClamAV into your cybersecurity strategy can help safeguard your systems and data from the ever-evolving landscape of cyber threats.<\/span><\/p>\n<div class=\"ap-custom-wrapper\"><\/div><!--ap-custom-wrapper-->","protected":false},"excerpt":{"rendered":"<p>Introduction ClamAV is an open-source antivirus engine designed for detecting trojans, viruses, malware, and other malicious threats on Unix-based systems. Initially developed for email scanning on Unix-based systems like Linux, it has evolved into a comprehensive antivirus solution for a variety of platforms, including Windows and macOS. Known for its reliability, ease of use, and [&hellip;]<\/p>\n","protected":false},"author":1729,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":882},"categories":[1994],"tags":[5680,5681,5682,5683,1358],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60489"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1729"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=60489"}],"version-history":[{"count":3,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60489\/revisions"}],"predecessor-version":[{"id":60817,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60489\/revisions\/60817"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=60489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=60489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=60489"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}