You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by is...@apache.org on 2020/01/13 14:13:32 UTC

[lucene-solr] branch branch_7_7 updated (3aad331 -> 1b21ba7)

This is an automated email from the ASF dual-hosted git repository.

ishan pushed a change to branch branch_7_7
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git.


    from 3aad331  SOLR-13793: Limiting number of forwards to total replicas in collection to avoid deadly forwarding loops
     new 2937630  Provided the patch for solr-13971 for 7.7
     new 1b21ba7  SOLR-14025: VelocityResponseWriter has been hardened

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 solr/CHANGES.txt                                   |   7 +
 .../solr/response/SolrParamResourceLoader.java     |  73 -----------
 .../solr/response/VelocityResponseWriter.java      | 108 +++++++++-------
 .../velocity/solr/collection1/conf/solrconfig.xml  |   3 -
 .../solr/collection1/conf/velocity/custom_tool.vm  |   1 -
 .../solr/collection1/conf/velocity/foreach.vm      |   1 -
 .../collection1/conf/velocity/locale_number.vm     |   1 +
 .../collection1/conf/velocity/outside_the_box.vm   |   4 +
 .../conf/velocity/sandbox_intersection.vm          |   5 +
 .../velocity/src/test/custom_tool.vm}              |  14 +-
 .../contrib/velocity/src/test/foreach.vm           |  11 +-
 .../solr/velocity/VelocityResponseWriterTest.java  | 143 ++++++++++++++-------
 .../solr/configsets/_default/conf/solrconfig.xml   |  13 +-
 .../solr/cloud/TestQueryingOnDownCollection.java   |   1 -
 .../solr/configsets/_default/conf/solrconfig.xml   |  13 +-
 .../src/velocity-response-writer.adoc              |  31 ++---
 16 files changed, 196 insertions(+), 233 deletions(-)
 delete mode 100644 solr/contrib/velocity/src/java/org/apache/solr/response/SolrParamResourceLoader.java
 delete mode 100644 solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/custom_tool.vm
 delete mode 100644 solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/foreach.vm
 create mode 100644 solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/locale_number.vm
 create mode 100644 solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/outside_the_box.vm
 create mode 100644 solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/sandbox_intersection.vm
 copy solr/{core/src/test-files/README => contrib/velocity/src/test/custom_tool.vm} (71%)
 copy lucene/join/src/java/overview.html => solr/contrib/velocity/src/test/foreach.vm (80%)


[lucene-solr] 01/02: Provided the patch for solr-13971 for 7.7

Posted by is...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ishan pushed a commit to branch branch_7_7
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 2937630e49e07883be8e46127de1dbdff6196824
Author: Sachin Pattan <sa...@sap.com>
AuthorDate: Wed Jan 8 11:46:29 2020 +0100

    Provided the patch for solr-13971 for 7.7
---
 solr/CHANGES.txt                                       |  3 +++
 .../apache/solr/response/VelocityResponseWriter.java   | 12 +++++++-----
 .../solr/velocity/VelocityResponseWriterTest.java      | 11 ++++++++++-
 .../solr/configsets/_default/conf/solrconfig.xml       | 13 +------------
 .../solr/configsets/_default/conf/solrconfig.xml       | 13 +------------
 solr/solr-ref-guide/src/velocity-response-writer.adoc  | 18 +++++++++---------
 6 files changed, 31 insertions(+), 39 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index c769355..983e4a7 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -45,6 +45,9 @@ Bug fixes
   the number of replicas. This avoids making too many cascading calls to remote servers, which, if not restricted, can
   bring down nodes containing the said collection (Kesharee Nandan Vishwakarma, Ishan Chattopadhyaya)
 
+* SOLR-13971: Velocity response writer's resource loading now possible only through startup parameters. Also, removed velocity 
+  response writer from _default configset. (Ishan Chattopadhyaya, Sachin Pattan)
+
 ==================  7.7.2 ==================
 
 Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
diff --git a/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java b/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
index ad1ee39..6325355 100644
--- a/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
+++ b/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
@@ -65,9 +65,11 @@ public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAwar
   // init param names, these are _only_ loaded at init time (no per-request control of these)
   //   - multiple different named writers could be created with different init params
   public static final String TEMPLATE_BASE_DIR = "template.base.dir";
+  public static final String PROPERTIES_FILE = "init.properties.file";
+
+  // System property names, these are _only_ loaded at node startup (no per-request control of these)
   public static final String PARAMS_RESOURCE_LOADER_ENABLED = "params.resource.loader.enabled";
   public static final String SOLR_RESOURCE_LOADER_ENABLED = "solr.resource.loader.enabled";
-  public static final String PROPERTIES_FILE = "init.properties.file";
 
   // request param names
   public static final String TEMPLATE = "v.template";
@@ -110,12 +112,12 @@ public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAwar
     }
 
     // params resource loader: off by default
-    Boolean prle = args.getBooleanArg(PARAMS_RESOURCE_LOADER_ENABLED);
+    Boolean prle = Boolean.getBoolean(PARAMS_RESOURCE_LOADER_ENABLED);
     paramsResourceLoaderEnabled = (null == prle ? false : prle);
 
