diff --git a/CHANGES b/CHANGES
index a6bae660a35fdea7ed68eb2281aeb6641e83bbad..01ec4dc86fee63d93a8970328ba1eb2b89bf7b05 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,22 @@
+0.5
+- A Template is explicitly disallowed
+  from having a url that normalizes to relative outside
+  of the root.   That is, if the Lookup is based 
+  at /home/mytemplates, an include that would place
+  the ultimate template at 
+  /home/mytemplates/../some_other_directory,
+  i.e. outside of /home/mytemplates,
+  is disallowed.   This usage was never intended
+  despite the lack of an explicit check.
+  The main issue this causes
+  is that module files can be written outside 
+  of the module root (or raise an error, if file perms aren't
+  set up), and can also lead to the same template being 
+  cached in the lookup under multiple, relative roots. 
+  TemplateLookup instead has always supported multiple 
+  file roots for this purpose.
+  [ticket:174]
+
 0.4.2
 - Fixed bug regarding <%call>/def calls w/ content
   whereby the identity of the "caller" callable
diff --git a/mako/__init__.py b/mako/__init__.py
index c9913ebf62af0eef5d888a39585ecdc3c8418bc6..5b067a3717e367f040fa8954f9463ca71b523064 100644
--- a/mako/__init__.py
+++ b/mako/__init__.py
@@ -5,5 +5,5 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 
-__version__ = '0.4.2'
+__version__ = '0.5.0'
 
diff --git a/mako/lookup.py b/mako/lookup.py
index b397d21f001b4430c9ca221bd2d1ebdb40ba3a31..e3d92da217929f8e96078f9cf50ae1fef5f58b68 100644
--- a/mako/lookup.py
+++ b/mako/lookup.py
@@ -204,7 +204,7 @@ class TemplateLookup(TemplateCollection):
         Note the "relativeto" argument is not supported here at the moment.
  
         """
- 
+
         try:
             if self.filesystem_checks:
                 return self._check(uri, self._collection[uri])
diff --git a/mako/template.py b/mako/template.py
index 903dc4254c9e315417f7995e4abeb42f9e12efef..3d02c55e618e532fd70425d68e6bc110e78ed7db 100644
--- a/mako/template.py
+++ b/mako/template.py
@@ -163,7 +163,17 @@ class Template(object):
         else:
             self.module_id = "memory:" + hex(id(self))
             self.uri = self.module_id
- 
+
+        u_norm = self.uri
+        if u_norm.startswith("/"):
+            u_norm = u_norm[1:]
+        u_norm = os.path.normpath(u_norm)
+        if u_norm.startswith(".."):
+            raise exceptions.TemplateLookupException(
+                    "Template uri \"%s\" is invalid - "
+                    "it cannot be relative outside "
+                    "of the root path." % self.uri)
+
         self.input_encoding = input_encoding
         self.output_encoding = output_encoding
         self.encoding_errors = encoding_errors
@@ -203,18 +213,14 @@ class Template(object):
             if module_filename is not None:
                 path = module_filename
             elif module_directory is not None:
-                u = self.uri
-                if u[0] == '/':
-                    u = u[1:]
                 path = os.path.abspath(
                         os.path.join(
                             os.path.normpath(module_directory), 
-                            os.path.normpath(u) + ".py"
+                            u_norm + ".py"
                             )
                         )
             else:
                 path = None
- 
             module = self._compile_from_file(path, filename)
         else:
             raise exceptions.RuntimeException(
diff --git a/test/templates/othersubdir/foo.html b/test/templates/othersubdir/foo.html
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/test/test_lookup.py b/test/test_lookup.py
index 190d8a516dbd18171bd6bc62bd8fa2cee5d5e0ed..40b900919a1655b983b2ae002556620ce687c82b 100644
--- a/test/test_lookup.py
+++ b/test/test_lookup.py
@@ -1,9 +1,11 @@
 from mako.template import Template
-from mako import lookup, exceptions
+from mako import lookup, exceptions, runtime
+from mako.util import FastEncodingBuffer
 from util import flatten_result, result_lines
 import unittest
+import os
 
-from test import TemplateTest, template_base, module_base
+from test import TemplateTest, template_base, module_base, assert_raises_message
 
 tl = lookup.TemplateLookup(directories=[template_base])
 class LookupTest(unittest.TestCase):
@@ -74,3 +76,29 @@ class LookupTest(unittest.TestCase):
         )
         assert f.uri not in tl._collection
 
+    def test_dont_accept_relative_outside_of_root(self):
+        """test the mechanics of an include where 
+        the include goes outside of the path"""
+        tl = lookup.TemplateLookup(directories=[os.path.join(template_base, "subdir")])
+        index = tl.get_template("index.html")
+
+        ctx = runtime.Context(FastEncodingBuffer())
+        ctx._with_template=index
+
+        assert_raises_message(
+            exceptions.TemplateLookupException,
+           "Template uri \"../index.html\" is invalid - it "
+            "cannot be relative outside of the root path",
+            runtime._lookup_template, ctx, "../index.html", index.uri
+        )
+
+        assert_raises_message(
+            exceptions.TemplateLookupException,
+           "Template uri \"../othersubdir/foo.html\" is invalid - it "
+            "cannot be relative outside of the root path",
+            runtime._lookup_template, ctx, "../othersubdir/foo.html", index.uri
+        )
+
+        # this is OK since the .. cancels out
+        t = runtime._lookup_template(ctx, "foo/../index.html", index.uri)
+
diff --git a/test/test_template.py b/test/test_template.py
index a62783e46b2e54a04b21b2c439da9a5f409bd465..4d301aab19281bb10d416edb4d2970cf693a74c8 100644
--- a/test/test_template.py
+++ b/test/test_template.py
@@ -9,7 +9,7 @@ import os
 from util import flatten_result, result_lines
 import codecs
 from test import TemplateTest, eq_, template_base, module_base, \
-    skip_if, assert_raises
+    skip_if, assert_raises, assert_raises_message
 
 class EncodingTest(TemplateTest):
     def test_unicode(self):
@@ -918,8 +918,25 @@ class FilenameToURITest(TemplateTest):
         finally:
             os.path = current_path
  
- 
- 
+    def test_dont_accept_relative_outside_of_root(self):
+        assert_raises_message(
+            exceptions.TemplateLookupException,
+            "Template uri \"../../foo.html\" is invalid - it "
+            "cannot be relative outside of the root path",
+            Template, "test", uri="../../foo.html", 
+        )
+
+        assert_raises_message(
+            exceptions.TemplateLookupException,
+            "Template uri \"/../../foo.html\" is invalid - it "
+            "cannot be relative outside of the root path",
+            Template, "test", uri="/../../foo.html", 
+        )
+
+        # normalizes in the root is OK
+        t = Template("test", uri="foo/bar/../../foo.html")
+        eq_(t.uri, "foo/bar/../../foo.html")
+
 class ModuleTemplateTest(TemplateTest):
     def test_module_roundtrip(self):
         lookup = TemplateLookup()