Home | History | Annotate | Download | only in generic
      1 /*
      2  * Copyright (C) 2009 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #ifndef BindingSecurity_h
     32 #define BindingSecurity_h
     33 
     34 #include "BindingSecurityBase.h"
     35 #include "Element.h"
     36 #include "Frame.h"
     37 #include "GenericBinding.h"
     38 #include "HTMLFrameElementBase.h"
     39 #include "HTMLNames.h"
     40 #include "HTMLParserIdioms.h"
     41 #include "Settings.h"
     42 
     43 namespace WebCore {
     44 
     45 class DOMWindow;
     46 class Node;
     47 
     48 // Security functions shared by various language bindings.
     49 template <class Binding>
     50 class BindingSecurity : public BindingSecurityBase {
     51 public:
     52     // Check if the active execution context can access the target frame.
     53     static bool canAccessFrame(State<Binding>*, Frame*, bool reportError);
     54 
     55     // Check if it is safe to access the given node from the
     56     // current security context.
     57     static bool checkNodeSecurity(State<Binding>*, Node* target);
     58 
     59     static bool allowPopUp(State<Binding>*);
     60     static bool allowSettingFrameSrcToJavascriptUrl(State<Binding>*, HTMLFrameElementBase*, String value);
     61     static bool allowSettingSrcToJavascriptURL(State<Binding>*, Element*, String name, String value);
     62 
     63     static bool shouldAllowNavigation(State<Binding>*, Frame*);
     64 
     65 private:
     66     explicit BindingSecurity() {}
     67     ~BindingSecurity();
     68 
     69     // Check if the current DOMWindow's security context can access the target
     70     // DOMWindow.  This function does not report errors, so most callers should
     71     // use canAccessFrame instead.
     72     static bool canAccessWindow(State<Binding>*, DOMWindow* target);
     73 };
     74 
     75 // Implementations of templated methods must be in this file.
     76 
     77 template <class Binding>
     78 bool BindingSecurity<Binding>::canAccessWindow(State<Binding>* state,
     79                                                DOMWindow* targetWindow)
     80 {
     81     DOMWindow* activeWindow = state->activeWindow();
     82     return canAccess(activeWindow, targetWindow);
     83 }
     84 
     85 template <class Binding>
     86 bool BindingSecurity<Binding>::canAccessFrame(State<Binding>* state,
     87                                               Frame* target,
     88                                               bool reportError)
     89 {
     90     // The subject is detached from a frame, deny accesses.
     91     if (!target)
     92         return false;
     93 
     94     if (!canAccessWindow(state, getDOMWindow(target))) {
     95         if (reportError)
     96             state->immediatelyReportUnsafeAccessTo(target);
     97         return false;
     98     }
     99     return true;
    100 }
    101 
    102 template <class Binding>
    103 bool BindingSecurity<Binding>::checkNodeSecurity(State<Binding>* state, Node* node)
    104 {
    105     if (!node)
    106         return false;
    107 
    108     Frame* target = getFrame(node);
    109 
    110     if (!target)
    111         return false;
    112 
    113     return canAccessFrame(state, target, true);
    114 }
    115 
    116 template <class Binding>
    117 bool BindingSecurity<Binding>::allowPopUp(State<Binding>* state)
    118 {
    119     if (state->processingUserGesture())
    120         return true;
    121 
    122     Frame* frame = state->firstFrame();
    123     ASSERT(frame);
    124     Settings* settings = frame->settings();
    125     return settings && settings->javaScriptCanOpenWindowsAutomatically();
    126 }
    127 
    128 template <class Binding>
    129 bool BindingSecurity<Binding>::allowSettingFrameSrcToJavascriptUrl(State<Binding>* state, HTMLFrameElementBase* frame, String value)
    130 {
    131     if (protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value))) {
    132         Node* contentDoc = frame->contentDocument();
    133         if (contentDoc && !checkNodeSecurity(state, contentDoc))
    134             return false;
    135     }
    136     return true;
    137 }
    138 
    139 template <class Binding>
    140 bool BindingSecurity<Binding>::allowSettingSrcToJavascriptURL(State<Binding>* state, Element* element, String name, String value)
    141 {
    142     if ((element->hasTagName(HTMLNames::iframeTag) || element->hasTagName(HTMLNames::frameTag)) && equalIgnoringCase(name, "src"))
    143         return allowSettingFrameSrcToJavascriptUrl(state, static_cast<HTMLFrameElementBase*>(element), value);
    144     return true;
    145 }
    146 
    147 template <class Binding>
    148 bool BindingSecurity<Binding>::shouldAllowNavigation(State<Binding>* state, Frame* frame)
    149 {
    150     Frame* activeFrame = state->activeFrame();
    151     return activeFrame && activeFrame->loader()->shouldAllowNavigation(frame);
    152 }
    153 
    154 }
    155 
    156 #endif // BindingSecurity_h
    157