-    // solr resource loader: on by default
-    Boolean srle = args.getBooleanArg(SOLR_RESOURCE_LOADER_ENABLED);
-    solrResourceLoaderEnabled = (null == srle ? true : srle);
+    // solr resource loader: off by default
+    Boolean srle = Boolean.getBoolean(SOLR_RESOURCE_LOADER_ENABLED);
+    solrResourceLoaderEnabled = (null == srle ? false : srle);
 
     initPropertiesFileName = (String) args.get(PROPERTIES_FILE);
 
diff --git a/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java b/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
index 9b70e1b..b5fa387 100644
--- a/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
+++ b/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
@@ -24,6 +24,7 @@ import org.apache.solr.response.SolrParamResourceLoader;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.response.VelocityResponseWriter;
 import org.apache.solr.request.SolrQueryRequest;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -33,10 +34,18 @@ import java.io.StringWriter;
 public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
   @BeforeClass
   public static void beforeClass() throws Exception {
+    System.setProperty("params.resource.loader.enabled", "true");
+    System.setProperty("solr.resource.loader.enabled", "true");
     initCore("solrconfig.xml", "schema.xml", getFile("velocity/solr").getAbsolutePath());
     System.out.println(getFile("velocity/solr").getAbsolutePath());
   }
-
+  
+  @AfterClass
+  public static void afterClass() throws Exception {
+    System.clearProperty("params.resource.loader.enabled");
+    System.clearProperty("solr.resource.loader.enabled");
+  }
+  
   @Test
   public void testVelocityResponseWriterRegistered() {
     QueryResponseWriter writer = h.getCore().getQueryResponseWriter("velocity");
diff --git a/solr/core/src/test-files/solr/configsets/_default/conf/solrconfig.xml b/solr/core/src/test-files/solr/configsets/_default/conf/solrconfig.xml
index 7941aeb..9e994a6 100644
--- a/solr/core/src/test-files/solr/configsets/_default/conf/solrconfig.xml
+++ b/solr/core/src/test-files/solr/configsets/_default/conf/solrconfig.xml
@@ -81,8 +81,6 @@
   <lib dir="${solr.install.dir:../../../..}/contrib/langid/lib/" regex=".*\.jar" />
   <lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-langid-\d.*\.jar" />
 
-  <lib dir="${solr.install.dir:../../../..}/contrib/velocity/lib" regex=".*\.jar" />
-  <lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-velocity-\d.*\.jar" />
   <!-- an exact 'path' can be used instead of a 'dir' to specify a
        specific jar file.  This will cause a serious error to be logged
        if it can't be loaded.
@@ -773,7 +771,7 @@
        (SearchHandler) can be registered multiple times with different
        names (and different init parameters)
     -->
-  <requestHandler name="/browse" class="solr.SearchHandler" useParams="query,facets,velocity,browse">
+  <requestHandler name="/browse" class="solr.SearchHandler" useParams="query,facets,browse">
     <lst name="defaults">
       <str name="echoParams">explicit</str>
     </lst>
@@ -1294,15 +1292,6 @@
     <str name="content-type">text/plain; charset=UTF-8</str>
   </queryResponseWriter>
 
-  <!--
-     Custom response writers can be declared as needed...
-    -->
-  <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
-    <str name="template.base.dir">${velocity.template.base.dir:}</str>
-    <str name="solr.resource.loader.enabled">${velocity.solr.resource.loader.enabled:true}</str>
-    <str name="params.resource.loader.enabled">${velocity.params.resource.loader.enabled:false}</str>
-  </queryResponseWriter>
-
   <!-- XSLT response writer transforms the XML output by any xslt file found
        in Solr's conf/xslt directory.  Changes to xslt files are checked for
        every xsltCacheLifetimeSeconds.
diff --git a/solr/server/solr/configsets/_default/conf/solrconfig.xml b/solr/server/solr/configsets/_default/conf/solrconfig.xml
index 7941aeb..9e994a6 100644
--- a/solr/server/solr/configsets/_default/conf/solrconfig.xml
+++ b/solr/server/solr/configsets/_default/conf/solrconfig.xml
@@ -81,8 +81,6 @@
   <lib dir="${solr.install.dir:../../../..}/contrib/langid/lib/" regex=".*\.jar" />
   <lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-langid-\d.*\.jar" />
 
-  <lib dir="${solr.install.dir:../../../..}/contrib/velocity/lib" regex=".*\.jar" />
-  <lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-velocity-\d.*\.jar" />
   <!-- an exact 'path' can be used instead of a 'dir' to specify a
        specific jar file.  This will cause a serious error to be logged
        if it can't be loaded.
@@ -773,7 +771,7 @@
        (SearchHandler) can be registered multiple times with different
        names (and different init parameters)
     -->
-  <requestHandler name="/browse" class="solr.SearchHandler" useParams="query,facets,velocity,browse">
+  <requestHandler name="/browse" class="solr.SearchHandler" useParams="query,facets,browse">
     <lst name="defaults">
       <str name="echoParams">explicit</str>
     </lst>
@@ -1294,15 +1292,6 @@
     <str name="content-type">text/plain; charset=UTF-8</str>
   </queryResponseWriter>
 
-  <!--
-     Custom response writers can be declared as needed...
-    -->
-  <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
-    <str name="template.base.dir">${velocity.template.base.dir:}</str>
-    <str name="solr.resource.loader.enabled">${velocity.solr.resource.loader.enabled:true}</str>
-    <str name="params.resource.loader.enabled">${velocity.params.resource.loader.enabled:false}</str>
-  </queryResponseWriter>
-
   <!-- XSLT response writer transforms the XML output by any xslt file found
        in Solr's conf/xslt directory.  Changes to xslt files are checked for
        every xsltCacheLifetimeSeconds.
diff --git a/solr/solr-ref-guide/src/velocity-response-writer.adoc b/solr/solr-ref-guide/src/velocity-response-writer.adoc
index 38c3c4e..37ee3b6 100644
--- a/solr/solr-ref-guide/src/velocity-response-writer.adoc
+++ b/solr/solr-ref-guide/src/velocity-response-writer.adoc
@@ -27,8 +27,6 @@ Its JAR and dependencies must be added (via `<lib>` or solr/home lib inclusion),
 
 <!--
   <str name="init.properties.file">velocity-init.properties</str>
-  <bool name="params.resource.loader.enabled">true</bool>
-  <bool name="solr.resource.loader.enabled">false</bool>
   <lst name="tools">
     <str name="mytool">com.example.MyCustomTool</str>
   </lst>
@@ -36,16 +34,11 @@ Its JAR and dependencies must be added (via `<lib>` or solr/home lib inclusion),
 </queryResponseWriter>
 ----
 
-The above example shows the optional initialization and custom tool parameters used by VelocityResponseWriter; these are detailed in the following table. These initialization parameters are only specified in the writer registration in `solrconfig.xml`, not as request-time parameters. See further below for request-time parameters.
+The above example shows the optional initialization and custom tool parameters used by VelocityResponseWriter; these are detailed in the following table. These initialization parameters are only specified in the writer registration in `solrconfig.xml`, not as request-time parameters. In this example, all Solr nodes should be started with `-Dparams.resource.loader.enabled=true`. See further below for request-time parameters.
 
 == Configuration & Usage
 
-=== VelocityResponseWriter Initialization Parameters
-
-`template.base.dir`::
-If specified and exists as a file system directory, a file resource loader will be added for this directory. Templates in this directory will override "solr" resource loader templates.
-
-`init.properties.file`:: Specifies a properties file name which must exist in the Solr `conf/` directory (*not* under a `velocity/` subdirectory) or root of a JAR file in a <lib>.
+=== VelocityResponseWriter Startup Parameters
 
 `params.resource.loader.enabled`::
 The "params" resource loader allows templates to be specified in Solr request parameters. For example:
@@ -58,6 +51,13 @@ where `v.template=custom` says to render a template called "custom" and the valu
 `solr.resource.loader.enabled`::
 The "solr" resource loader is the only template loader registered by default. Templates are served from resources visible to the SolrResourceLoader under a `velocity/` subdirectory. The VelocityResponseWriter itself has some built-in templates (in its JAR file, under `velocity/`) that are available automatically through this loader. These built-in templates can be overridden when the same template name is in conf/velocity/ or by using the `template.base.dir` option.
 
+=== VelocityResponseWriter Initialization Parameters
+
+`template.base.dir`::
+If specified and exists as a file system directory, a file resource loader will be added for this directory. Templates in this directory will override "solr" resource loader templates.
+
+`init.properties.file`:: Specifies a properties file name which must exist in the Solr `conf/` directory (*not* under a `velocity/` subdirectory) or root of a JAR file in a <lib>.
+
 `tools`::
 External "tools" can be specified as list of string name/value (tool name / class name) pairs. Tools, in the Velocity context, are simply Java objects. Tool classes are constructed using a no-arg constructor (or a single-SolrCore-arg constructor if it exists) and added to the Velocity context with the specified name.
 +


[lucene-solr] 02/02: SOLR-14025: VelocityResponseWriter has been hardened

Posted by is...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ishan pushed a commit to branch branch_7_7
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 1b21ba78ba3198ea7829e551eb2194ceccba3592
Author: Ishan Chattopadhyaya <is...@apache.org>
AuthorDate: Mon Jan 13 19:03:31 2020 +0530

    SOLR-14025: VelocityResponseWriter has been hardened
---
 solr/CHANGES.txt                                   |   4 +
 .../solr/response/SolrParamResourceLoader.java     |  73 -----------
 .../solr/response/VelocityResponseWriter.java      | 104 ++++++++-------
 .../velocity/solr/collection1/conf/solrconfig.xml  |   3 -
 .../solr/collection1/conf/velocity/custom_tool.vm  |   1 -
 .../solr/collection1/conf/velocity/foreach.vm      |   1 -
 .../collection1/conf/velocity/locale_number.vm     |   1 +
 .../collection1/conf/velocity/outside_the_box.vm   |   4 +
 .../conf/velocity/sandbox_intersection.vm          |   5 +
 solr/contrib/velocity/src/test/custom_tool.vm      |  19 +++
 solr/contrib/velocity/src/test/foreach.vm          |  14 +++
 .../solr/velocity/VelocityResponseWriterTest.java  | 140 +++++++++++++--------
 .../solr/cloud/TestQueryingOnDownCollection.java   |   1 -
 .../src/velocity-response-writer.adoc              |  27 ++--
 14 files changed, 205 insertions(+), 192 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 983e4a7..9c385ff 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -48,6 +48,10 @@ Bug fixes
 * SOLR-13971: Velocity response writer's resource loading now possible only through startup parameters. Also, removed velocity 
   response writer from _default configset. (Ishan Chattopadhyaya, Sachin Pattan)
 
+* SOLR-14025: VelocityResponseWriter has been hardened - only trusted configsets can render configset provided
+  templates and rendering templates from request parameters has been removed.
+
+
 ==================  7.7.2 ==================
 
 Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
diff --git a/solr/contrib/velocity/src/java/org/apache/solr/response/SolrParamResourceLoader.java b/solr/contrib/velocity/src/java/org/apache/solr/response/SolrParamResourceLoader.java
deleted file mode 100644
index 17b2878..0000000
--- a/solr/contrib/velocity/src/java/org/apache/solr/response/SolrParamResourceLoader.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.response;
-
-import org.apache.solr.request.SolrQueryRequest;
-import org.apache.velocity.runtime.resource.loader.ResourceLoader;
-import org.apache.velocity.runtime.resource.Resource;
-import org.apache.velocity.exception.ResourceNotFoundException;
-import org.apache.commons.collections.ExtendedProperties;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-public class SolrParamResourceLoader extends ResourceLoader {
-  public static final String TEMPLATE_PARAM_PREFIX = VelocityResponseWriter.TEMPLATE + ".";
-
-  private Map<String,String> templates = new HashMap<>();
-  public SolrParamResourceLoader(SolrQueryRequest request) {
-    super();
-
-    // TODO: Consider using content streams, but need a template name associated with each stream
-    // for now, a custom param convention of template.<name>=<template body> is a nice example
-    // of per-request overrides of templates
-
-    org.apache.solr.common.params.SolrParams params = request.getParams();
-    Iterator<String> names = params.getParameterNamesIterator();
-    while (names.hasNext()) {
-      String name = names.next();
-      
-      if (name.startsWith(TEMPLATE_PARAM_PREFIX)) {
-        templates.put(name.substring(TEMPLATE_PARAM_PREFIX.length()) + VelocityResponseWriter.TEMPLATE_EXTENSION,params.get(name));
-      }
-    }
-  }
-
-  @Override
-  public void init(ExtendedProperties extendedProperties) {
-  }
-
-  @Override
-  public InputStream getResourceStream(String s) throws ResourceNotFoundException {
-    String template = templates.get(s);
-    return template == null ? null : new ByteArrayInputStream(template.getBytes(StandardCharsets.UTF_8));
-  }
-
-  @Override
-  public boolean isSourceModified(Resource resource) {
-    return false;
-  }
-
-  @Override
-  public long getLastModified(Resource resource) {
-    return 0;
-  }
-}
diff --git a/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java b/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
index 6325355..a977d31 100644
--- a/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
+++ b/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
@@ -68,7 +68,6 @@ public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAwar
   public static final String PROPERTIES_FILE = "init.properties.file";
 
   // System property names, these are _only_ loaded at node startup (no per-request control of these)
-  public static final String PARAMS_RESOURCE_LOADER_ENABLED = "params.resource.loader.enabled";
   public static final String SOLR_RESOURCE_LOADER_ENABLED = "solr.resource.loader.enabled";
 
   // request param names
@@ -84,8 +83,6 @@ public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAwar
   public static final String JSON_CONTENT_TYPE = "application/json;charset=UTF-8";
 
   private File fileResourceLoaderBaseDir;
-  private boolean paramsResourceLoaderEnabled;
-  private boolean solrResourceLoaderEnabled;
   private String initPropertiesFileName;  // used just to hold from init() to inform()
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -111,14 +108,6 @@ public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAwar
       }
     }
 
