bool CookieServiceParent::RecvSetCookieString(const URIParams& aHost, const bool& aIsForeign, const nsCString& aCookieString, const nsCString& aServerTime, const bool& aFromHttp, const IPC::SerializedLoadContext& aLoadContext) { if (!mCookieService) return true; // Deserialize URI. Having a host URI is mandatory and should always be // provided by the child; thus we consider failure fatal. nsCOMPtr<nsIURI> hostURI = DeserializeURI(aHost); if (!hostURI) return false; uint32_t appId; bool isInBrowserElement, isPrivate; bool valid = GetAppInfoFromParams(aLoadContext, appId, isInBrowserElement, isPrivate); if (!valid) { return false; } nsDependentCString cookieString(aCookieString, 0); //TODO: bug 812475, pass a real channel object mCookieService->SetCookieStringInternal(hostURI, aIsForeign, cookieString, aServerTime, aFromHttp, appId, isInBrowserElement, isPrivate, nullptr); return true; }
bool CookieServiceParent::RecvGetCookieString(const URIParams& aHost, const bool& aIsForeign, const bool& aFromHttp, const IPC::SerializedLoadContext& aLoadContext, nsCString* aResult) { if (!mCookieService) return true; // Deserialize URI. Having a host URI is mandatory and should always be // provided by the child; thus we consider failure fatal. nsCOMPtr<nsIURI> hostURI = DeserializeURI(aHost); if (!hostURI) return false; NeckoOriginAttributes attrs; bool isPrivate; bool valid = GetOriginAttributesFromParams(aLoadContext, attrs, isPrivate); if (!valid) { return false; } mCookieService->GetCookieStringInternal(hostURI, aIsForeign, aFromHttp, attrs, isPrivate, *aResult); return true; }
bool CookieServiceParent::RecvGetCookieString(const URIParams& aHost, const bool& aIsForeign, const bool& aFromHttp, const IPC::SerializedLoadContext& aLoadContext, PBrowserParent* aBrowser, nsCString* aResult) { if (!mCookieService) return true; // Deserialize URI. Having a host URI is mandatory and should always be // provided by the child; thus we consider failure fatal. nsCOMPtr<nsIURI> hostURI = DeserializeURI(aHost); if (!hostURI) return false; uint32_t appId; bool isInBrowserElement, isPrivate; bool valid = GetAppInfoFromParams(aLoadContext, aBrowser, appId, isInBrowserElement, isPrivate); if (!valid) { return false; } mCookieService->GetCookieStringInternal(hostURI, aIsForeign, aFromHttp, appId, isInBrowserElement, isPrivate, *aResult); return true; }
bool NeckoChild::RecvPredOnPredictDNS(const URIParams& aURI) { MOZ_ASSERT(NS_IsMainThread(), "PredictorChild::RecvOnPredictDNS off " "main thread."); nsCOMPtr<nsIURI> uri = DeserializeURI(aURI); // Get the current predictor nsresult rv = NS_OK; nsCOMPtr<nsINetworkPredictorVerifier> predictor = do_GetService("@mozilla.org/network/predictor;1", &rv); NS_ENSURE_SUCCESS(rv, false); predictor->OnPredictDNS(uri); return true; }
bool CookieServiceParent::RecvSetCookieString(const URIParams& aHost, const bool& aIsForeign, const nsCString& aCookieString, const nsCString& aServerTime, const bool& aFromHttp, const IPC::SerializedLoadContext& aLoadContext) { if (!mCookieService) return true; // Deserialize URI. Having a host URI is mandatory and should always be // provided by the child; thus we consider failure fatal. nsCOMPtr<nsIURI> hostURI = DeserializeURI(aHost); if (!hostURI) return false; uint32_t appId; bool isInBrowserElement, isPrivate; bool valid = GetAppInfoFromParams(aLoadContext, appId, isInBrowserElement, isPrivate); if (!valid) { return false; } // This is a gross hack. We've already computed everything we need to know // for whether to set this cookie or not, but we need to communicate all of // this information through to nsICookiePermission, which indirectly // computes the information from the channel. We only care about the // aIsPrivate argument as nsCookieService::SetCookieStringInternal deals // with aIsForeign before we have to worry about nsCookiePermission trying // to use the channel to inspect it. nsCOMPtr<nsIChannel> dummyChannel; CreateDummyChannel(hostURI, appId, isInBrowserElement, isPrivate, getter_AddRefs(dummyChannel)); // NB: dummyChannel could be null if something failed in CreateDummyChannel. nsDependentCString cookieString(aCookieString, 0); mCookieService->SetCookieStringInternal(hostURI, aIsForeign, cookieString, aServerTime, aFromHttp, appId, isInBrowserElement, isPrivate, dummyChannel); return true; }
already_AddRefed<nsIURI> DeserializeURI(const OptionalURIParams& aParams) { MOZ_ASSERT(NS_IsMainThread()); nsCOMPtr<nsIURI> uri; switch (aParams.type()) { case OptionalURIParams::Tvoid_t: break; case OptionalURIParams::TURIParams: uri = DeserializeURI(aParams.get_URIParams()); break; default: MOZ_CRASH("Unknown params!"); } return uri.forget(); }
PRemoteOpenFileParent* NeckoParent::AllocPRemoteOpenFileParent(const URIParams& aURI, const OptionalURIParams& aAppURI) { nsCOMPtr<nsIURI> uri = DeserializeURI(aURI); nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(uri); if (!fileURL) { return nullptr; } // security checks if (UsingNeckoIPCSecurity()) { nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID); if (!appsService) { return nullptr; } bool haveValidBrowser = false; bool hasManage = false; nsCOMPtr<mozIApplication> mozApp; for (uint32_t i = 0; i < Manager()->ManagedPBrowserParent().Length(); i++) { nsRefPtr<TabParent> tabParent = static_cast<TabParent*>(Manager()->ManagedPBrowserParent()[i]); uint32_t appId = tabParent->OwnOrContainingAppId(); nsresult rv = appsService->GetAppByLocalId(appId, getter_AddRefs(mozApp)); if (NS_FAILED(rv) || !mozApp) { continue; } hasManage = false; rv = mozApp->HasPermission("webapps-manage", &hasManage); if (NS_FAILED(rv)) { continue; } haveValidBrowser = true; break; } if (!haveValidBrowser) { return nullptr; } nsAutoCString requestedPath; fileURL->GetPath(requestedPath); NS_UnescapeURL(requestedPath); // Check if we load the whitelisted app uri for the neterror page. bool netErrorWhiteList = false; nsCOMPtr<nsIURI> appUri = DeserializeURI(aAppURI); if (appUri) { nsAdoptingString netErrorURI; netErrorURI = Preferences::GetString("b2g.neterror.url"); if (netErrorURI) { nsAutoCString spec; appUri->GetSpec(spec); netErrorWhiteList = spec.Equals(NS_ConvertUTF16toUTF8(netErrorURI).get()); } } if (hasManage || netErrorWhiteList) { // webapps-manage permission means allow reading any application.zip file // in either the regular webapps directory, or the core apps directory (if // we're using one). NS_NAMED_LITERAL_CSTRING(appzip, "/application.zip"); nsAutoCString pathEnd; requestedPath.Right(pathEnd, appzip.Length()); if (!pathEnd.Equals(appzip)) { return nullptr; } nsAutoCString pathStart; requestedPath.Left(pathStart, mWebAppsBasePath.Length()); if (!pathStart.Equals(mWebAppsBasePath)) { if (mCoreAppsBasePath.IsEmpty()) { return nullptr; } requestedPath.Left(pathStart, mCoreAppsBasePath.Length()); if (!pathStart.Equals(mCoreAppsBasePath)) { return nullptr; } } // Finally: make sure there are no "../" in URI. // Note: not checking for symlinks (would cause I/O for each path // component). So it's up to us to avoid creating symlinks that could // provide attack vectors. if (PL_strnstr(requestedPath.BeginReading(), "/../", requestedPath.Length())) { printf_stderr("NeckoParent::AllocPRemoteOpenFile: " "FATAL error: requested file URI '%s' contains '/../' " "KILLING CHILD PROCESS\n", requestedPath.get()); return nullptr; } } else { // regular packaged apps can only access their own application.zip file nsAutoString basePath; nsresult rv = mozApp->GetBasePath(basePath); if (NS_FAILED(rv)) { return nullptr; } nsAutoString uuid; rv = mozApp->GetId(uuid); if (NS_FAILED(rv)) { return nullptr; } nsPrintfCString mustMatch("%s/%s/application.zip", NS_LossyConvertUTF16toASCII(basePath).get(), NS_LossyConvertUTF16toASCII(uuid).get()); if (!requestedPath.Equals(mustMatch)) { printf_stderr("NeckoParent::AllocPRemoteOpenFile: " "FATAL error: app without webapps-manage permission is " "requesting file '%s' but is only allowed to open its " "own application.zip at %s: KILLING CHILD PROCESS\n", requestedPath.get(), mustMatch.get()); return nullptr; } } } RemoteOpenFileParent* parent = new RemoteOpenFileParent(fileURL); return parent; }