Discussion
Pegasystems Inc.
JP
Last activity: 17 Oct 2023 11:01 EDT
How to dismiss a virus-infected file using an anti-virus software
Hi,
Some customers want to accomplish this requirement: when an operator is trying to attach a file to a case, and if the file is infected with a virus, system should dismiss the file immediately. We know that scanning operation itself is not Pega's job, and it has to be done by external third-party software such as Norton or McAfee, but how exactly can we do it? You may find some articles about out-of-the-box activity called "CallVirusCheck", but this is an extension point and expected to be overridden. However you may not find sample code out there. We had a chance to implement this requirement and in this post, I am sharing how we did it. Please be noted, I do not think our implementation is a typical use case. Rather, I would like this approach to be referenced as just one of many.
1. File attachment procedure (Pega 8.4.1)
First of all, let's review the basic steps to attach a file.
(1) Place a "Attach content" button on a section. End user clicks the button.
(2) A little screen pops up. Click "Select file(s)" button and specify a file(s) from your local machine.
(3) Specified file is displayed as below. At this point, the binary file is transformed into base64 encoded texts and loaded onto a memory (you can find the contents at dragDropFileUpload.pxResults(X) on a clipboard). Click "Attach" button.
(4) A file is attached to a case. At this point, two records are inserted to the database on background. One for PC_LINK_ATTACHMENT table (class: Link-Attachment), and one for PC_DATA_WORKATTACH table (class: Data-WorkAttach-File). Data-WorkAttach-File holds an actual file contents and Link-Attachment works as an intermediate object that associates a work object with Data-WorkAttach-File.
2. How to use CallVirusCheck activity
There is an out-of-the-box activity called "CallVirusCheck" under Data-WorkAttach-File class as below. This is empty by default and you can override it as you need. Ideally, in the Java step, you would want to integrate with your anti-virus software to scan the file. If virus is detected, set strings that start with "Virus" to "VirusCheckStatus" parameter.
For example, if you hardcode "Virus-MyTest" as below, system behaves as if it detects virus every time (of course in the real world you shouldn't do this - you should have a conditional step).
If "Virus" is set to the parameter, system throws an error message "There was an error reported by the virus scan and adding the attachment has failed. If the problem persists, please report it to an administrator." as below. The file won't get attached to a case. Be noted, this "CallVirusCheck" activity is fired after "Attach" button is clicked at step (3), not when a file is selected at step (2).
3. Our implementation
Now, let me talk about how we handled anti-virus use case. First of all, in our case, customer used Trend Micro, that is a Japanese anti-virus software. According to customer, Trend Micro does not have an API to integrate with, and we had to come up with another approach. Secondly, customer used repository (filesystem) for attachments. In that case, when file is attached, the file is saved to the repository instead of the database table (PC_DATA_WORKATTACH). Also, the difference between repository and database is, if repository is used, when file is selected at step (2), the file is uploaded to the Service Export directory at app node temporarily. Then, when "Attach" button is clicked, the file is removed from filesystem and copied to the repository. Trend Micro is installed at all app nodes, and virus-infected files that are uploaded to Service Export are immediately deleted in real time. We took advantage of this - in the "CallVirusCheck" activity Java step, check if the uploaded file exists, if not found, set "Virus" for "VirusCheckStatus" parameter. You will need to follow two steps below.
3-1. Override "CallVirusCheck" activity
Override the out-of-the-box "CallVirusCheck" activity under Data-WorkAttach-File class and add below snippet.
//get attachment file related clipboard page
ClipboardPage cpAttachmentFilePage = tools.findPage("pyNewFileAttachment");
//get attachment file path
String pyAttachmentFilePath = cpAttachmentFilePage.getString("pyFilePath");
//initial PRFile with attachment file path
PRFile prfUploaded = new PRFile(pyAttachmentFilePath);
//check if file exists
if (!prfUploaded.exists()) {
//set param VirusCheckStatus with Virus-XXXXXXXX value. This value should start with [Virus]
tools.putParamValue("VirusCheckStatus","Virus-FileNotExists");
}
The activity should look like this.
* You may wonder, "If file is deleted from Service Export directory by anti-virus software, why should we check it by Java manually? Wouldn't it fail anyways because the file at Service Export is supposed to be moved to repository but it doesn't exist?" Well, it is not quite true. Even if file is deleted, file is still copied to the repository successfully. How? First, PRPC tries to move the file that is at Service Export directory. If it doesn't exist there, then it copies the one that is stored on OS native memory (not Pega's clipboard) to the repository.
3-2. Override "pyUploadFile" activity
Next, overriding "CallVirusCheck" activity is actually not enough. We've found out that image files such as jpg, jpeg, png, gif, bmp, are not copied to Service Export directory. The out-of-the-box "pyUploadFile" activity does this filter (PRPC loads image files onto clipboard by Base64 encoded text and does not copy the file to Service Export directory, while other type of files are treated as Stream and the file is copied to Service Export directory). In order for our approach to work, all files including image must be copied to the filesystem regardless of its file type. Since this activity is not FINAL, we overrode it to disable the filter steps.
- Comment out line 95 "boolean isFileTypeImage...".
- Comment out line 96 "java.util.HashMap hmFileInfo..."
- Copy line 96 and paste it to line 97. Replace the last "isFileTypeImage" with "false".
That's it. Now let's test it.
1. Select a file. Let's select a virus-infected image file.
2. Virus-infected image file is copied to Service Export directory, since image files filter is disabled. Service Export is located under temp\StaticContent\global as below. Trend Micro real time scan detects virus and deletes the file immediately after it is copied to the filesystem.
3. After deletion, clicking "Attach" button fails.
Make sure file attach succeeds if the file is not deleted from Service Export.
Thanks,