From: Brian Warner Date: Mon, 16 Jul 2007 18:53:12 +0000 (-0700) Subject: webish.py: disallow slashes in POSTed filenames. Closes #75. X-Git-Url: https://git.rkrishnan.org/components/com_hotproperty/reliability?a=commitdiff_plain;h=f207f4a199452da9159d73145ddb44cac8f7f24f;p=tahoe-lafs%2Ftahoe-lafs.git webish.py: disallow slashes in POSTed filenames. Closes #75. --- diff --git a/docs/webapi.txt b/docs/webapi.txt index 1089b805..1a9f75b8 100644 --- a/docs/webapi.txt +++ b/docs/webapi.txt @@ -234,7 +234,8 @@ for files and directories which do not yet exist. this because forms are the only way for a web browser to upload a file (browsers do not know how to do PUT or DELETE). The file's contents and the new child name will be included in the form's arguments. This can only be - used to upload a single file at a time. + used to upload a single file at a time. To avoid confusion, name= is not + allowed to contain a slash (a 400 Bad Request error will result). POST DIRURL t=mkdir diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index ff450d71..e31f8efe 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -310,13 +310,18 @@ class Web(unittest.TestCase): return client.getPage(url, method="POST", postdata=body, headers=headers, followRedirect=False) - def shouldFail(self, res, expected_failure, which, substring=None): + def shouldFail(self, res, expected_failure, which, + substring=None, response_substring=None): if isinstance(res, failure.Failure): res.trap(expected_failure) if substring: self.failUnless(substring in str(res), "substring '%s' not in '%s'" % (substring, str(res))) + if response_substring: + self.failUnless(response_substring in res.value.response, + "respose substring '%s' not in '%s'" + % (response_substring, res.value.response)) else: self.fail("%s was supposed to raise %s, not get '%s'" % (which, expected_failure, res)) @@ -776,6 +781,23 @@ class Web(unittest.TestCase): d.addCallback(_check) return d + def test_POST_upload_named_badfilename(self): # YES + d = self.POST("/vdrive/global/foo", t="upload", + name="slashes/are/bad.txt", file=self.NEWFILE_CONTENTS) + d.addBoth(self.shouldFail, error.Error, + "test_POST_upload_named_badfilename", + "400 Bad Request", + "name= may not contain a slash", + ) + def _check(res): + # make sure that nothing was added + kids = sorted(self._foo_node.children.keys()) + self.failUnlessEqual(sorted(["bar.txt", "blockingfile", + "empty", "sub"]), + kids) + d.addCallback(_check) + return d + def test_POST_mkdir(self): # YES, return value? d = self.POST("/vdrive/global/foo", t="mkdir", name="newdir") def _check(res): diff --git a/src/allmydata/webish.py b/src/allmydata/webish.py index 94b89a6d..adcb575e 100644 --- a/src/allmydata/webish.py +++ b/src/allmydata/webish.py @@ -502,6 +502,10 @@ class POSTHandler(rend.Page): name = req.args["name"][0] elif name in req.fields: name = req.fields["name"].value + if "/" in name: + req.setResponseCode(http.BAD_REQUEST) + req.setHeader("content-type", "text/plain") + return "name= may not contain a slash" when_done = None if "when_done" in req.args: