diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSGrammar.y.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSGrammar.y --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSGrammar.y.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-11 16:55:20.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSGrammar.y 2010-02-25 17:07:29.114742034 +0100 @@ -416,7 +416,9 @@ valid_rule: ; rule: - valid_rule + valid_rule { + static_cast(parser)->m_hadSyntacticallyValidCSSRule = true; + } | invalid_rule | invalid_at | invalid_import @@ -1517,8 +1519,12 @@ invalid_rule: ; invalid_block: - '{' error invalid_block_list error closing_brace - | '{' error closing_brace + '{' error invalid_block_list error closing_brace { + static_cast(parser)->invalidBlockHit(); + } + | '{' error closing_brace { + static_cast(parser)->invalidBlockHit(); + } ; invalid_block_list: diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSImportRule.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSImportRule.cpp --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSImportRule.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-11 16:55:20.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSImportRule.cpp 2010-02-25 17:13:34.292803953 +0100 @@ -25,6 +25,7 @@ #include "CachedCSSStyleSheet.h" #include "DocLoader.h" #include "Document.h" +#include "SecurityOrigin.h" #include "MediaList.h" #include "Settings.h" #include @@ -60,11 +61,21 @@ void CSSImportRule::setCSSStyleSheet(con m_styleSheet->setParent(0); m_styleSheet = CSSStyleSheet::create(this, url, charset); + bool crossOriginCSS = false; + bool validMIMEType = false; CSSStyleSheet* parent = parentStyleSheet(); bool strict = !parent || parent->useStrictParsing(); - String sheetText = sheet->sheetText(strict); + bool enforceMIMEType = strict; + + String sheetText = sheet->sheetText(enforceMIMEType, &validMIMEType); m_styleSheet->parseString(sheetText, strict); + if (!parent || !parent->doc() || !parent->doc()->securityOrigin()->canRequest(KURL(ParsedURLString, url))) + crossOriginCSS = true; + + if (crossOriginCSS && !validMIMEType && !m_styleSheet->hasSyntacticallyValidCSSHeader()) + m_styleSheet = CSSStyleSheet::create(this, url, charset); + if (strict && parent && parent->doc() && parent->doc()->settings() && parent->doc()->settings()->needsSiteSpecificQuirks()) { // Work around . DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css")); diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSParser.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSParser.cpp --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSParser.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-25 17:07:29.101741771 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSParser.cpp 2010-02-25 17:07:29.117741744 +0100 @@ -139,6 +139,7 @@ CSSParser::CSSParser(bool strictParsing) , m_currentShorthand(0) , m_implicitShorthand(false) , m_hasFontFaceOnlyValues(false) + , m_hadSyntacticallyValidCSSRule(false) , m_defaultNamespace(starAtom) , m_data(0) , yy_start(1) @@ -5175,6 +5176,12 @@ WebKitCSSKeyframeRule* CSSParser::create return keyframePtr; } +void CSSParser::invalidBlockHit() +{ + if (m_styleSheet && !m_hadSyntacticallyValidCSSRule) + m_styleSheet->setHasSyntacticallyValidCSSHeader(false); +} + static int cssPropertyID(const UChar* propertyName, unsigned length) { if (!length) diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSParser.h.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSParser.h --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSParser.h.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-11 16:55:20.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSParser.h 2010-02-25 17:07:29.117741744 +0100 @@ -191,6 +191,7 @@ namespace WebCore { bool addVariableDeclarationBlock(const CSSParserString&); bool checkForVariables(CSSParserValueList*); void addUnresolvedProperty(int propId, bool important); + void invalidBlockHit(); Vector* reusableSelectorVector() { return &m_reusableSelectorVector; } @@ -212,6 +213,7 @@ namespace WebCore { bool m_implicitShorthand; bool m_hasFontFaceOnlyValues; + bool m_hadSyntacticallyValidCSSRule; Vector m_variableNames; Vector > m_variableValues; diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.cpp --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-11 16:55:19.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.cpp 2010-02-25 17:07:29.118741824 +0100 @@ -41,6 +41,7 @@ CSSStyleSheet::CSSStyleSheet(CSSStyleShe , m_loadCompleted(false) , m_strictParsing(!parentSheet || parentSheet->useStrictParsing()) , m_isUserStyleSheet(parentSheet ? parentSheet->isUserStyleSheet() : false) + , m_hasSyntacticallyValidCSSHeader(true) { } @@ -52,6 +53,7 @@ CSSStyleSheet::CSSStyleSheet(Node* paren , m_loadCompleted(false) , m_strictParsing(false) , m_isUserStyleSheet(false) + , m_hasSyntacticallyValidCSSHeader(true) { } @@ -61,6 +63,7 @@ CSSStyleSheet::CSSStyleSheet(CSSRule* ow , m_charset(charset) , m_loadCompleted(false) , m_strictParsing(!ownerRule || ownerRule->useStrictParsing()) + , m_hasSyntacticallyValidCSSHeader(true) { CSSStyleSheet* parentSheet = ownerRule ? ownerRule->parentStyleSheet() : 0; m_doc = parentSheet ? parentSheet->doc() : 0; diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.h.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.h --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.h.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-11 16:55:20.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.h 2010-02-25 17:07:29.118741824 +0100 @@ -95,6 +95,8 @@ public: void setIsUserStyleSheet(bool b) { m_isUserStyleSheet = b; } bool isUserStyleSheet() const { return m_isUserStyleSheet; } + void setHasSyntacticallyValidCSSHeader(bool b) { m_hasSyntacticallyValidCSSHeader = b; } + bool hasSyntacticallyValidCSSHeader() const { return m_hasSyntacticallyValidCSSHeader; } private: CSSStyleSheet(Node* ownerNode, const String& href, const String& charset); @@ -110,6 +112,7 @@ private: bool m_loadCompleted : 1; bool m_strictParsing : 1; bool m_isUserStyleSheet : 1; + bool m_hasSyntacticallyValidCSSHeader : 1; }; } // namespace diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.cpp --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-11 16:55:19.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/dom/ProcessingInstruction.cpp 2010-02-25 17:07:29.118741824 +0100 @@ -203,7 +203,10 @@ void ProcessingInstruction::setCSSStyleS #endif RefPtr newSheet = CSSStyleSheet::create(this, url, charset); m_sheet = newSheet; - parseStyleSheet(sheet->sheetText()); + // We don't need the cross-origin security check here because we are + // getting the sheet text in "strict" mode. This enforces a valid CSS MIME + // type. + parseStyleSheet(sheet->sheetText(true)); newSheet->setTitle(m_title); newSheet->setMedia(MediaList::create(newSheet.get(), m_media)); newSheet->setDisabled(m_alternate); diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/html/HTMLLinkElement.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/html/HTMLLinkElement.cpp --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/html/HTMLLinkElement.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-11 16:55:17.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/html/HTMLLinkElement.cpp 2010-02-25 17:07:29.119741915 +0100 @@ -260,14 +260,27 @@ void HTMLLinkElement::setCSSStyleSheet(c bool strictParsing = !document()->inCompatMode(); bool enforceMIMEType = strictParsing; + bool crossOriginCSS = false; + bool validMIMEType = false; // Check to see if we should enforce the MIME type of the CSS resource in strict mode. // Running in iWeb 2 is one example of where we don't want to - if (enforceMIMEType && document()->page() && !document()->page()->settings()->enforceCSSMIMETypeInStrictMode()) enforceMIMEType = false; - String sheetText = sheet->sheetText(enforceMIMEType); + String sheetText = sheet->sheetText(enforceMIMEType, &validMIMEType); m_sheet->parseString(sheetText, strictParsing); + // If we're loading a stylesheet cross-origin, and the MIME type is not + // standard, require the CSS to at least start with a syntactically + // valid CSS rule. + // This prevents an attacker playing games by injecting CSS strings into + // HTML, XML, JSON, etc. etc. + if (!document()->securityOrigin()->canRequest(KURL(ParsedURLString, url))) + crossOriginCSS = true; + + if (crossOriginCSS && !validMIMEType && !m_sheet->hasSyntacticallyValidCSSHeader()) + m_sheet = CSSStyleSheet::create(this, url, charset); + if (strictParsing && document()->settings() && document()->settings()->needsSiteSpecificQuirks()) { // Work around . DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css")); diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/loader/CachedCSSStyleSheet.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/loader/CachedCSSStyleSheet.cpp --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/loader/CachedCSSStyleSheet.cpp.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-11 16:55:19.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/loader/CachedCSSStyleSheet.cpp 2010-02-25 17:07:29.119741915 +0100 @@ -71,11 +71,11 @@ String CachedCSSStyleSheet::encoding() c return m_decoder->encoding().name(); } -const String CachedCSSStyleSheet::sheetText(bool enforceMIMEType) const +const String CachedCSSStyleSheet::sheetText(bool enforceMIMEType, bool* hasValidMIMEType) const { ASSERT(!isPurgeable()); - if (!m_data || m_data->isEmpty() || !canUseSheet(enforceMIMEType)) + if (!m_data || m_data->isEmpty() || !canUseSheet(enforceMIMEType, hasValidMIMEType)) return String(); if (!m_decodedSheetText.isNull()) @@ -122,12 +122,12 @@ void CachedCSSStyleSheet::error() checkNotify(); } -bool CachedCSSStyleSheet::canUseSheet(bool enforceMIMEType) const +bool CachedCSSStyleSheet::canUseSheet(bool enforceMIMEType, bool* hasValidMIMEType) const { if (errorOccurred()) return false; - if (!enforceMIMEType) + if (!enforceMIMEType && !hasValidMIMEType) return true; // This check exactly matches Firefox. Note that we grab the Content-Type @@ -138,7 +138,12 @@ bool CachedCSSStyleSheet::canUseSheet(bo // This code defaults to allowing the stylesheet for non-HTTP protocols so // folks can use standards mode for local HTML documents. String mimeType = extractMIMETypeFromMediaType(response().httpHeaderField("Content-Type")); - return mimeType.isEmpty() || equalIgnoringCase(mimeType, "text/css") || equalIgnoringCase(mimeType, "application/x-unknown-content-type"); + bool typeOK = mimeType.isEmpty() || equalIgnoringCase(mimeType, "text/css") || equalIgnoringCase(mimeType, "application/x-unknown-content-type"); + if (hasValidMIMEType) + *hasValidMIMEType = typeOK; + if (!enforceMIMEType) + return true; + return typeOK; } } diff -up qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/loader/CachedCSSStyleSheet.h.cve-2010-0051-lax-css-parsing-cross-domain-theft qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/loader/CachedCSSStyleSheet.h --- qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/loader/CachedCSSStyleSheet.h.cve-2010-0051-lax-css-parsing-cross-domain-theft 2010-02-11 16:55:19.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/loader/CachedCSSStyleSheet.h 2010-02-25 17:07:29.120741848 +0100 @@ -40,7 +40,7 @@ namespace WebCore { CachedCSSStyleSheet(const String& URL, const String& charset); virtual ~CachedCSSStyleSheet(); - const String sheetText(bool enforceMIMEType = true) const; + const String sheetText(bool enforceMIMEType = true, bool* hasValidMIMEType = 0) const; virtual void didAddClient(CachedResourceClient*); @@ -56,7 +56,7 @@ namespace WebCore { void checkNotify(); private: - bool canUseSheet(bool enforceMIMEType) const; + bool canUseSheet(bool enforceMIMEType, bool* hasValidMIMEType) const; protected: RefPtr m_decoder;