-    // params resource loader: off by default
-    Boolean prle = Boolean.getBoolean(PARAMS_RESOURCE_LOADER_ENABLED);
-    paramsResourceLoaderEnabled = (null == prle ? false : prle);
-
-    // solr resource loader: off by default
-    Boolean srle = Boolean.getBoolean(SOLR_RESOURCE_LOADER_ENABLED);
-    solrResourceLoaderEnabled = (null == srle ? false : srle);
-
     initPropertiesFileName = (String) args.get(PROPERTIES_FILE);
 
     NamedList tools = (NamedList)args.get("tools");
@@ -233,25 +222,32 @@ public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAwar
     resourceTool.configure(toolConfig);
     context.put("resource", resourceTool);
 
-/*
-    // Custom tools, specified in config as:
-        <queryResponseWriter name="velocityWithCustomTools" class="solr.VelocityResponseWriter">
-          <lst name="tools">
-            <str name="mytool">com.example.solr.velocity.MyTool</str>
-          </lst>
-        </queryResponseWriter>
-*/
-    // Custom tools can override any of the built-in tools provided above, by registering one with the same name
-    for(String name : customTools.keySet()) {
-      Object customTool = SolrCore.createInstance(customTools.get(name), Object.class, "VrW custom tool: " + name, request.getCore(), request.getCore().getResourceLoader());
-      if (customTool instanceof LocaleConfig) {
-        ((LocaleConfig)customTool).configure(toolConfig);
+   if (request.getCore().getCoreDescriptor().isConfigSetTrusted()) {
+      // Load custom tools, only if in a trusted configset
+
+      /*
+          // Custom tools, specified in config as:
+              <queryResponseWriter name="velocityWithCustomTools" class="solr.VelocityResponseWriter">
+                <lst name="tools">
+                  <str name="mytool">com.example.solr.velocity.MyTool</str>
+                </lst>
+              </queryResponseWriter>
+      */
+      // Custom tools can override any of the built-in tools provided above, by registering one with the same name
+      if (request.getCore().getCoreDescriptor().isConfigSetTrusted()) {
+        for (Map.Entry<String, String> entry : customTools.entrySet()) {
+          String name = entry.getKey();
+          // TODO: at least log a warning when one of the *fixed* tools classes is same name with a custom one, currently silently ignored
+          Object customTool = SolrCore.createInstance(entry.getValue(), Object.class, "VrW custom tool: " + name, request.getCore(), request.getCore().getResourceLoader());
+          if (customTool instanceof LocaleConfig) {
+            ((LocaleConfig) customTool).configure(toolConfig);
+          }
+          context.put(name, customTool);
+        }
       }
-      context.put(name, customTool);
-    }
 
-    // custom tools _cannot_ override context objects added below, like $request and $response
-    // TODO: at least log a warning when one of the *fixed* tools classes in name with a custom one, currently silently ignored
+      // custom tools _cannot_ override context objects added below, like $request and $response
+    }
 
 
     // Turn the SolrQueryResponse into a SolrResponse.
@@ -285,15 +281,10 @@ public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAwar
   }
 
   private VelocityEngine createEngine(SolrQueryRequest request) {
-    VelocityEngine engine = new VelocityEngine();
-
-    // route all Velocity logging through Solr's logging facility
-    engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, velocityLogger);
+    boolean trustedMode = request.getCore().getCoreDescriptor().isConfigSetTrusted();
 
-    // Set some engine properties that improve the experience
-    //   - these could be considered in the future for parameterization, but can also be overridden by using
-    //     the init.properties.file setting.  (TODO: add a test for this properties set here overridden)
 
+    VelocityEngine engine = new VelocityEngine();
     // load the built-in _macros.vm first, then load VM_global_library.vm for legacy (pre-5.0) support,
     // and finally allow macros.vm to have the final say and override anything defined in the preceding files.
     engine.setProperty(RuntimeConstants.VM_LIBRARY, "_macros.vm,VM_global_library.vm,macros.vm");
@@ -308,25 +299,25 @@ public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAwar
        and there are Velocity template resource loaders.  It's confusing, they overlap: there is a Velocity resource
        loader that loads templates from Solr's resource loader (SolrVelocityResourceLoader).
 
-      The Velocity resource loader order is [params,][file,][solr], intentionally ordered in this manner, and each
-      one optional and individually enable-able.  By default, only "solr" (resource loader) is used, parsing templates
-      from a velocity/ sub-tree in either the classpath or under conf/.
+      The Velocity resource loader order is `[file,][solr],builtin` intentionally ordered in this manner.
+      The "file" resource loader, enabled when the configset is trusted and `template.base.dir` is specified as a
+      response writer init property.
+
+      The "solr" resource loader, enabled when the configset is trusted, and provides templates from a velocity/
+      sub-tree in either the classpath or under conf/.
 
-      A common usage would be to enable the file template loader, keeping the solr loader enabled; the Velocity resource
-      loader path would then be "file,solr" (params is disabled by default).  The basic browse templates are built into
+      By default, only "builtin" resource loader is enabled, providing tenplates from builtin Solr .jar files.
+
+      The basic browse templates are built into
       this plugin, but can be individually overridden by placing a same-named template in the template.base.dir specified
-      directory.
+      directory, or within a trusted configset's velocity/ directory.
      */
     ArrayList<String> loaders = new ArrayList<String>();
-    if (paramsResourceLoaderEnabled) {
-      loaders.add("params");
-      engine.setProperty("params.resource.loader.instance", new SolrParamResourceLoader(request));
-    }
-    if (fileResourceLoaderBaseDir != null) {
+    if ((fileResourceLoaderBaseDir != null) && trustedMode) {
       loaders.add("file");
       engine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, fileResourceLoaderBaseDir.getAbsolutePath());
     }
-    if (solrResourceLoaderEnabled) {
+    if (trustedMode) {
       // The solr resource loader serves templates under a velocity/ subtree from <lib>, conf/,
       // or SolrCloud's configuration tree.  Or rather the other way around, other resource loaders are rooted
       // from the top, whereas this is velocity/ sub-tree rooted.
@@ -344,6 +335,25 @@ public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAwar
 
     engine.setProperty(RuntimeConstants.INPUT_ENCODING, "UTF-8");
 
+    // install a class/package restricting uberspector
+    engine.setProperty(RuntimeConstants.UBERSPECT_CLASSNAME,"org.apache.velocity.util.introspection.SecureUberspector");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_PACKAGES,"java.lang.reflect");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.Class");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.ClassLoader");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.Compiler");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.InheritableThreadLocal");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.Package");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.Process");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.Runtime");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.RuntimePermission");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.SecurityManager");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.System");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.Thread");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.ThreadGroup");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"java.lang.ThreadLocal");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"org.apache.solr.core.SolrResourceLoader");
+    engine.addProperty(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,"org.apache.solr.core.CoreContainer");
+
     // bring in any custom properties too
     engine.init(velocityInitProps);
 
diff --git a/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml
index f1e0687..35ce52b 100644
--- a/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml
+++ b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml
@@ -38,9 +38,6 @@
   </queryResponseWriter>
 
   <queryResponseWriter name="velocityWithCustomTools" class="solr.VelocityResponseWriter">
