• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
BindingSecurity()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>
canAccessWindow(State<Binding> * state,DOMWindow * targetWindow)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>
canAccessFrame(State<Binding> * state,Frame * target,bool reportError)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>
checkNodeSecurity(State<Binding> * state,Node * node)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>
allowPopUp(State<Binding> * state)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>
allowSettingFrameSrcToJavascriptUrl(State<Binding> * state,HTMLFrameElementBase * frame,String value)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>
allowSettingSrcToJavascriptURL(State<Binding> * state,Element * element,String name,String value)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>
shouldAllowNavigation(State<Binding> * state,Frame * frame)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