Fix privacy leak where script could get the path to the file selected in a file input. Bug 143220, r+sr=sicking, a=schrep.

This commit is contained in:
bzbarsky@mit.edu 2007-11-14 22:16:06 -08:00
parent 086bfe7160
commit c667bcaf6e
5 changed files with 99 additions and 18 deletions

View File

@ -162,6 +162,12 @@ public:
static PRBool IsCallerTrustedForWrite();
/**
* Check whether a caller is trusted to have aCapability. This also
* checks for UniversalXPConnect in addition to aCapability.
*/
static PRBool IsCallerTrustedForCapability(const char* aCapability);
/**
* Do not ever pass null pointers to this method. If one of your
* nsIContents is null, you have to decide for yourself what

View File

@ -744,18 +744,20 @@ nsContentUtils::Shutdown()
nsAutoGCRoot::Shutdown();
}
static PRBool IsCallerTrustedForCapability(const char* aCapability)
// static
PRBool
nsContentUtils::IsCallerTrustedForCapability(const char* aCapability)
{
// The secman really should handle UniversalXPConnect case, since that
// should include UniversalBrowserRead... doesn't right now, though.
PRBool hasCap;
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
if (NS_FAILED(ssm->IsCapabilityEnabled(aCapability, &hasCap)))
if (NS_FAILED(sSecurityManager->IsCapabilityEnabled(aCapability, &hasCap)))
return PR_FALSE;
if (hasCap)
return PR_TRUE;
if (NS_FAILED(ssm->IsCapabilityEnabled("UniversalXPConnect", &hasCap)))
if (NS_FAILED(sSecurityManager->IsCapabilityEnabled("UniversalXPConnect",
&hasCap)))
return PR_FALSE;
return hasCap;
}

View File

@ -740,11 +740,20 @@ nsHTMLInputElement::GetValue(nsAString& aValue)
}
if (mType == NS_FORM_INPUT_FILE) {
if (mFileName) {
aValue = *mFileName;
}
else {
aValue.Truncate();
if (nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
if (mFileName) {
aValue = *mFileName;
}
else {
aValue.Truncate();
}
} else {
// Just return the leaf name
nsCOMPtr<nsIFile> file;
GetFile(getter_AddRefs(file));
if (!file || NS_FAILED(file->GetLeafName(aValue))) {
aValue.Truncate();
}
}
return NS_OK;
@ -771,15 +780,7 @@ nsHTMLInputElement::SetValue(const nsAString& aValue)
// OK and gives pages a way to clear a file input if necessary.
if (mType == NS_FORM_INPUT_FILE) {
if (!aValue.IsEmpty()) {
nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager();
PRBool enabled;
nsresult rv =
securityManager->IsCapabilityEnabled("UniversalFileRead", &enabled);
NS_ENSURE_SUCCESS(rv, rv);
if (!enabled) {
if (!nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
// setting the value of a "FILE" input widget requires the
// UniversalFileRead privilege
return NS_ERROR_DOM_SECURITY_ERR;

View File

@ -59,6 +59,7 @@ _TEST_FILES = test_bug589.html \
bug100533_load.html \
bug100533_iframe.html \
test_bug100533.html \
test_bug143220.html \
test_bug237071.html \
bug242709_iframe.html \
bug242709_load.html \

View File

@ -0,0 +1,71 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=143220
-->
<head>
<title>Test for Bug 143220</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=143220">Mozilla Bug 143220</a>
<p id="display">
<input type="file" id="i1">
<input type="file" id="i2">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 143220 **/
var leafName;
var fullPath;
function initVals() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
var file = dirSvc.get("XpcomLib", Components.interfaces.nsILocalFile);
isnot(file, null, "Must have file here");
leafName = file.leafName;
fullPath = file.path;
}
function initControl1() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalFileRead");
$("i1").value = fullPath;
is($("i1").value, fullPath, "Should have set full path 1");
}
function initControl2() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
$("i2").value = fullPath;
is($("i2").value, fullPath, "Should have set full path 2");
}
initVals();
// Check that we can't just set the value
try {
$("i1").value = fullPath;
is(0, 1, "Should have thrown exception on set!");
} catch(e) {
is($("i1").value, "", "Shouldn't have value here");
}
initControl1();
initControl2();
is($("i1").value, leafName, "Leaking full value?");
is($("i2").value, leafName, "Leaking full value?");
</script>
</pre>
</body>
</html>