-    <!-- Enable params resource loader to make tests leaner, no external template needed -->
-    <bool name="params.resource.loader.enabled">true</bool>
-
     <lst name="tools">
       <!-- how someone would typically add a custom tool, with a custom, non-clashing name -->
       <str name="mytool">org.apache.solr.velocity.MockTool</str>
diff --git a/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/custom_tool.vm b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/custom_tool.vm
deleted file mode 100644
index 461a27b..0000000
--- a/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/custom_tool.vm
+++ /dev/null
@@ -1 +0,0 @@
-$!mytool.star("foo")
\ No newline at end of file
diff --git a/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/foreach.vm b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/foreach.vm
deleted file mode 100644
index 3449dac..0000000
--- a/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/foreach.vm
+++ /dev/null
@@ -1 +0,0 @@
-#foreach($x in ["a","b"])$!foreach.index#end
\ No newline at end of file
diff --git a/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/locale_number.vm b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/locale_number.vm
new file mode 100644
index 0000000..9994022
--- /dev/null
+++ b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/locale_number.vm
@@ -0,0 +1 @@
+$number.format(2112)
\ No newline at end of file
diff --git a/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/outside_the_box.vm b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/outside_the_box.vm
new file mode 100644
index 0000000..c52c94b
--- /dev/null
+++ b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/outside_the_box.vm
@@ -0,0 +1,4 @@
+#set($x='')
+#set($sys=$x.class.forName('java.lang.System'))
+#set($ex=$sys.getProperty('os.name'))
+$ex
\ No newline at end of file
diff --git a/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/sandbox_intersection.vm b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/sandbox_intersection.vm
new file mode 100644
index 0000000..80c7422
--- /dev/null
+++ b/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/sandbox_intersection.vm
@@ -0,0 +1,5 @@
+#set($x='')
+#set($sys=$x.class.forName('java.nio.file.Paths'))
+#set($path=$sys.get('/dumbass/denied_location'))
+#set($ex=$path.resolve($path).toRealPath())
+$ex
\ No newline at end of file
diff --git a/solr/contrib/velocity/src/test/custom_tool.vm b/solr/contrib/velocity/src/test/custom_tool.vm
new file mode 100644
index 0000000..3efff7d
--- /dev/null
+++ b/solr/contrib/velocity/src/test/custom_tool.vm
@@ -0,0 +1,19 @@
+#* Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. *#
+
+mytool.star=$!mytool.star("LATERALUS")
+mytool.locale=$!mytool.locale
+log.star=$!log.star("log overridden")
+response.star=$!response.star("response overridden??")
diff --git a/solr/contrib/velocity/src/test/foreach.vm b/solr/contrib/velocity/src/test/foreach.vm
new file mode 100644
index 0000000..5d7d1e9
--- /dev/null
+++ b/solr/contrib/velocity/src/test/foreach.vm
@@ -0,0 +1,14 @@
+#* Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. *##foreach($x in ["a","b"])$!foreach.index#end
diff --git a/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java b/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
index b5fa387..64ac549 100644
--- a/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
+++ b/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
@@ -16,11 +16,13 @@
  */
 package org.apache.solr.velocity;
 
+import java.io.StringReader;
+import java.util.Properties;
+
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.response.QueryResponseWriter;
-import org.apache.solr.response.SolrParamResourceLoader;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.response.VelocityResponseWriter;
 import org.apache.solr.request.SolrQueryRequest;
@@ -34,16 +36,18 @@ import java.io.StringWriter;
 public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
   @BeforeClass
   public static void beforeClass() throws Exception {
-    System.setProperty("params.resource.loader.enabled", "true");
-    System.setProperty("solr.resource.loader.enabled", "true");
     initCore("solrconfig.xml", "schema.xml", getFile("velocity/solr").getAbsolutePath());
-    System.out.println(getFile("velocity/solr").getAbsolutePath());
   }
   
   @AfterClass
   public static void afterClass() throws Exception {
-    System.clearProperty("params.resource.loader.enabled");
-    System.clearProperty("solr.resource.loader.enabled");
+  }
+  
+  @Override
+  public void setUp() throws Exception {
+    // This test case toggles the configset used from trusted to untrusted - return to default of trusted for each test
+    h.getCoreContainer().getCoreDescriptor(h.coreName).setConfigSetTrusted(true);
+    super.setUp();
   }
   
   @Test
@@ -53,34 +57,16 @@ public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
   }
 
   @Test
