[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdelibs/khtml
From: Maks Orlovich <maksim () kde ! org>
Date: 2010-11-12 2:33:01
Message-ID: 20101112023301.E7A4BAC89E () svn ! kde ! org
[Download RAW message or body]
SVN commit 1195832 by orlovich:
Adopt WebCore's SecurityOrigin class, as it lets us nicely centralize various XSS \
check details --- in particular those we need for postMessage.
M +1 -0 CMakeLists.txt
M +13 -4 ecma/kjs_data.cpp
M +2 -1 ecma/kjs_data.h
M +13 -6 ecma/kjs_window.cpp
M +1 -1 html/html_imageimpl.cpp
M +10 -13 khtml_part.cpp
M +19 -11 xml/dom_docimpl.cpp
M +9 -2 xml/dom_docimpl.h
AM xml/security_origin.cpp [License: BSD]
AM xml/security_origin.h [License: BSD]
--- trunk/KDE/kdelibs/khtml/CMakeLists.txt #1195831:1195832
@@ -372,6 +372,7 @@
# khtml/xml/Makefile.am: khtmlxml
set(khtmlxml_STAT_SRCS
+ ${CMAKE_SOURCE_DIR}/khtml/xml/security_origin.cpp
${CMAKE_SOURCE_DIR}/khtml/xml/dom_docimpl.cpp
${CMAKE_SOURCE_DIR}/khtml/xml/dom_nodeimpl.cpp
${CMAKE_SOURCE_DIR}/khtml/xml/dom_nodelistimpl.cpp
--- trunk/KDE/kdelibs/khtml/ecma/kjs_data.cpp #1195831:1195832
@@ -127,8 +127,10 @@
}
//------------------------------------------------------------------------------
-DelayedPostMessage::DelayedPostMessage(const QString& _targetOrigin, JSValue* \
_payload):
- targetOrigin(_targetOrigin), payload(_payload)
+DelayedPostMessage::DelayedPostMessage(const QString& _sourceOrigin,
+ const QString& _targetOrigin,
+ JSValue* _payload):
+ sourceOrigin(_sourceOrigin), targetOrigin(_targetOrigin), payload(_payload)
{}
void DelayedPostMessage::mark()
@@ -144,11 +146,18 @@
kDebug(6070) << doc << targetOrigin;
if (doc) {
// Verify destination.
- if (targetOrigin != QLatin1String("*")) {
+ bool safe = false;
+ if (targetOrigin == QLatin1String("*")) {
+ safe = true;
+ } else {
KUrl targetUrl(targetOrigin);
- kDebug(6070) << doc->domain();
+ kDebug(6070) << doc->origin()->toString();
}
+
+ if (safe) {
+
}
+ }
return true;
}
--- trunk/KDE/kdelibs/khtml/ecma/kjs_data.h #1195831:1195832
@@ -54,11 +54,12 @@
class DelayedPostMessage: public Window::DelayedAction
{
public:
- DelayedPostMessage(const QString& _targetOrigin, JSValue* _payload);
+ DelayedPostMessage(const QString& _sourceOrigin, const QString& _targetOrigin, \
JSValue* _payload);
virtual void mark();
virtual bool execute(Window*);
private:
+ QString sourceOrigin;
QString targetOrigin;
JSValue* payload;
};
--- trunk/KDE/kdelibs/khtml/ecma/kjs_window.cpp #1195831:1195832
@@ -1361,17 +1361,17 @@
kDebug(6070) << "Window::isSafeScript: active part has no document!";
return false;
}
- DOM::DOMString actDomain = actDocument->domain();
- DOM::DOMString thisDomain = thisDocument->domain();
+ khtml::SecurityOrigin* actDomain = actDocument->origin();
+ khtml::SecurityOrigin* thisDomain = thisDocument->origin();
- if ( actDomain == thisDomain ) {
+ if ( actDomain->canAccess( thisDomain ) ) {
#ifdef KJS_VERBOSE
//kDebug(6070) << "JavaScript: access granted, domain is '" << \
actDomain.string() << "'"; #endif
return true;
}
- kDebug(6070) << "WARNING: JavaScript: access denied for current frame '" << \
actDomain.string() << "' to frame '" << thisDomain.string() << "'"; + kDebug(6070) \
<< "WARNING: JavaScript: access denied for current frame '" << actDomain->toString() \
<< "' to frame '" << thisDomain->toString() << "'"; // TODO after 3.1: throw \
security exception (exec->setException()) return false;
}
@@ -1807,7 +1807,7 @@
khtmlpart->end();
if ( p->docImpl() ) {
//kDebug(6070) << "Setting domain to " << p->docImpl()->domain().string();
- khtmlpart->docImpl()->setDomain( p->docImpl()->domain());
+ khtmlpart->docImpl()->setOrigin( p->docImpl()->origin());
khtmlpart->docImpl()->setBaseURL( p->docImpl()->baseURL() );
}
}
@@ -2041,6 +2041,13 @@
return jsString(ret);
}
case Window::PostMessage: {
+ // Get our own origin.
+ if (!part->xmlDocImpl()) {
+ setDOMException(exec, DOM::DOMException::SECURITY_ERR);
+ return jsUndefined();
+ }
+
+ QString sourceOrigin = part->xmlDocImpl()->origin()->toString();
QString targetOrigin = args[1]->toString(exec).qstring();
KUrl targetURL(targetOrigin);
kDebug(6070) << "postMessage targetting:" << targetOrigin;
@@ -2058,7 +2065,7 @@
JSValue* payload = cloneData(exec, args[0]);
// Queue the actual action, for after script execution.
- window->m_delayed.append(new DelayedPostMessage(targetOrigin, payload));
+ window->m_delayed.append(new DelayedPostMessage(sourceOrigin, targetOrigin, \
payload)); }
};
--- trunk/KDE/kdelibs/khtml/html/html_imageimpl.cpp #1195831:1195832
@@ -99,7 +99,7 @@
}
KUrl fullURL = document()->completeURL(parsedURL.string());
- if (document()->URL().host() != fullURL.host() || \
document()->URL().port() != fullURL.port()) + if \
(document()->origin()->taintsCanvas(fullURL)) unsafe = true;
}
}
--- trunk/KDE/kdelibs/khtml/khtml_part.cpp #1195831:1195832
@@ -5040,12 +5040,13 @@
void KHTMLPartPrivate::propagateInitialDomainTo(KHTMLPart* kid)
{
// This method is used to propagate our domain information for
- // child frames, potentially widening to have less periods, and also
- // to provide a domain for about: or JavaScript: URLs altogether.
- // Note that DocumentImpl:;setDomain does the checking.
- if ( m_doc && kid->d->m_doc )
- kid->d->m_doc->setDomain( m_doc->domain() );
+ // child frames, to provide a domain for about: or JavaScript: URLs
+ if ( m_doc && kid->d->m_doc ) {
+ DocumentImpl* kidDoc = kid->d->m_doc;
+ if ( kidDoc->origin()->isEmpty() )
+ kidDoc->setOrigin( m_doc->origin() );
}
+}
void KHTMLPart::slotChildURLRequest( const KUrl &url, const \
KParts::OpenUrlArguments& args, const KParts::BrowserArguments &browserArgs ) {
@@ -5147,14 +5148,10 @@
// now compare the domains
if (callingHtmlPart && callingHtmlPart->xmlDocImpl() && xmlDocImpl()) {
- DOM::DOMString actDomain = callingHtmlPart->xmlDocImpl()->domain();
- DOM::DOMString destDomain = xmlDocImpl()->domain();
+ khtml::SecurityOrigin* actDomain = callingHtmlPart->xmlDocImpl()->origin();
+ khtml::SecurityOrigin* destDomain = xmlDocImpl()->origin();
-#ifdef DEBUG_FINDFRAME
- kDebug(6050) << "actDomain =" << actDomain.string() << "destDomain =" << \
destDomain.string();
-#endif
-
- if (actDomain == destDomain)
+ if (actDomain->canAccess(destDomain))
return true;
}
#ifdef DEBUG_FINDFRAME
@@ -5170,7 +5167,7 @@
KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, \
khtml::ChildFrame **childFrame ) {
#ifdef DEBUG_FINDFRAME
- kDebug(6050) << this << "URL =" << url() << "name =" << name() << \
"findFrameParent(" << f << ")"; + kDebug(6050) << this << "URL =" << url() << "name \
=" << objectName() << "findFrameParent(" << f << ")"; #endif
// Check access
KHTMLPart* const callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
--- trunk/KDE/kdelibs/khtml/xml/dom_docimpl.cpp #1195831:1195832
@@ -2844,34 +2844,42 @@
return childFrame->m_partContainerElement.data();
}
+khtml::SecurityOrigin* DocumentImpl::origin() const
+{
+ if (!m_origin)
+ m_origin = SecurityOrigin::create(URL());
+ return m_origin.get();
+}
+
+void DocumentImpl::setOrigin(khtml::SecurityOrigin* newOrigin)
+{
+ assert(origin()->isEmpty());
+ m_origin = newOrigin;
+}
+
DOMString DocumentImpl::domain() const
{
- if ( m_domain.isEmpty() ) // not set yet (we set it on demand to save time and \
space)
- m_domain = URL().host(); // Initially set to the host
- return m_domain;
+ return origin()->domain();
}
void DocumentImpl::setDomain(const DOMString &newDomain)
{
- if ( m_domain.isEmpty() ) // not set yet (we set it on demand to save time and \
space)
- m_domain = URL().host().toLower(); // Initially set to the host
+ // ### this test really should move to SecurityOrigin..
+ DOMString oldDomain = origin()->domain();
- if ( m_domain.isEmpty() /*&& part() && part()->openedByJS()*/ )
- m_domain = newDomain.lower();
-
// Both NS and IE specify that changing the domain is only allowed when
// the new domain is a suffix of the old domain.
- int oldLength = m_domain.length();
+ int oldLength = oldDomain.length();
int newLength = newDomain.length();
if ( newLength < oldLength ) // e.g. newDomain=kde.org (7) and \
m_domain=www.kde.org (11) {
- DOMString test = m_domain.copy();
+ DOMString test = oldDomain.copy();
DOMString reference = newDomain.lower();
if ( test[oldLength - newLength - 1] == '.' ) // Check that it's a \
subdomain, not e.g. "de.org" {
test.remove( 0, oldLength - newLength ); // now test is "kde.org" from \
m_domain
if ( test == reference ) // and we check that it's the \
same thing as newDomain
- m_domain = reference;
+ m_origin->setDomainFromDOM( reference.string() );
}
}
}
--- trunk/KDE/kdelibs/khtml/xml/dom_docimpl.h #1195831:1195832
@@ -31,6 +31,7 @@
#include "xml/dom_nodelistimpl.h"
#include "xml/dom_textimpl.h"
#include "xml/dom2_traversalimpl.h"
+#include "xml/security_origin.h"
#include "misc/shared.h"
#include "misc/loader.h"
#include "misc/seed.h"
@@ -559,8 +560,13 @@
// Returns 0 if this is the top level document.
HTMLPartContainerElementImpl *ownerElement() const;
+ khtml::SecurityOrigin* origin() const;
+ void setOrigin(khtml::SecurityOrigin*);
+
+ // These represent JS operations on domain strings, rather than full-blown \
origins. + // (so no port, protocol, etc.)
+ void setDomain( const DOMString &newDomain );
DOMString domain() const;
- void setDomain( const DOMString &newDomain ); // not part of the DOM
bool isURLAllowed(const QString& url) const;
@@ -721,7 +727,8 @@
SharedPtr<khtml::RenderArena> m_renderArena;
private:
JSEditor *m_jsEditor;
- mutable DOMString m_domain;
+ mutable RefPtr<khtml::SecurityOrigin> m_origin;
+
int m_selfOnlyRefCount;
public:
// Nodes belonging to this document hold "self-only" references -
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic