CVE-2010-5327 (published 2017-01-13T19:59Z)

Liferay Portal through 6.2.10 allows remote authenticated users to execute arbitrary shell commands via a crafted Velocity template.

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-264
cwe_name: Permissions, Privileges, and Access Controls
description: Weaknesses in this category are related to the management of permissions, privileges, and other security features that are used to perform access control.

Fix information:
repo_url: https://github.com/liferay/liferay-portal
commit_details: repo_url: https://github.com/liferay/liferay-portal
author: Raymond Auge
author_date: 2012-06-08 11:10:10-04:00
msg: LPS-27741 Add security by plugin context execution to template engines

- We have to initialize/destroy a new template context specific to each plugin (keyed by ClassLoader of the plugin)
- Add/Replaced helper utilities to support classloading control (and access to classes/packages) within templates
repository: repo_url: https://github.com/liferay/liferay-portal
repo_name: liferay/liferay-portal
repo_language: Java
owner: liferay
file_changes: filename: HotDeployImpl.java
change_type: ModificationType.MODIFY
diff: @@ -21,6 +21,7 @@ import com.liferay.portal.kernel.deploy.hot.HotDeployListener;
 import com.liferay.portal.kernel.log.Log;
 import com.liferay.portal.kernel.log.LogFactoryUtil;
 import com.liferay.portal.kernel.servlet.ServletContextPool;
+import com.liferay.portal.kernel.template.TemplateManagerUtil;
 import com.liferay.portal.kernel.util.BasePortalLifecycle;
 import com.liferay.portal.kernel.util.HttpUtil;
 import com.liferay.portal.kernel.util.PortalLifecycle;