-  public void testCustomParamTemplate() throws Exception {
-    org.apache.solr.response.VelocityResponseWriter vrw = new VelocityResponseWriter();
-    NamedList<String> nl = new NamedList<String>();
-    nl.add(VelocityResponseWriter.PARAMS_RESOURCE_LOADER_ENABLED, "true");
+  public void testSecureUberspector() throws Exception {
+    VelocityResponseWriter vrw = new VelocityResponseWriter();
+    NamedList<String> nl = new NamedList<>();
+    nl.add("template.base.dir", getFile("velocity").getAbsolutePath());
     vrw.init(nl);
-    SolrQueryRequest req = req(VelocityResponseWriter.TEMPLATE,"custom",
-        SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"custom","$response.response.response_data");
+    SolrQueryRequest req = req(VelocityResponseWriter.TEMPLATE,"outside_the_box");
     SolrQueryResponse rsp = new SolrQueryResponse();
     StringWriter buf = new StringWriter();
-    rsp.add("response_data", "testing");
     vrw.write(buf, req, rsp);
-    assertEquals("testing", buf.toString());
-  }
-
-  @Test
-  public void testParamResourceLoaderDisabled() throws Exception {
-    VelocityResponseWriter vrw = new VelocityResponseWriter();
-    // by default param resource loader is disabled, no need to set it here
-    SolrQueryRequest req = req(VelocityResponseWriter.TEMPLATE,"custom",
-        SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"custom","$response.response.response_data");
-    SolrQueryResponse rsp = new SolrQueryResponse();
-    StringWriter buf = new StringWriter();
-    try {
-      vrw.write(buf, req, rsp);
-      fail("Should have thrown exception due to missing template");
-    } catch (IOException e) {
-      // expected exception
-    }
+    assertEquals("$ex",buf.toString());  // $ex rendered literally because it is null, and thus did not succeed to break outside the box
   }
 
   @Test
@@ -97,8 +83,37 @@ public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
   }
 
   @Test
+  public void testTemplateTrust() throws Exception {
+    // Try on trusted configset....
+    assertEquals("0", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"numFound")));
+
+    // Turn off trusted configset, which disables the Solr resource loader
+    h.getCoreContainer().getCoreDescriptor(h.coreName).setConfigSetTrusted(false);
+    assertFalse(h.getCoreContainer().getCoreDescriptor(coreName).isConfigSetTrusted());
+
+    try {
+      assertEquals("0", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"numFound")));
+      fail("template rendering should have failed, from an untrusted configset");
+    } catch (IOException e) {
+      // expected exception
+      assertEquals(IOException.class, e.getClass());
+    }
+
+    // set the harness back to the default of trusted
+    h.getCoreContainer().getCoreDescriptor(h.coreName).setConfigSetTrusted(true);
+  }
+
+
+  @Test
   public void testSolrResourceLoaderTemplate() throws Exception {
     assertEquals("0", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"numFound")));
+
+    // Turn off trusted configset, which disables the init properties
+    h.getCoreContainer().getCoreDescriptor(h.coreName).setConfigSetTrusted(false);
+    assertFalse(h.getCoreContainer().getCoreDescriptor(coreName).isConfigSetTrusted());
+
+    // set the harness back to the default of trusted
+    h.getCoreContainer().getCoreDescriptor(h.coreName).setConfigSetTrusted(true);
   }
 
   @Test
@@ -130,19 +145,46 @@ public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
 
   @Test
   public void testCustomTools() throws Exception {
-    // custom_tool.vm responds with $!mytool.star("foo"), but $mytool is not defined (only in velocityWithCustomTools)
-    assertEquals("", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"custom_tool")));
-
-    assertEquals("** LATERALUS **", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
-            SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t", "$mytool.star(\"LATERALUS\")")));
-
-    // Does $log get overridden?
-    assertEquals("** log overridden **", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
-            SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t", "$log.star(\"log overridden\")")));
-
-    // Does $response get overridden?  actual blank response because of the bang on $! reference that silences bogus $-references
-    assertEquals("", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
-        SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t", "$!response.star(\"response overridden??\")")));
+    // Render this template once without a custom tool defined, and once with it defined.  The tool has a `.star` method.
+    // The tool added as `mytool`, `log`, and `response`.  `log` is designed to be overridable, but not `response`
+    //    mytool.star=$!mytool.star("LATERALUS")
+    //    mytool.locale=$!mytool.locale
+    //    log.star=$!log.star("log overridden")
+    //    response.star=$!response.star("response overridden??")
+
+    // First without the tool defined, with `$!` turning null object/method references into empty string
+    Properties rendered_props = new Properties();
+    String rsp = h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"custom_tool"));
+    rendered_props.load(new StringReader(rsp));
+    // ignore mytool.locale here, as it will be the random test one
+    assertEquals("",rendered_props.getProperty("mytool.star"));
+    assertEquals("",rendered_props.getProperty("log.star"));
+    assertEquals("",rendered_props.getProperty("response.star"));
+
+    // Now with custom tools defined:
+    rsp = h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"custom_tool",VelocityResponseWriter.LOCALE, "de_DE"));
+    rendered_props.clear();
+    rendered_props.load(new StringReader(rsp));
+    assertEquals("** LATERALUS **",rendered_props.getProperty("mytool.star"));
+    assertEquals("** log overridden **",rendered_props.getProperty("log.star"));
+    assertEquals("",rendered_props.getProperty("response.star"));
+    assertEquals("de_DE",rendered_props.getProperty("mytool.locale"));
+
+
+    // Turn off trusted configset, which disables the custom tool injection
+    h.getCoreContainer().getCoreDescriptor(h.coreName).setConfigSetTrusted(false);
+    assertFalse(h.getCoreContainer().getCoreDescriptor(coreName).isConfigSetTrusted());
+
+    rsp = h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"custom_tool",VelocityResponseWriter.LOCALE, "de_DE"));
+    rendered_props.clear();
+    rendered_props.load(new StringReader(rsp));
+    assertEquals("",rendered_props.getProperty("mytool.star"));
+    assertEquals("",rendered_props.getProperty("log.star"));
+    assertEquals("",rendered_props.getProperty("response.star"));
+    assertEquals("",rendered_props.getProperty("mytool.locale"));
+
+    // set the harness back to the default of trusted
+    h.getCoreContainer().getCoreDescriptor(h.coreName).setConfigSetTrusted(true);
 
     // Custom tools can also have a SolrCore-arg constructor because they are instantiated with SolrCore.createInstance
     // TODO: do we really need to support this?  no great loss, as a custom tool could take a SolrCore object as a parameter to
@@ -164,14 +206,10 @@ public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
     assertEquals("Colour", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"resource_get")));
 
     // Test that $number tool uses the specified locale
-    assertEquals("2,112", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
-        SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t","$number.format(2112)", VelocityResponseWriter.LOCALE, "en_US")));
-    assertEquals("2.112", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
-        SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t","$number.format(2112)", VelocityResponseWriter.LOCALE, "de_DE")));
-
-    // Test that custom tool extending LocaleConfig gets the right locale
-    assertEquals("de_DE", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
-        SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t","$mytool.locale", VelocityResponseWriter.LOCALE, "de_DE")));
+    assertEquals("2,112", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"locale_number",
+        VelocityResponseWriter.LOCALE, "en_US")));
+    assertEquals("2.112", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"locale_number",
+        VelocityResponseWriter.LOCALE, "de_DE")));
   }
 
   @Test
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java b/solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java
index 5ad9407..851d82e 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java
@@ -24,7 +24,6 @@ import java.util.Map;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrRequest;
-import org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.QueryRequest;
 import org.apache.solr.client.solrj.request.UpdateRequest;
diff --git a/solr/solr-ref-guide/src/velocity-response-writer.adoc b/solr/solr-ref-guide/src/velocity-response-writer.adoc
index 37ee3b6..0039787 100644
--- a/solr/solr-ref-guide/src/velocity-response-writer.adoc
+++ b/solr/solr-ref-guide/src/velocity-response-writer.adoc
@@ -16,7 +16,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-The VelocityResponseWriter is an optional plugin available in the `contrib/velocity` directory. It powers the /browse user interfaces when using configurations such as "_default", "techproducts", and "example/files".
+The VelocityResponseWriter is an optional plugin available in the `contrib/velocity` directory. It powers the /browse user interfaces when using some example configurations such as "techproducts" and "example/files".
 
 Its JAR and dependencies must be added (via `<lib>` or solr/home lib inclusion), and must be registered in `solrconfig.xml` like this:
 
@@ -34,22 +34,13 @@ Its JAR and dependencies must be added (via `<lib>` or solr/home lib inclusion),
 </queryResponseWriter>
 ----
 
-The above example shows the optional initialization and custom tool parameters used by VelocityResponseWriter; these are detailed in the following table. These initialization parameters are only specified in the writer registration in `solrconfig.xml`, not as request-time parameters. In this example, all Solr nodes should be started with `-Dparams.resource.loader.enabled=true`. See further below for request-time parameters.
-
 == Configuration & Usage
 
-=== VelocityResponseWriter Startup Parameters
-
-`params.resource.loader.enabled`::
-The "params" resource loader allows templates to be specified in Solr request parameters. For example:
-+
-[source,bash]
-http://localhost:8983/solr/gettingstarted/select?q=\*:*&wt=velocity&v.template=custom&v.template.custom=CUSTOM%3A%20%23core_name
-+
-where `v.template=custom` says to render a template called "custom" and the value of `v.template.custom` is the custom template. This is `false` by default; it'd be a niche, unusual, use case to need this enabled.
+=== Template Rendering Protections
 
-`solr.resource.loader.enabled`::
-The "solr" resource loader is the only template loader registered by default. Templates are served from resources visible to the SolrResourceLoader under a `velocity/` subdirectory. The VelocityResponseWriter itself has some built-in templates (in its JAR file, under `velocity/`) that are available automatically through this loader. These built-in templates can be overridden when the same template name is in conf/velocity/ or by using the `template.base.dir` option.
+Velocity template rendering is largely controlled by the `trusted` configset flag.  Templates built into (the `/browse` ones) the component library are always available
+with this component.  In a trusted configset, templates in the `velocity/` subdirectory of the configset are renderable.  Also in a trusted configset, when `template.base.dir`
+is specified those templates are renderable.
 
 === VelocityResponseWriter Initialization Parameters
 
@@ -95,7 +86,6 @@ Locale to use with the `$resource` tool and other LocaleConfig implementing tool
 +
 Resource bundles can be added by providing a JAR file visible by the SolrResourceLoader with resource bundles under a velocity sub-directory. Resource bundles are not loadable under `conf/`, as only the class loader aspect of SolrResourceLoader can be used here.
 
-`v.template._template_name_`:: When the "params" resource loader is enabled, templates can be specified as part of the Solr request.
 
 
 === VelocityResponseWriter Context Objects
@@ -121,3 +111,10 @@ Resource bundles can be added by providing a JAR file visible by the SolrResourc
 |`content` |The rendered output of the main template, when rendering the layout (`v.layout.enabled=true` and `v.layout=<template>`).
 |[custom tool(s)] |Tools provided by the optional "tools" list of the VelocityResponseWriter registration are available by their specified name.
 |===
+
+=== VelocityResponseWriter Usage
+
+To see results in an HTML user interface on your own collection, try http://localhost:8983/solr/<my collection>/select?q=*:*&wt=velocity&v.template=browse&v.layout=layout
+
+Or try `/browse` in the examples techproducts or example/files.
+