[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