1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/* 2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2013 Google, Inc. All Rights Reserved. 3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modification, are permitted provided that the following conditions 6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * are met: 7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * documentation and/or other materials provided with the distribution. 12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "config.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/XSSAuditorDelegate.h" 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h" 30bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/frame/Frame.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/DocumentLoader.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoader.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoaderClient.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/PingLoader.h" 351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/JSONValues.h" 36bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/FormData.h" 3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/SecurityOrigin.h" 38591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/text/StringBuilder.h" 39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)namespace WebCore { 41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)String XSSInfo::buildConsoleError() const 43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) StringBuilder message; 45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) message.append("The XSS Auditor "); 461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) message.append(m_didBlockEntirePage ? "blocked access to" : "refused to execute a script in"); 47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) message.append(" '"); 481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) message.append(m_originalURL); 49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) message.append("' because "); 501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) message.append(m_didBlockEntirePage ? "the source code of a script" : "its source code"); 51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) message.append(" was found within the request."); 52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (m_didSendCSPHeader) 54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) message.append(" The server sent a 'Content-Security-Policy' header requesting this behavior."); 551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) else if (m_didSendXSSProtectionHeader) 56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) message.append(" The server sent an 'X-XSS-Protection' header requesting this behavior."); 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) message.append(" The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header."); 59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return message.toString(); 61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)bool XSSInfo::isSafeToSendToAnotherThread() const 641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){ 651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return m_originalURL.isSafeToSendToAnotherThread(); 661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} 671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)XSSAuditorDelegate::XSSAuditorDelegate(Document* document) 691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) : m_document(document) 701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) , m_didSendNotifications(false) 711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){ 721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT(isMainThread()); 731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT(m_document); 741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} 751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)PassRefPtr<FormData> XSSAuditorDelegate::generateViolationReport(const XSSInfo& xssInfo) 77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(isMainThread()); 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 80f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) FrameLoader& frameLoader = m_document->frame()->loader(); 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) String httpBody; 82f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) if (frameLoader.documentLoader()) { 83f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) if (FormData* formData = frameLoader.documentLoader()->originalRequest().httpBody()) 84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) httpBody = formData->flattenToString(); 85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 87591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<JSONObject> reportDetails = JSONObject::create(); 881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) reportDetails->setString("request-url", xssInfo.m_originalURL); 89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) reportDetails->setString("request-body", httpBody); 90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 91591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<JSONObject> reportObject = JSONObject::create(); 92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) reportObject->setObject("xss-report", reportDetails.release()); 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return FormData::create(reportObject->toJSONString().utf8().data()); 95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo) 98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(isMainThread()); 100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, xssInfo.buildConsoleError()); 102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 10353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // stopAllLoaders can detach the Frame, so protect it. 10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RefPtr<Frame> protect(m_document->frame()); 105f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) FrameLoader& frameLoader = m_document->frame()->loader(); 106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (xssInfo.m_didBlockEntirePage) 107f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) frameLoader.stopAllLoaders(); 108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_didSendNotifications) { 110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_didSendNotifications = true; 111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 112f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) frameLoader.client()->didDetectXSS(m_document->url(), xssInfo.m_didBlockEntirePage); 113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_reportURL.isEmpty()) 1151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) PingLoader::sendViolationReport(m_document->frame(), m_reportURL, generateViolationReport(xssInfo), PingLoader::XSSAuditorViolationReport); 116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (xssInfo.m_didBlockEntirePage) 119e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) m_document->frame()->navigationScheduler().scheduleLocationChange(m_document, SecurityOrigin::urlWithUniqueSecurityOrigin(), String()); 120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} // namespace WebCore 123