@@ -105,7 +106,11 @@ public class HotDeployImpl implements HotDeploy {
 		_deployedServletContextNames.remove(
 			hotDeployEvent.getServletContextName());
 
-		PACLPolicyManager.unregister(hotDeployEvent.getContextClassLoader());
+		ClassLoader classLoader = hotDeployEvent.getContextClassLoader();
+
+		TemplateManagerUtil.destroy(classLoader);
+
+		PACLPolicyManager.unregister(classLoader);
 	}
 
 	public void registerListener(HotDeployListener hotDeployListener) {

programming_language: Java
filename: FreeMarkerManager.java
change_type: ModificationType.MODIFY
diff: @@ -22,6 +22,10 @@ import com.liferay.portal.kernel.template.TemplateContextType;
 import com.liferay.portal.kernel.template.TemplateException;
 import com.liferay.portal.kernel.template.TemplateManager;
 import com.liferay.portal.kernel.util.StringPool;
+import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
+import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
+import com.liferay.portal.security.pacl.PACLPolicy;
+import com.liferay.portal.security.pacl.PACLPolicyManager;
 import com.liferay.portal.template.RestrictedTemplate;
 import com.liferay.portal.template.TemplateContextHelper;
 import com.liferay.portal.util.PropsValues;
@@ -35,6 +39,7 @@ import freemarker.template.Configuration;
 import java.io.IOException;
 
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * @author Mika Koivisto
@@ -63,6 +68,10 @@ public class FreeMarkerManager implements TemplateManager {
 			return;
 		}
 
+		_classLoaderHelperUtilities.clear();
+
+		_classLoaderHelperUtilities = null;
+
 		_configuration.clearEncodingMap();
 		_configuration.clearSharedVariables();
 		_configuration.clearTemplateCache();
@@ -84,11 +93,55 @@ public class FreeMarkerManager implements TemplateManager {
 		_templateContextHelper = null;
 	}
 
+	public void destroy(ClassLoader classLoader) {
+		_classLoaderHelperUtilities.remove(classLoader);
+	}
+
 	public Template getTemplate(
 		String templateId, String templateContent, String errorTemplateId,
 		String errorTemplateContent, TemplateContextType templateContextType) {
 
-		if (templateContextType.equals(TemplateContextType.EMPTY)) {
+		if (templateContextType.equals(TemplateContextType.CLASS_LOADER)) {
+
+			// This template will have all of its utilities initialized within
+			// the class loader of the current thread
+
+			ClassLoader contextClassLoader =
+				PACLClassLoaderUtil.getContextClassLoader();
+
+			PACLPolicy threadLocalPACLPolicy =
+				PortalSecurityManagerThreadLocal.getPACLPolicy();
+
+			PACLPolicy contextClassLoaderPACLPolicy =
+				PACLPolicyManager.getPACLPolicy(contextClassLoader);
+
+			try {
+				PortalSecurityManagerThreadLocal.setPACLPolicy(
+					contextClassLoaderPACLPolicy);
+
+				Map<String, Object> helperUtilities =
+					_classLoaderHelperUtilities.get(contextClassLoader);
+
+				if (helperUtilities == null) {
+					helperUtilities =
+						_templateContextHelper.getHelperUtilities();
+
+					_classLoaderHelperUtilities.put(
+						contextClassLoader, helperUtilities);
+				}
+
+				return new PACLFreeMarkerTemplate(
+					templateId, templateContent, errorTemplateId,
+					errorTemplateContent, helperUtilities, _configuration,
+					_templateContextHelper, _stringTemplateLoader,
+					contextClassLoaderPACLPolicy);
+			}
+			finally {
+				PortalSecurityManagerThreadLocal.setPACLPolicy(
+					threadLocalPACLPolicy);
+			}
+		}
+		else if (templateContextType.equals(TemplateContextType.EMPTY)) {
 			return new FreeMarkerTemplate(
 					templateId, templateContent, errorTemplateId,
 					errorTemplateContent, null, _configuration,
@@ -186,6 +239,8 @@ public class FreeMarkerManager implements TemplateManager {
 		_configuration.setDefaultEncoding(StringPool.UTF8);
 		_configuration.setLocalizedLookup(
 			PropsValues.FREEMARKER_ENGINE_LOCALIZED_LOOKUP);
+		_configuration.setNewBuiltinClassResolver(
+			new LiferayTemplateClassResolver());
 		_configuration.setObjectWrapper(new LiferayObjectWrapper());
 		_configuration.setTemplateLoader(multiTemplateLoader);
 		_configuration.setTemplateUpdateDelay(
@@ -217,6 +272,8 @@ public class FreeMarkerManager implements TemplateManager {
 
 	private static Log _log = LogFactoryUtil.getLog(FreeMarkerManager.class);
 
+	private Map<ClassLoader, Map<String, Object>> _classLoaderHelperUtilities =
+		new ConcurrentHashMap<ClassLoader, Map<String, Object>>();
 	private Configuration _configuration;
 	private Map<String, Object> _restrictedHelperUtilities;
 	private Map<String, Object> _standardHelperUtilities;

programming_language: Java
filename: FreeMarkerTemplateContextHelper.java
change_type: ModificationType.MODIFY
diff: @@ -28,8 +28,6 @@ import com.liferay.portal.util.WebKeys;
 
 import freemarker.ext.beans.BeansWrapper;
 
-import freemarker.template.utility.ObjectConstructor;
-
 import java.util.Map;
 import java.util.Set;
 
@@ -52,7 +50,7 @@ public class FreeMarkerTemplateContextHelper extends TemplateContextHelper {
 
 		// Object util
 
-		helperUtilities.put("objectUtil", new ObjectConstructor());
+		helperUtilities.put("objectUtil", new LiferayObjectConstructor());
 
 		// Portlet preferences
 

programming_language: Java
filename: LiferayObjectConstructor.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.freemarker;
+
+import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
+
+import freemarker.ext.beans.BeansWrapper;
+
+import freemarker.template.TemplateMethodModelEx;
+import freemarker.template.TemplateModelException;
+
+import java.util.List;
+
+/**
+ * @author Raymond Augé
+ */
+public class LiferayObjectConstructor implements TemplateMethodModelEx {
+
+	public Object exec(@SuppressWarnings("rawtypes") List arguments)
+		throws TemplateModelException {
+
+		if (arguments.isEmpty()) {
+			throw new TemplateModelException(
+				"This method must have at least one argument as the name of " +
+					"the class to instantiate");
+		}
+
+		Class<?> clazz = null;
+
+		try {
+			String className = String.valueOf(arguments.get(0));
+
+			clazz = Class.forName(
+				className, true, PACLClassLoaderUtil.getContextClassLoader());
+		}
+		catch (Exception e) {
+			throw new TemplateModelException(e.getMessage());
+		}
+
+		BeansWrapper beansWrapper = BeansWrapper.getDefaultInstance();
+
+		Object object = beansWrapper.newInstance(
+			clazz, arguments.subList(1, arguments.size()));
+
+		return beansWrapper.wrap(object);
+	}
+
+}
\ No newline at end of file

programming_language: Java
filename: LiferayTemplateClassResolver.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.freemarker;
+
+import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
+import com.liferay.portal.util.PropsValues;
+
+import freemarker.core.Environment;
+import freemarker.core.TemplateClassResolver;
+
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.utility.ObjectConstructor;
+
+/**
+ * @author Raymond Augé
+ */
+public class LiferayTemplateClassResolver implements TemplateClassResolver {
+
+	public Class<?> resolve(
+			String className, Environment environment, Template template)
+		throws TemplateException {
+
+		if (className.equals(ObjectConstructor.class.getName())) {
+			throw new TemplateException(
+				"Instantiating " + className + " is not allowed in the " +
+					"template for security reasons",
+				environment);
+		}
+
+		for (String restrictedClassName :
+				PropsValues.FREEMARKER_ENGINE_RESTRICTED_CLASSES) {
+
+			if (className.equals(restrictedClassName)) {
+				throw new TemplateException(
+					"Instantiating " + className + " is not allowed in the " +
+						"template for security reasons",
+					environment);
+			}
+		}
+
+		for (String restrictedPackageName :
+				PropsValues.FREEMARKER_ENGINE_RESTRICTED_PACKAGES) {
+
+			if (className.startsWith(restrictedPackageName)) {
+				throw new TemplateException(
+					"Instantiating " + className + " is not allowed in the " +
+						"template for security reasons",
+					environment);
+			}
+		}
+
+		try {
+			return Class.forName(
+				className, true, PACLClassLoaderUtil.getContextClassLoader());
+		}
+		catch (Exception e) {
+			throw new TemplateException(e, environment);
+		}
+	}
+
+}
\ No newline at end of file

programming_language: Java
filename: PACLFreeMarkerTemplate.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.freemarker;
+
+import com.liferay.portal.kernel.template.TemplateException;
+import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
+import com.liferay.portal.security.pacl.PACLPolicy;
+import com.liferay.portal.template.TemplateContextHelper;
+
+import freemarker.template.Configuration;
+
+import java.io.Writer;
+
+import java.util.Map;
+
+/**
+ * @author Raymond Augé
+ */
+public class PACLFreeMarkerTemplate extends FreeMarkerTemplate {
+
+	public PACLFreeMarkerTemplate(
+		String templateId, String templateContent, String errorTemplateId,
+		String errorTemplateContent, Map<String, Object> context,
+		Configuration configuration,
+		TemplateContextHelper templateContextHelper,
+		StringTemplateLoader stringTemplateLoader, PACLPolicy paclPolicy) {
+
+		super(
+			templateId, templateContent, errorTemplateId, errorTemplateContent,
+			context, configuration, templateContextHelper,
+			stringTemplateLoader);
+
+		_paclPolicy = paclPolicy;
+	}
+
+	@Override
+	public boolean processTemplate(Writer writer) throws TemplateException {
+		PACLPolicy initialPolicy =
+			PortalSecurityManagerThreadLocal.getPACLPolicy();
+
+		try {
+			PortalSecurityManagerThreadLocal.setPACLPolicy(_paclPolicy);
+
+			return super.processTemplate(writer);
+		}
+		finally {
+			PortalSecurityManagerThreadLocal.setPACLPolicy(initialPolicy);
+		}
+	}
+
+	private PACLPolicy _paclPolicy;
+
+}
\ No newline at end of file

programming_language: Java
filename: TemplateContextHelper.java
change_type: ModificationType.MODIFY
diff: @@ -19,6 +19,8 @@ import com.liferay.portal.kernel.audit.AuditRouterUtil;
 import com.liferay.portal.kernel.json.JSONFactoryUtil;
 import com.liferay.portal.kernel.language.LanguageUtil;
 import com.liferay.portal.kernel.language.UnicodeLanguageUtil;
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
 import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
 import com.liferay.portal.kernel.templateparser.TemplateContext;
 import com.liferay.portal.kernel.util.ArrayUtil_IW;
@@ -100,23 +102,44 @@ public class TemplateContextHelper {
 
 		// Audit message factory
 
-		variables.put(
-			"auditMessageFactoryUtil",
-			AuditMessageFactoryUtil.getAuditMessageFactory());
+		try {
+			variables.put(
+				"auditMessageFactoryUtil",
+				AuditMessageFactoryUtil.getAuditMessageFactory());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Audit router util
 
-		variables.put("auditRouterUtil", AuditRouterUtil.getAuditRouter());
+		try {
+			variables.put("auditRouterUtil", AuditRouterUtil.getAuditRouter());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Browser sniffer
 
-		variables.put("browserSniffer", BrowserSnifferUtil.getBrowserSniffer());
+		try {
+			variables.put(
+				"browserSniffer", BrowserSnifferUtil.getBrowserSniffer());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Date format
 
-		variables.put(
-			"dateFormatFactory",
-			FastDateFormatFactoryUtil.getFastDateFormatFactory());
+		try {
+			variables.put(
+				"dateFormatFactory",
+				FastDateFormatFactoryUtil.getFastDateFormatFactory());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Date util
 
@@ -124,32 +147,62 @@ public class TemplateContextHelper {
 
 		// Expando column service
 
-		ServiceLocator serviceLocator = ServiceLocator.getInstance();
+		try {
+			ServiceLocator serviceLocator = ServiceLocator.getInstance();
+
+			// Service locator
 
-		variables.put(
-			"expandoColumnLocalService",
-			serviceLocator.findService(
-				ExpandoColumnLocalService.class.getName()));
+			variables.put("serviceLocator", serviceLocator);
+
+			try {
+				variables.put(
+					"expandoColumnLocalService",
+					serviceLocator.findService(
+						ExpandoColumnLocalService.class.getName()));
+			}
+			catch (SecurityException se) {
+				_log.error(se, se);
+			}
 
-		// Expando row service
+			// Expando row service
 
-		variables.put(
-			"expandoRowLocalService",
-			serviceLocator.findService(ExpandoRowLocalService.class.getName()));
+			try {
+				variables.put(
+					"expandoRowLocalService",
+					serviceLocator.findService(
+						ExpandoRowLocalService.class.getName()));
+			}
+			catch (SecurityException se) {
+				_log.error(se, se);
+			}
 
-		// Expando table service
+			// Expando table service
 
-		variables.put(
-			"expandoTableLocalService",
-			serviceLocator.findService(
-				ExpandoTableLocalService.class.getName()));
+			try {
+				variables.put(
+					"expandoTableLocalService",
+					serviceLocator.findService(
+						ExpandoTableLocalService.class.getName()));
+			}
+			catch (SecurityException se) {
+				_log.error(se, se);
+			}
 
-		// Expando value service
+			// Expando value service
 
-		variables.put(
-			"expandoValueLocalService",
-			serviceLocator.findService(
-				ExpandoValueLocalService.class.getName()));
+			try {
+				variables.put(
+					"expandoValueLocalService",
+					serviceLocator.findService(
+						ExpandoValueLocalService.class.getName()));
+			}
+			catch (SecurityException se) {
+				_log.error(se, se);
+			}
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Getter util
 
@@ -157,31 +210,67 @@ public class TemplateContextHelper {
 
 		// Html util
 
-		variables.put("htmlUtil", HtmlUtil.getHtml());
+		try {
+			variables.put("htmlUtil", HtmlUtil.getHtml());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Http util
 
-		variables.put("httpUtil", HttpUtil.getHttp());
+		try {
+			variables.put("httpUtil", HttpUtil.getHttp());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Journal content util
 
-		variables.put(
-			"journalContentUtil", JournalContentUtil.getJournalContent());
+		try {
+			variables.put(
+				"journalContentUtil", JournalContentUtil.getJournalContent());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// JSON factory util
 
-		variables.put("jsonFactoryUtil", JSONFactoryUtil.getJSONFactory());
+		try {
+			variables.put("jsonFactoryUtil", JSONFactoryUtil.getJSONFactory());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Language util
 
-		variables.put("languageUtil", LanguageUtil.getLanguage());
+		try {
+			variables.put("languageUtil", LanguageUtil.getLanguage());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
-		variables.put(
-			"unicodeLanguageUtil", UnicodeLanguageUtil.getUnicodeLanguage());
+		try {
+			variables.put(
+				"unicodeLanguageUtil",
+				UnicodeLanguageUtil.getUnicodeLanguage());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Locale util
 
-		variables.put("localeUtil", LocaleUtil.getInstance());
+		try {
+			variables.put("localeUtil", LocaleUtil.getInstance());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Param util
 
@@ -189,38 +278,80 @@ public class TemplateContextHelper {
 
 		// Portal util
 
-		variables.put("portalUtil", PortalUtil.getPortal());
+		try {
+			variables.put("portalUtil", PortalUtil.getPortal());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
-		variables.put("portal", PortalUtil.getPortal());
+		try {
+			variables.put("portal", PortalUtil.getPortal());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Prefs props util
 
-		variables.put("prefsPropsUtil", PrefsPropsUtil.getPrefsProps());
+		try {
+			variables.put("prefsPropsUtil", PrefsPropsUtil.getPrefsProps());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Props util
 
-		variables.put("propsUtil", PropsUtil.getProps());
+		try {
+			variables.put("propsUtil", PropsUtil.getProps());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Portlet URL factory
 
-		variables.put(
-			"portletURLFactory", PortletURLFactoryUtil.getPortletURLFactory());
+		try {
+			variables.put(
+				"portletURLFactory",
+				PortletURLFactoryUtil.getPortletURLFactory());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Randomizer
 
-		variables.put(
-			"randomizer", Randomizer_IW.getInstance().getWrappedInstance());
+		try {
+			variables.put(
+				"randomizer", Randomizer_IW.getInstance().getWrappedInstance());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
-		// SAX reader util
+		try {
+			UtilLocator utilLocator = UtilLocator.getInstance();
 
-		UtilLocator utilLocator = UtilLocator.getInstance();
+			// Util locator
 
-		variables.put(
-			"saxReaderUtil", utilLocator.findUtil(SAXReader.class.getName()));
+			variables.put("utilLocator", utilLocator);
 
-		// Service locator
+			// SAX reader util
 
-		variables.put("serviceLocator", serviceLocator);
+			try {
+				variables.put(
+					"saxReaderUtil",
+					utilLocator.findUtil(SAXReader.class.getName()));
+			}
+			catch (SecurityException se) {
+				_log.error(se, se);
+			}
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Session clicks
 
@@ -238,10 +369,6 @@ public class TemplateContextHelper {
 
 		variables.put("timeZoneUtil", TimeZoneUtil_IW.getInstance());
 
-		// Util locator
-
-		variables.put("utilLocator", utilLocator);
-
 		// Unicode formatter
 
 		variables.put("unicodeFormatter", UnicodeFormatter_IW.getInstance());
@@ -252,46 +379,138 @@ public class TemplateContextHelper {
 
 		// Web server servlet token
 
-		variables.put(
-			"webServerToken",
-			WebServerServletTokenUtil.getWebServerServletToken());
+		try {
+			variables.put(
+				"webServerToken",
+				WebServerServletTokenUtil.getWebServerServletToken());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Permissions
 
-		variables.put(
-			"accountPermission", AccountPermissionUtil.getAccountPermission());
-		variables.put(
-			"commonPermission", CommonPermissionUtil.getCommonPermission());
-		variables.put(
-			"groupPermission", GroupPermissionUtil.getGroupPermission());
-		variables.put(
-			"layoutPermission", LayoutPermissionUtil.getLayoutPermission());
-		variables.put(
-			"organizationPermission",
-			OrganizationPermissionUtil.getOrganizationPermission());
-		variables.put(
-			"passwordPolicyPermission",
-			PasswordPolicyPermissionUtil.getPasswordPolicyPermission());
-		variables.put(
-			"portalPermission", PortalPermissionUtil.getPortalPermission());
-		variables.put(
-			"portletPermission", PortletPermissionUtil.getPortletPermission());
-		variables.put("rolePermission", RolePermissionUtil.getRolePermission());
-		variables.put(
-			"userGroupPermission",
-			UserGroupPermissionUtil.getUserGroupPermission());
-		variables.put("userPermission", UserPermissionUtil.getUserPermission());
+		try {
+			variables.put(
+				"accountPermission",
+				AccountPermissionUtil.getAccountPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"commonPermission", CommonPermissionUtil.getCommonPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"groupPermission", GroupPermissionUtil.getGroupPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"layoutPermission", LayoutPermissionUtil.getLayoutPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"organizationPermission",
+				OrganizationPermissionUtil.getOrganizationPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"passwordPolicyPermission",
+				PasswordPolicyPermissionUtil.getPasswordPolicyPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"portalPermission", PortalPermissionUtil.getPortalPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"portletPermission",
+				PortletPermissionUtil.getPortletPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"rolePermission", RolePermissionUtil.getRolePermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"userGroupPermission",
+				UserGroupPermissionUtil.getUserGroupPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"userPermission", UserPermissionUtil.getUserPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		// Deprecated
 
-		variables.put(
-			"dateFormats",
-			FastDateFormatFactoryUtil.getFastDateFormatFactory());
-		variables.put(
-			"imageToken", WebServerServletTokenUtil.getWebServerServletToken());
-		variables.put(
-			"locationPermission",
-			OrganizationPermissionUtil.getOrganizationPermission());
+		try {
+			variables.put(
+				"dateFormats",
+				FastDateFormatFactoryUtil.getFastDateFormatFactory());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"imageToken",
+				WebServerServletTokenUtil.getWebServerServletToken());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
+
+		try {
+			variables.put(
+				"locationPermission",
+				OrganizationPermissionUtil.getOrganizationPermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		return variables;
 	}
@@ -486,4 +705,7 @@ public class TemplateContextHelper {
 		templateContext.put("tilesSelectable", tilesSelectable);
 	}
 
+	private static Log _log = LogFactoryUtil.getLog(
+		TemplateContextHelper.class);
+
 }
\ No newline at end of file

programming_language: Java
filename: PropsValues.java
change_type: ModificationType.MODIFY
diff: @@ -608,6 +608,10 @@ public class PropsValues {
 
 	public static final int FREEMARKER_ENGINE_MODIFICATION_CHECK_INTERVAL = GetterUtil.getInteger(PropsUtil.get(PropsKeys.FREEMARKER_ENGINE_MODIFICATION_CHECK_INTERVAL));
 
+	public static final String[] FREEMARKER_ENGINE_RESTRICTED_CLASSES = PropsUtil.getArray(PropsKeys.FREEMARKER_ENGINE_RESTRICTED_CLASSES);
+
+	public static final String[] FREEMARKER_ENGINE_RESTRICTED_PACKAGES = PropsUtil.getArray(PropsKeys.FREEMARKER_ENGINE_RESTRICTED_PACKAGES);
+
 	public static final String FREEMARKER_ENGINE_TEMPLATE_EXCEPTION_HANDLER = PropsUtil.get(PropsKeys.FREEMARKER_ENGINE_TEMPLATE_EXCEPTION_HANDLER);
 
 	public static final String[] FREEMARKER_ENGINE_TEMPLATE_LOADERS = PropsUtil.getArray(PropsKeys.FREEMARKER_ENGINE_TEMPLATE_LOADERS);
@@ -1644,6 +1648,10 @@ public class PropsValues {
 
 	public static final int VELOCITY_ENGINE_RESOURCE_MANAGER_MODIFICATION_CHECK_INTERVAL = GetterUtil.getInteger(PropsUtil.get(PropsKeys.VELOCITY_ENGINE_RESOURCE_MANAGER_MODIFICATION_CHECK_INTERVAL));
 
+	public static final String[] VELOCITY_ENGINE_RESTRICTED_CLASSES = PropsUtil.getArray(PropsKeys.VELOCITY_ENGINE_RESTRICTED_CLASSES);
+
+	public static final String[] VELOCITY_ENGINE_RESTRICTED_PACKAGES = PropsUtil.getArray(PropsKeys.VELOCITY_ENGINE_RESTRICTED_PACKAGES);
+
 	public static final String VIRTUAL_HOSTS_DEFAULT_SITE_NAME = PropsUtil.get(PropsKeys.VIRTUAL_HOSTS_DEFAULT_SITE_NAME);
 
 	public static final String[] VIRTUAL_HOSTS_IGNORE_EXTENSIONS = PropsUtil.getArray(PropsKeys.VIRTUAL_HOSTS_IGNORE_EXTENSIONS);

programming_language: Java
filename: LiferayMethodExceptionEventHandler.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.velocity;
+
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
+
+import org.apache.velocity.app.event.MethodExceptionEventHandler;
+
+/**
+ * @author Raymond Augé
+ */
+public class LiferayMethodExceptionEventHandler
+	implements MethodExceptionEventHandler {
+
+	public Object methodException(
+			@SuppressWarnings("rawtypes") Class clazz, String method,
+			Exception e)
+		throws Exception {
+
+		_log.error(e, e);
+
+		return null;
+	}
+
+	private static Log _log = LogFactoryUtil.getLog(
+		LiferayMethodExceptionEventHandler.class);
+
+}
\ No newline at end of file

programming_language: Java
filename: PACLVelocityTemplate.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.velocity;
+
+import com.liferay.portal.kernel.template.TemplateException;
+import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
+import com.liferay.portal.security.pacl.PACLPolicy;
+import com.liferay.portal.template.TemplateContextHelper;
+
+import java.io.Writer;
+
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * @author Raymond Augé
+ */
+public class PACLVelocityTemplate extends VelocityTemplate {
+
+	public PACLVelocityTemplate(
+		String templateId, String templateContent, String errorTemplateId,
+		String errorTemplateContent, VelocityContext velocityContext,
+		VelocityEngine velocityEngine,
+		TemplateContextHelper templateContextHelper, PACLPolicy paclPolicy) {
+
+		super(
+			templateId, templateContent, errorTemplateId, errorTemplateContent,
+			velocityContext, velocityEngine, templateContextHelper);
+
+		_paclPolicy = paclPolicy;
+	}
+
+	@Override
+	public boolean processTemplate(Writer writer) throws TemplateException {
+		PACLPolicy initialPolicy =
+			PortalSecurityManagerThreadLocal.getPACLPolicy();
+
+		try {
+			PortalSecurityManagerThreadLocal.setPACLPolicy(_paclPolicy);
+
+			return super.processTemplate(writer);
+		}
+		finally {
+			PortalSecurityManagerThreadLocal.setPACLPolicy(initialPolicy);
+		}
+	}
+
+	private PACLPolicy _paclPolicy;
+
+}
\ No newline at end of file

programming_language: Java
filename: VelocityManager.java
change_type: ModificationType.MODIFY
diff: @@ -19,18 +19,26 @@ import com.liferay.portal.kernel.template.TemplateContextType;
 import com.liferay.portal.kernel.template.TemplateException;
 import com.liferay.portal.kernel.template.TemplateManager;
 import com.liferay.portal.kernel.util.PropsKeys;
+import com.liferay.portal.kernel.util.StringUtil;
+import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
+import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
+import com.liferay.portal.security.pacl.PACLPolicy;
+import com.liferay.portal.security.pacl.PACLPolicyManager;
 import com.liferay.portal.template.RestrictedTemplate;
 import com.liferay.portal.template.TemplateContextHelper;
 import com.liferay.portal.util.PropsUtil;
 import com.liferay.portal.util.PropsValues;
 
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.commons.collections.ExtendedProperties;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
 import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
 import org.apache.velocity.runtime.resource.util.StringResourceRepository;
+import org.apache.velocity.util.introspection.SecureUberspector;
 
 /**
  * @author Raymond Augé
@@ -65,17 +73,71 @@ public class VelocityManager implements TemplateManager {
 	public void destroy() {
 		StringResourceLoader.clearRepositories();
 
+		_classLoaderVelocityContexts.clear();
+
+		_classLoaderVelocityContexts = null;
 		_restrictedVelocityContext = null;
 		_standardVelocityContext = null;
 		_velocityEngine = null;
 		_templateContextHelper = null;
 	}
 
+	public void destroy(ClassLoader classLoader) {
+		_classLoaderVelocityContexts.remove(classLoader);
+	}
+
 	public Template getTemplate(
 		String templateId, String templateContent, String errorTemplateId,
 		String errorTemplateContent, TemplateContextType templateContextType) {
 
-		if (templateContextType.equals(TemplateContextType.EMPTY)) {
+		if (templateContextType.equals(TemplateContextType.CLASS_LOADER)) {
+
+			// This template will have all of its utilities initialized within
+			// the class loader of the current thread
+
+			ClassLoader contextClassLoader =
+				PACLClassLoaderUtil.getContextClassLoader();
+
+			PACLPolicy threadLocalPACLPolicy =
+				PortalSecurityManagerThreadLocal.getPACLPolicy();
+
+			PACLPolicy contextClassLoaderPACLPolicy =
+				PACLPolicyManager.getPACLPolicy(contextClassLoader);
+
+			try {
+				PortalSecurityManagerThreadLocal.setPACLPolicy(
+					contextClassLoaderPACLPolicy);
+
+				VelocityContext velocityContext =
+					_classLoaderVelocityContexts.get(contextClassLoader);
+
+				if (velocityContext == null) {
+					velocityContext = new VelocityContext();
+
+					Map<String, Object> helperUtilities =
+						_templateContextHelper.getHelperUtilities();
+
+					for (Map.Entry<String, Object> entry :
+							helperUtilities.entrySet()) {
+
+						velocityContext.put(entry.getKey(), entry.getValue());
+					}
+
+					_classLoaderVelocityContexts.put(
+						contextClassLoader, velocityContext);
+				}
+
+				return new PACLVelocityTemplate(
+					templateId, templateContent, errorTemplateId,
+					errorTemplateContent, velocityContext, _velocityEngine,
+					_templateContextHelper, contextClassLoaderPACLPolicy);
+			}
+			finally {
+				PortalSecurityManagerThreadLocal.setPACLPolicy(
+					threadLocalPACLPolicy);
+			}
+		}
+		else if (templateContextType.equals(TemplateContextType.EMPTY)) {
 			return new VelocityTemplate(
 				templateId, templateContent, errorTemplateId,
 				errorTemplateContent, null, _velocityEngine,
@@ -142,30 +204,43 @@ public class VelocityManager implements TemplateManager {
 
 		ExtendedProperties extendedProperties = new FastExtendedProperties();
 
-		extendedProperties.setProperty(_RESOURCE_LOADER, "string,servlet");
+		extendedProperties.setProperty(
+			VelocityEngine.EVENTHANDLER_METHODEXCEPTION,
+			LiferayMethodExceptionEventHandler.class.getName());
 
 		extendedProperties.setProperty(
-			"string." + _RESOURCE_LOADER + ".cache",
-			String.valueOf(
-				PropsValues.VELOCITY_ENGINE_RESOURCE_MANAGER_CACHE_ENABLED));
+			RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,
+			StringUtil.merge(PropsValues.VELOCITY_ENGINE_RESTRICTED_CLASSES));
 
 		extendedProperties.setProperty(
-			"string." + _RESOURCE_LOADER + ".class",
-			StringResourceLoader.class.getName());
+			RuntimeConstants.INTROSPECTOR_RESTRICT_PACKAGES,
+			StringUtil.merge(PropsValues.VELOCITY_ENGINE_RESTRICTED_PACKAGES));
 
 		extendedProperties.setProperty(
-			"string." + _RESOURCE_LOADER + ".repository.class",
-			StringResourceRepositoryImpl.class.getName());
+			VelocityEngine.RESOURCE_LOADER, "string,servlet");
 
 		extendedProperties.setProperty(
-			"servlet." + _RESOURCE_LOADER + ".cache",
+			"servlet." + VelocityEngine.RESOURCE_LOADER + ".cache",
 			String.valueOf(
 				PropsValues.VELOCITY_ENGINE_RESOURCE_MANAGER_CACHE_ENABLED));
 
 		extendedProperties.setProperty(
-			"servlet." + _RESOURCE_LOADER + ".class",
+			"servlet." + VelocityEngine.RESOURCE_LOADER + ".class",
 			LiferayResourceLoader.class.getName());
 
+		extendedProperties.setProperty(
+			"string." + VelocityEngine.RESOURCE_LOADER + ".cache",
+			String.valueOf(
+				PropsValues.VELOCITY_ENGINE_RESOURCE_MANAGER_CACHE_ENABLED));
+
+		extendedProperties.setProperty(
+			"string." + VelocityEngine.RESOURCE_LOADER + ".class",
+			StringResourceLoader.class.getName());
+
+		extendedProperties.setProperty(
+			"string." + VelocityEngine.RESOURCE_LOADER + ".repository.class",
+			StringResourceRepositoryImpl.class.getName());
+
 		extendedProperties.setProperty(
 			VelocityEngine.RESOURCE_MANAGER_CLASS,
 			PropsUtil.get(PropsKeys.VELOCITY_ENGINE_RESOURCE_MANAGER));
@@ -174,6 +249,18 @@ public class VelocityManager implements TemplateManager {
 			VelocityEngine.RESOURCE_MANAGER_CACHE_CLASS,
 			PropsUtil.get(PropsKeys.VELOCITY_ENGINE_RESOURCE_MANAGER_CACHE));
 
+		extendedProperties.setProperty(
+			VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS,
+			PropsUtil.get(PropsKeys.VELOCITY_ENGINE_LOGGER));
+
+		extendedProperties.setProperty(
+			VelocityEngine.RUNTIME_LOG_LOGSYSTEM + ".log4j.category",
+			PropsUtil.get(PropsKeys.VELOCITY_ENGINE_LOGGER_CATEGORY));
+
+		extendedProperties.setProperty(
+			RuntimeConstants.UBERSPECT_CLASSNAME,
+			SecureUberspector.class.getName());
+
 		extendedProperties.setProperty(
 			VelocityEngine.VM_LIBRARY,
 			PropsUtil.get(PropsKeys.VELOCITY_ENGINE_VELOCIMACRO_LIBRARY));
@@ -188,14 +275,6 @@ public class VelocityManager implements TemplateManager {
 			String.valueOf(
 				!PropsValues.VELOCITY_ENGINE_RESOURCE_MANAGER_CACHE_ENABLED));
 
-		extendedProperties.setProperty(
-			VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS,
-			PropsUtil.get(PropsKeys.VELOCITY_ENGINE_LOGGER));
-
-		extendedProperties.setProperty(
-			VelocityEngine.RUNTIME_LOG_LOGSYSTEM + ".log4j.category",
-			PropsUtil.get(PropsKeys.VELOCITY_ENGINE_LOGGER_CATEGORY));
-
 		_velocityEngine.setExtendedProperties(extendedProperties);
 
 		try {
@@ -229,9 +308,8 @@ public class VelocityManager implements TemplateManager {
 		_templateContextHelper = templateContextHelper;
 	}
 
-	private static final String _RESOURCE_LOADER =
-		VelocityEngine.RESOURCE_LOADER;
-
+	private Map<ClassLoader, VelocityContext> _classLoaderVelocityContexts =
+		new ConcurrentHashMap<ClassLoader, VelocityContext>();
 	private VelocityContext _restrictedVelocityContext;
 	private VelocityContext _standardVelocityContext;
 	private TemplateContextHelper _templateContextHelper;

programming_language: Java
filename: VelocityTemplateContextHelper.java
change_type: ModificationType.MODIFY
diff: @@ -14,6 +14,8 @@
 
 package com.liferay.portal.velocity;
 
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
 import com.liferay.portal.kernel.templateparser.TemplateContext;
 import com.liferay.portal.kernel.util.GetterUtil;
 import com.liferay.portal.kernel.util.SetUtil;
@@ -84,8 +86,13 @@ public class VelocityTemplateContextHelper extends TemplateContextHelper {
 
 		// Permissions
 
-		velocityContext.put(
-			"rolePermission", RolePermissionUtil.getRolePermission());
+		try {
+			velocityContext.put(
+				"rolePermission", RolePermissionUtil.getRolePermission());
+		}
+		catch (SecurityException se) {
+			_log.error(se, se);
+		}
 
 		return velocityContext;
 	}
@@ -159,4 +166,7 @@ public class VelocityTemplateContextHelper extends TemplateContextHelper {
 		}
 	}
 
+	private static Log _log = LogFactoryUtil.getLog(
+		VelocityTemplateContextHelper.class);
+
 }
\ No newline at end of file

programming_language: Java
filename: portal.properties
change_type: ModificationType.MODIFY
diff: @@ -5592,6 +5592,21 @@
     freemarker.engine.localized.lookup=false
     freemarker.engine.modification.check.interval=60
 
+    #
+    # Set a comma delimited list of java classes the FreeMarker engine cannot
+    # have access to.
+    #
+    freemarker.engine.restricted.classes=\
+        java.lang.Class,\
+        java.lang.ClassLoader,\
+        java.lang.Thread
+
+    #
+    # Set a comma delimited list of java packages the FreeMarker engine cannot
+    # have access to.
+    #
+    freemarker.engine.restricted.packages=
+
     #
     # Exception handler can have it's value set to the name of a class
     # implementing FreeMarker TemplateExceptionHandler or rethrow, debug,
@@ -6753,6 +6768,21 @@
     velocity.engine.resource.manager.cache.enabled=true
     #velocity.engine.resource.manager.modification.check.interval=0
 
+    #
+    # Set a comma delimited list of java classes the Velocity engine cannot have
+    # access to.
+    #
+    velocity.engine.restricted.classes=\
+        java.lang.Class,\
+        java.lang.ClassLoader,\
+        java.lang.Thread
+
+    #
+    # Set a comma delimited list of java packages the Velocity engine cannot
+    # have access to.
+    #
+    velocity.engine.restricted.packages=
+
     #
     # Input a list of comma delimited macros that will be loaded. These files
     # must exist in the class path.

programming_language: Python
filename: TemplateManager.java
change_type: ModificationType.MODIFY
diff: @@ -29,6 +29,8 @@ public interface TemplateManager {
 
 	public void destroy();
 
+	public void destroy(ClassLoader classLoader);
+
 	public Template getTemplate(
 		String templateId, String templateContent, String errorTemplateId,
 		String errorTemplateContent, TemplateContextType templateContextType);

programming_language: Java
filename: TemplateManagerUtil.java
change_type: ModificationType.MODIFY
diff: @@ -56,6 +56,14 @@ public class TemplateManagerUtil {
 		templateManagers.clear();
 	}
 
+	public static void destroy(ClassLoader classLoader) {
+		Map<String, TemplateManager> templateManagers = _getTemplateManagers();
+
+		for (TemplateManager templateManager : templateManagers.values()) {
+			templateManager.destroy(classLoader);
+		}
+	}
+
 	public static Template getTemplate(
 			String templateManagerName, String templateId,
 			String templateContent, String errorTemplateId,

programming_language: Java
filename: PropsKeys.java
change_type: ModificationType.MODIFY
diff: @@ -749,6 +749,10 @@ public interface PropsKeys {
 
 	public static final String FREEMARKER_ENGINE_MODIFICATION_CHECK_INTERVAL = "freemarker.engine.modification.check.interval";
 
+	public static final String FREEMARKER_ENGINE_RESTRICTED_CLASSES = "freemarker.engine.restricted.classes";
+
+	public static final String FREEMARKER_ENGINE_RESTRICTED_PACKAGES = "freemarker.engine.restricted.packages";
+
 	public static final String FREEMARKER_ENGINE_TEMPLATE_EXCEPTION_HANDLER = "freemarker.engine.template.exception.handler";
 
 	public static final String FREEMARKER_ENGINE_TEMPLATE_LOADERS = "freemarker.engine.template.loaders";
@@ -2227,6 +2231,10 @@ public interface PropsKeys {
 
 	public static final String VELOCITY_ENGINE_RESOURCE_MANAGER_MODIFICATION_CHECK_INTERVAL = "velocity.engine.resource.manager.modification.check.interval";
 
+	public static final String VELOCITY_ENGINE_RESTRICTED_CLASSES = "velocity.engine.restricted.classes";
+
+	public static final String VELOCITY_ENGINE_RESTRICTED_PACKAGES = "velocity.engine.restricted.packages";
+
 	public static final String VELOCITY_ENGINE_VELOCIMACRO_LIBRARY = "velocity.engine.velocimacro.library";
 
 	public static final String VERIFY_FREQUENCY = "verify.frequency";

programming_language: Java