velocity-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Geir Magnusson Jr." <ge...@optonline.net>
Subject Re: template encodings
Date Mon, 16 Jul 2001 22:48:22 GMT
Why didn't you use the ClasspathResourceLoader or the jar resource
loader?

geir

Jonathan Revusky wrote:
> 
> Jon Stevens wrote:
> >
> > on 7/15/01 5:09 PM, "Jonathan Revusky" <jrevusky@terra.es> wrote:
> >
> > > Somebody else pointed out that if you
> > > specifically give an absolute location for the template file, it doesn't
> > > work, i.e. some naive user who tries:
> > > getTemplate("C:\\mytemplates\\mytemplate.html"). Well, that's basically
> > > a bug. The default code should have the smarts that if you give it an
> > > absolute path AND the file is there and readable, it should use it. To
> > > have any other behavior is to willfully waste people's time.
> >
> > No, it is a security hole.
> >
> > You don't want some random user to be able to access something like
> > /etc/passwd or /etc/shadow.
> 
> Could you explain the mechanism by which a random user would access
> /etc/passwd because I load a template file from an absolute path?
> 
> >
> > Setting a base template path is necessary. Then everything to access the
> > file is relative to that path and you don't have to worry about people
> > randomly reading files from that path.
> >
> > Go read the bugtraq archives. You will see literally hundreds of security
> > holes as a result of what you describe.
> >
> > This is a very common mistake by newbie software engineers.
> >
> > Lastly, it is entirely possible within Velocity for you to come up with your
> > own ResourceLoader. So, if you don't like the one that comes with Velocity,
> > then make your own!
> 
> I already did. Though I am advocating the position of a newbie user, *I*
> am not at all helpless in this regard. The code below is in the version
> of Niggle I put up today. It seems fairly reasonable to me. Note that a
> template is only loaded from an absolute location if the application
> programmer specifies an absolute location. I encourage people to locate
> their templates relative to the servlet context classpath.
> 
> /*
> Bridge Code to use Velocity template engine with Niggle
> Copyright (c) 2001, Jonathan Revusky
> All rights reserved.
> 
> Redistribution and use in source and binary forms, with or without
> modification, are permitted provided that the following conditions
> are met:
> 
> Redistributions of source code must retain the above copyright notice,
> this list of conditions and the following disclaimer.
> 
> Redistributions in binary form must reproduce the above copyright
> notice,
> this list of conditions and the following disclaimer in the
> documentation
> and/or other materials provided with the distribution.
> 
> The name of Jonathan Revusky may not be used to endorse or promote
> products derived from this software without specific prior written
> permission.
> 
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
> IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY OF SUCH DAMAGE.
> */
> 
> package com.revusky.niggle.templates.velocityimpl;
> 
> import org.apache.velocity.exception.ResourceNotFoundException;
> import org.apache.velocity.runtime.resource.loader.ResourceLoader;
> import org.apache.velocity.runtime.resource.Resource;
> import org.apache.commons.collections.ExtendedProperties;
> import com.revusky.oreo.util.*;
> import java.io.*;
> import java.util.*;
> import java.net.URL;
> 
> public class CustomResourceLoader extends ResourceLoader {
> 
>     static private ClassLoader classLoader;
>     static private String searchPath;
> 
>     static public void setClassLoader(ClassLoader classLoader) {
>         CustomResourceLoader.classLoader = classLoader;
>     }
> 
>     static public void setSearchPath(String searchPath) {
>         CustomResourceLoader.searchPath = searchPath;
>     }
> 
>     public void init(ExtendedProperties props) {
>         Logger.log("Niggle custom resource loader for Velocity :
> initialized.", Logger.LOG_INFO);
>     }
> 
>     public InputStream getResourceStream(String name)
>     throws ResourceNotFoundException {
>         try {
>             return findResource(name);
>         } catch (IOException ioe) {
>         }
>         throw new ResourceNotFoundException("Template " + name + " not
> found");
>     }
> 
>     private InputStream findResource(String name) throws IOException {
>         InputStream is = findAbsolute(name);
>         if (is == null) {
>             is = findOnSearchPath(name);
>         }
>         if (is == null) {
>             is = findOnClassPath(name);
>         }
>         return is;
>     }
> 
>     private InputStream findAbsolute(String name) throws IOException {
>         File f = new File(name);
>         if (f.isAbsolute() && f.canRead()) {
>             fileCache.put(name, f);
>             lastModifiedCache.put(name, new Long(f.lastModified()));
>             return new FileInputStream(f);
>         }
>         else
>             return null;
>     }
> 
>     private InputStream findOnSearchPath(String name) throws IOException
> {
>         if (searchPath != null) {
>             StringTokenizer st = new StringTokenizer(searchPath,
> File.pathSeparator);
>             while (st.hasMoreTokens()) {
>                 String path = st.nextToken();
>                 if (path.endsWith("/") || path.endsWith("\\")) {
>                     path = path.substring(0, path.length() -1);
>                 }
>                 String filename = path + "/" + name;
>                 InputStream is = findAbsolute(filename);
>                 if (is == null) {
>                     is = findOnClassPath(filename);
>                 }
>                 if (is != null) {
>                     return is;
>                 }
>             }
>         }
>         return null;
>     }
> 
>     private InputStream findOnClassPath(String name) throws IOException
> {
>         URL url = classLoader.getResource(name);
>         if (url == null) {
>             url = ClassLoader.getSystemResource(name);
>         }
>         if (url == null) {
>             return null;
>         }
>         String filename = url.getFile();
>         if (filename.startsWith("file:")) {
>             filename = filename.substring(5);
>         }
>         File f = new File(filename);
>         if (f.exists()) {
>             fileCache.put(name, f);
>             lastModifiedCache.put(name, new Long(f.lastModified()));
>         }
>         else
>             fileCache.put(name, null);
>         return url.openStream();
>     }
> 
>     public boolean isSourceModified(Resource res) {
>         String name = res.getName();
>         if (fileCache.containsKey(name)) {
>             File f = (File) fileCache.get(name);
>             if (f == null) {
>                 return false;
>             }
>             else {
>                 long l = f.lastModified();
>                 Long L = (Long) lastModifiedCache.get(name);
>                 return (L!=null) && (L.longValue() < l);
>             }
>         }
>         return false;
>     }
> 
>     public long getLastModified(Resource res) {
>         String name = res.getName();
>         Long L = (Long) lastModifiedCache.get(name);
>         if (L!= null) {
>             return L.longValue();
>         }
>         return 0L;
>     }
> 
>     private Map fileCache = Collections.synchronizedMap(new HashMap());
>     private Map lastModifiedCache = Collections.synchronizedMap(new
> HashMap());
> }

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
You have a genius for suggesting things I've come a cropper with!

Mime
View raw message