Custom AntiVirus implementation not working

Thomas Kellerer, modified 5 Years ago. Expert Posts: 490 Join Date: 6/9/08 Recent Posts
We have created an implementation of BaseFileAntivirusScanner to reject certain file types globally in the portal. The necessary jar file is located in Tomcat's ext folder and I can see that my class is instantiated during startup.
I can also see in my logfile that my scan() method is called and that it throws an AntivirusScannerException when the file shouldn't be allowed.
However, the document library still lets me upload the file without any error message.
In portal-ext.properties I have:
dl.store.antivirus.enabled=true
dl.store.antivirus.impl=com.my.package.MimeTypeVirusScanner
Is there anything else I need to configure in order for the document library ("Documents and Media") to reject the file if the scanner throws the exception?
Also: if that did work properly, would it also reject uploads in the Wiki portlet?
I am using Liferay 7.0 GA4
thumbnail
Olaf Kock, modified 5 Years ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts
I've created a simple AV-Implementation in 7.2, but the technique might already work in 7.0:
  • Create a WAR-Hook project
  • Add your AV implementation there
  • edit the Hook's portal.properties to contain the configuration that you've posted above.
Particularly, I'd recommend against mocking around with Tomcat's ext folder, as it requires work to make those classes visible to the OSGi environment. Rather go full plugin.
Unfortunately you'll have to try to port this to 7.0 yourself. What I've done is to rejected a file due to file size - just to have some criteria:

package de.olafkock.liferay.war.av;

import com.liferay.document.library.kernel.antivirus.AntivirusScannerException;
import com.liferay.document.library.kernel.antivirus.BaseFileAntivirusScanner;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import java.io.File;

public class DummyAVfromWarImpl extends BaseFileAntivirusScanner {
	public static final Log log = LogFactoryUtil.getLog(DummyAVfromWarImpl.class);

	@Override
	public void scan(File file) throws AntivirusScannerException {
	    // fatal logging only to show message without configuration for logger
		log.fatal("Fake-AV checking " + file.getName() + " " + file.length() + " " + file.getAbsolutePath());
		if(file.length() > 1000000) {
			log.fatal("fail because file length > 1000000");
			throw new AntivirusScannerException(AntivirusScannerException.VIRUS_DETECTED);
		} else {
			log.fatal("pass because file length <= 1000000"); 
		}
	}
}
Thomas Kellerer, modified 5 Years ago. Expert Posts: 490 Join Date: 6/9/08 Recent Posts
Thanks for the answer.
The WAR hook registers itself correctly, and the scan() method is called. I can also see my exception being thrown in the Liferay log file:
09:06:19,033 ERROR [http-nio-8080-exec-9][MimeTypeVirusScanner:70] Error validating C:\*****\liferay70\tomcat-8.0.32\temp\upload_00000084.exe
com.liferay.document.library.kernel.antivirus.AntivirusScannerException: File C:\*****\liferay70\tomcat-8.0.32\temp\upload_00000084.exe with type application/x-msdownload is not allowed.
        at com.my.package.scanner.MimeTypeVirusScanner.scan(MimeTypeVirusScanner.java:65)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.liferay.portal.kernel.bean.ClassLoaderBeanHandler.invoke(ClassLoaderBeanHandler.java:67)
        at com.sun.proxy.$Proxy723.scan(Unknown Source)
        at com.liferay.document.library.kernel.antivirus.AntivirusScannerWrapper.scan(AntivirusScannerWrapper.java:42)
        at com.liferay.document.library.kernel.antivirus.AntivirusScannerUtil.scan(AntivirusScannerUtil.java:53)
        at com.liferay.portlet.documentlibrary.store.DLStoreImpl.addFile(DLStoreImpl.java:84)
        at com.liferay.portlet.documentlibrary.store.DLStoreImpl.addFile(DLStoreImpl.java:104)
        at com.liferay.document.library.kernel.store.DLStoreUtil.addFile(DLStoreUtil.java:134)
        at com.liferay.portlet.documentlibrary.service.impl.DLFileEntryLocalServiceImpl.addFileEntry(DLFileEntryLocalServiceImpl.java:269)
(the part "File ... application/x-msdownload is not allowed" is the message my class provides when throwing the exception)
But the document library simply ignores the exception from the scanner. It happily stores the file and shows a success message.
So this doesn't seem to work like documented. Is there any other configuration setting I need to change?
thumbnail
Olaf Kock, modified 5 Years ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts
Thomas Kellerer:

But the document library simply ignores the exception from the scanner. It happily stores the file and shows a success message.
So this doesn't seem to work like documented. Is there any other configuration setting I need to change?
That sounds like a bug. As I've said: I've only tried on 7.2, and my file gets rejected with an error message.
You might want to try if you can reproduce on 7.0 GA7 - it might be a fixed issue even on that major version.
Thomas Kellerer, modified 5 Years ago. Expert Posts: 490 Join Date: 6/9/08 Recent Posts
OK, thanks for the answer.
Is upgrading from GA4 to GA7 really that complicated as it is described here?
https://portal.liferay.dev/docs/7-0/deploy/-/knowledge_base/d/running-the-upgrade-process
The upgrade process has never been friendly to us, so we will probably simply drop that check.
thumbnail
Christoph Rabel, modified 5 Years ago. Liferay Legend Posts: 1555 Join Date: 9/24/09 Recent Posts
You could simply give it a try.
Create a copy of the database and run the full upgrade process against it (autoupgrade=true). If it completes without errors, you are pretty much golden. I never bothered with the manual upgrades, I usually just found what caused the issue in the full upgrade and "fixed" it.
In my experience, the upgrade process has become a lot more stable. And upgrading within the same major version is usually no big deal. I would expect it to be as simple as create the upgrade tool config files (which are mostly the path and the db connection string), start the upgrade tool, wait, done.
Thomas Kellerer, modified 5 Years ago. Expert Posts: 490 Join Date: 6/9/08 Recent Posts
How do I upgrade the actual Liferay/Tomcat installation?
Can I just copy the new distribution over the existing? Probably not I guess.
If I can't just copy the new over the old one, then which directories do I have to copy/backup, which ones can be ignored/removed because they will be re-created by Liferay? I can't find anything in the Wiki regarding that
thumbnail
Christoph Rabel, modified 5 Years ago. Liferay Legend Posts: 1555 Join Date: 9/24/09 Recent Posts
You need the data folder, portal-*.properties (Note: Update liferay.home to new path if necessary) and any customizations you did manually, e.g. to setenv.sh and server.xml.
You might also want to check if the properties still work/exist/make sense. Liferay has removed a bunch of them in the last couple of years.
thumbnail
Olaf Kock, modified 5 Years ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts
Thomas Kellerer:

How do I upgrade the actual Liferay/Tomcat installation?
Can I just copy the new distribution over the existing? Probably not I guess.
  1. Restore your backup to a new location. You'll continue to work on this restored installation, which will make you confident that you have a backup in the first place. IMHO you're only allowed to call a backup a backup, if you've recently demonstrated that you can use it to restore a running system
  2. Validate that indeed everything works
  3. Update that new system any way you like. If it fails: Analyze, delete, repeat.