aboutsummaryrefslogtreecommitdiffstats
path: root/Mailman/Cgi
diff options
context:
space:
mode:
authormsapiro <>2005-12-12 00:47:25 +0000
committermsapiro <>2005-12-12 00:47:25 +0000
commit4899c4bbc49202ae6973a71017262bfba572edee (patch)
treeea8cf26f74f14cc8ac6c538f6fb9654fa438c751 /Mailman/Cgi
parent85ebd1b7e840ec979c3a5d52f2c3b58594b5a820 (diff)
downloadmailman2-4899c4bbc49202ae6973a71017262bfba572edee.tar.gz
mailman2-4899c4bbc49202ae6973a71017262bfba572edee.tar.xz
mailman2-4899c4bbc49202ae6973a71017262bfba572edee.zip
Fixes for bug 1080943.
Add error response for ./ and ../ in URL
Diffstat (limited to 'Mailman/Cgi')
-rw-r--r--Mailman/Cgi/private.py33
1 files changed, 27 insertions, 6 deletions
diff --git a/Mailman/Cgi/private.py b/Mailman/Cgi/private.py
index cbab3b06..5830e933 100644
--- a/Mailman/Cgi/private.py
+++ b/Mailman/Cgi/private.py
@@ -12,7 +12,8 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
"""Provide a password-interface wrapper around private archives.
"""
@@ -67,10 +68,17 @@ def main():
return
path = os.environ.get('PATH_INFO')
+ tpath = true_path(path)
+ if tpath <> path[1:]:
+ msg = _('Private archive - "./" and "../" not allowed in URL.')
+ doc.SetTitle(msg)
+ doc.AddItem(Header(2, msg))
+ print doc.Format()
+ syslog('error', 'Private archive hostile path: %s', path)
+ return
# BAW: This needs to be converted to the Site module abstraction
true_filename = os.path.join(
- mm_cfg.PRIVATE_ARCHIVE_FILE_DIR,
- true_path(path))
+ mm_cfg.PRIVATE_ARCHIVE_FILE_DIR, tpath)
listname = parts[0].lower()
mboxfile = ''
@@ -127,11 +135,24 @@ def main():
# Output the password form
charset = Utils.GetCharSet(mlist.preferred_language)
print 'Content-type: text/html; charset=' + charset + '\n\n'
- while path and path[0] == '/':
- path=path[1:] # Remove leading /'s
+ # Put the original full path in the authorization form, but avoid
+ # trailing slash if we're not adding parts. We add it below.
+ action = mlist.GetScriptURL('private', absolute=1)
+ if parts[1:]:
+ action = os.path.join(action, SLASH.join(parts[1:]))
+ # If we added '/index.html' to true_filename, add a slash to the
+ # URL. We need this because we no longer add the trailing slash in
+ # the private.html template. It's always OK to test parts[-1]
+ # since we've already verified parts[0] is listname.
+ # The basic rule is if the post URL (action) is a directory, it must
+ # be slash terminated, and not if it's a file. Otherwise, relative
+ # links in the target archive page don't work.
+ if true_filename.endswith('/index.html') and \
+ parts[-1] <> 'index.html':
+ action += SLASH
print Utils.maketext(
'private.html',
- {'action' : mlist.GetScriptURL('private', absolute=1),
+ {'action' : action,
'realname': mlist.real_name,
'message' : message,
}, mlist=mlist)