blob: 6bfbd6cfd1bfa8984545915a93ae96b41dac6a16 [file] [log] [blame]
--- o3d/ppapi_plugin/cross/whitelist.cc
+++ o3d/ppapi_plugin/cross/whitelist.cc
@@ -37,6 +37,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
+#include "ppapi/cpp/dev/url_util_dev.h"
#include "ppapi/cpp/private/var_private.h"
// TODO(jhorwich) Unfork this file when PPAPI plugin is merged into
@@ -56,41 +57,9 @@
O3D_PLUGIN_DOMAIN_WHITELIST
};
-static const char kHttpsProtocol[] = "https://";
-
-static std::string GetURL(pp::InstancePrivate *instance) {
- std::string url;
- pp::VarPrivate window = instance->GetWindowObject();
- pp::VarPrivate location = window.GetProperty("location");
- pp::VarPrivate href = location.GetProperty("href");
- url = href.AsString();
- return url;
-}
-
-static std::string ParseUrlHost(const std::string &in_url) {
- size_t host_start;
- if (in_url.find(kHttpsProtocol) == 0) {
- host_start = sizeof(kHttpsProtocol) - 1;
- } else {
- // Do not allow usage on non https pages.
- return "";
- }
- size_t path_start = in_url.find("/", host_start);
- if (path_start == std::string::npos) {
- path_start = in_url.size();
- }
- const std::string host_and_port(
- in_url.substr(host_start, path_start - host_start));
- size_t colon_pos = host_and_port.find(":");
- if (colon_pos == std::string::npos) {
- colon_pos = host_and_port.size();
- }
- return host_and_port.substr(0, colon_pos);
-}
-
-static bool IsDomainWhitelisted(const std::string &in_url) {
- std::string host(ParseUrlHost(in_url));
+static const char kHttpsProtocol[] = "https";
+static bool IsHostWhitelisted(std::string host) {
// convert the host to a lower-cased version so we
// don't have to worry about case mismatches.
std::transform(host.begin(), host.end(), host.begin(), ::tolower);
@@ -105,23 +74,46 @@
return false;
}
+static std::string GetURLComponent(std::string url,
+ const struct PP_URLComponent_Dev* comp) {
+ std::string result;
+ if (comp->begin >= 0 &&
+ comp->len > 0 &&
+ (comp->begin < url.size()) &&
+ (comp->len <= url.size() - comp->begin)) {
+ result = url.substr(comp->begin, comp->len);
+ }
+ return result;
+}
+
#endif // O3D_PLUGIN_DOMAIN_WHITELIST
bool IsDomainAuthorized(pp::InstancePrivate *instance) {
#ifdef O3D_PLUGIN_DOMAIN_WHITELIST
- std::string url(GetURL(instance));
- if (url.empty()) {
- // This can happen in Chrome due to a bug with cross-origin security checks,
- // including on legitimate pages. Until it's fixed we'll just allow any
- // domain when this happens.
- // http://code.google.com/p/chromium/issues/detail?id=64229
- LOG(WARNING) <<
- "Allowing use despite inability to determine the hosting page";
- return true;
+ const pp::URLUtil_Dev* utils = pp::URLUtil_Dev::Get();
+ if (utils == NULL) {
+ LOG(ERROR) << "Unable to get URLUtil_Dev interface - unauthorized";
+ return false;
+ }
+ PP_URLComponents_Dev components;
+ pp::Var doc_url = utils->GetDocumentURL(*instance, &components);
+ if (!doc_url.is_string()) {
+ LOG(ERROR) << "Unable to get document URL - unauthorized";
+ return false;
+ }
+ std::string url = doc_url.AsString();
+ std::string scheme = GetURLComponent(url, &components.scheme);
+ std::string host = GetURLComponent(url, &components.host);
+
+ // Require HTTPS
+ if (scheme.compare(kHttpsProtocol) != 0) {
+ LOG(ERROR) << "Non-HTTPS scheme - unauthorized";
+ return false;
}
- bool authorized = IsDomainWhitelisted(url);
+
+ bool authorized = IsHostWhitelisted(host);
if (!authorized) {
- LOG(ERROR) << "Unauthorized domain";
+ LOG(ERROR) << "Unauthorized host";
}
return authorized;
#else