1d0825bca7fe65beaee391d30da42e937db621564Steve Block/*
2d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2009 Google Inc. All rights reserved.
3d0825bca7fe65beaee391d30da42e937db621564Steve Block *
4d0825bca7fe65beaee391d30da42e937db621564Steve Block * Redistribution and use in source and binary forms, with or without
5d0825bca7fe65beaee391d30da42e937db621564Steve Block * modification, are permitted provided that the following conditions are
6d0825bca7fe65beaee391d30da42e937db621564Steve Block * met:
7d0825bca7fe65beaee391d30da42e937db621564Steve Block *
8d0825bca7fe65beaee391d30da42e937db621564Steve Block *     * Redistributions of source code must retain the above copyright
9d0825bca7fe65beaee391d30da42e937db621564Steve Block * notice, this list of conditions and the following disclaimer.
10d0825bca7fe65beaee391d30da42e937db621564Steve Block *     * Redistributions in binary form must reproduce the above
11d0825bca7fe65beaee391d30da42e937db621564Steve Block * copyright notice, this list of conditions and the following disclaimer
12d0825bca7fe65beaee391d30da42e937db621564Steve Block * in the documentation and/or other materials provided with the
13d0825bca7fe65beaee391d30da42e937db621564Steve Block * distribution.
14d0825bca7fe65beaee391d30da42e937db621564Steve Block *     * Neither the name of Google Inc. nor the names of its
15d0825bca7fe65beaee391d30da42e937db621564Steve Block * contributors may be used to endorse or promote products derived from
16d0825bca7fe65beaee391d30da42e937db621564Steve Block * this software without specific prior written permission.
17d0825bca7fe65beaee391d30da42e937db621564Steve Block *
18d0825bca7fe65beaee391d30da42e937db621564Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19d0825bca7fe65beaee391d30da42e937db621564Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21d0825bca7fe65beaee391d30da42e937db621564Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22d0825bca7fe65beaee391d30da42e937db621564Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23d0825bca7fe65beaee391d30da42e937db621564Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25d0825bca7fe65beaee391d30da42e937db621564Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26d0825bca7fe65beaee391d30da42e937db621564Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27d0825bca7fe65beaee391d30da42e937db621564Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28d0825bca7fe65beaee391d30da42e937db621564Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29d0825bca7fe65beaee391d30da42e937db621564Steve Block */
30d0825bca7fe65beaee391d30da42e937db621564Steve Block
31d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "config.h"
32d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "BindingSecurityBase.h"
33d0825bca7fe65beaee391d30da42e937db621564Steve Block
34d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "DOMWindow.h"
35d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Frame.h"
36d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "SecurityOrigin.h"
37d0825bca7fe65beaee391d30da42e937db621564Steve Block
38d0825bca7fe65beaee391d30da42e937db621564Steve Blocknamespace WebCore {
39d0825bca7fe65beaee391d30da42e937db621564Steve Block
40d0825bca7fe65beaee391d30da42e937db621564Steve BlockDOMWindow* BindingSecurityBase::getDOMWindow(Frame* frame)
41d0825bca7fe65beaee391d30da42e937db621564Steve Block{
42d0825bca7fe65beaee391d30da42e937db621564Steve Block    return frame->domWindow();
43d0825bca7fe65beaee391d30da42e937db621564Steve Block}
44d0825bca7fe65beaee391d30da42e937db621564Steve Block
45d0825bca7fe65beaee391d30da42e937db621564Steve BlockFrame* BindingSecurityBase::getFrame(Node* node)
46d0825bca7fe65beaee391d30da42e937db621564Steve Block{
47d0825bca7fe65beaee391d30da42e937db621564Steve Block    return node->document()->frame();
48d0825bca7fe65beaee391d30da42e937db621564Steve Block}
49d0825bca7fe65beaee391d30da42e937db621564Steve Block
50d0825bca7fe65beaee391d30da42e937db621564Steve Block// Same origin policy implementation:
51d0825bca7fe65beaee391d30da42e937db621564Steve Block//
52d0825bca7fe65beaee391d30da42e937db621564Steve Block// Same origin policy prevents JS code from domain A from accessing JS & DOM
53d0825bca7fe65beaee391d30da42e937db621564Steve Block// objects in a different domain B. There are exceptions and several objects
54d0825bca7fe65beaee391d30da42e937db621564Steve Block// are accessible by cross-domain code. For example, the window.frames object
55d0825bca7fe65beaee391d30da42e937db621564Steve Block// is accessible by code from a different domain, but window.document is not.
56d0825bca7fe65beaee391d30da42e937db621564Steve Block//
57d0825bca7fe65beaee391d30da42e937db621564Steve Block// The JS binding code sets security check callbacks on a function template,
58d0825bca7fe65beaee391d30da42e937db621564Steve Block// and accessing instances of the template calls the callback function.
59d0825bca7fe65beaee391d30da42e937db621564Steve Block// The callback function enforces the same origin policy.
60d0825bca7fe65beaee391d30da42e937db621564Steve Block//
61d0825bca7fe65beaee391d30da42e937db621564Steve Block// Callback functions are expensive. Binding code should use a security token
62d0825bca7fe65beaee391d30da42e937db621564Steve Block// string to do fast access checks for the common case where source and target
63d0825bca7fe65beaee391d30da42e937db621564Steve Block// are in the same domain. A security token is a string object that represents
64d0825bca7fe65beaee391d30da42e937db621564Steve Block// the protocol/url/port of a domain.
65d0825bca7fe65beaee391d30da42e937db621564Steve Block//
66d0825bca7fe65beaee391d30da42e937db621564Steve Block// There are special cases where security token matching is not enough.
67d0825bca7fe65beaee391d30da42e937db621564Steve Block// For example, JS can set its domain to a super domain by calling
68d0825bca7fe65beaee391d30da42e937db621564Steve Block// document.setDomain(...). In these cases, the binding code can reset
69d0825bca7fe65beaee391d30da42e937db621564Steve Block// a context's security token to its global object so that the fast access
70d0825bca7fe65beaee391d30da42e937db621564Steve Block// check will always fail.
71d0825bca7fe65beaee391d30da42e937db621564Steve Block
72d0825bca7fe65beaee391d30da42e937db621564Steve Block// Helper to check if the current execution context can access a target frame.
73d0825bca7fe65beaee391d30da42e937db621564Steve Block// First it checks same domain policy using the lexical context.
74d0825bca7fe65beaee391d30da42e937db621564Steve Block//
75d0825bca7fe65beaee391d30da42e937db621564Steve Block// This is equivalent to KJS::Window::allowsAccessFrom(ExecState*).
76d0825bca7fe65beaee391d30da42e937db621564Steve Blockbool BindingSecurityBase::canAccess(DOMWindow* activeWindow,
77d0825bca7fe65beaee391d30da42e937db621564Steve Block                                    DOMWindow* targetWindow)
78d0825bca7fe65beaee391d30da42e937db621564Steve Block{
79d0825bca7fe65beaee391d30da42e937db621564Steve Block    ASSERT(targetWindow);
80d0825bca7fe65beaee391d30da42e937db621564Steve Block
81d0825bca7fe65beaee391d30da42e937db621564Steve Block    String message;
82d0825bca7fe65beaee391d30da42e937db621564Steve Block
83d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (activeWindow == targetWindow)
84d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
85d0825bca7fe65beaee391d30da42e937db621564Steve Block
86d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!activeWindow)
87d0825bca7fe65beaee391d30da42e937db621564Steve Block        return false;
88d0825bca7fe65beaee391d30da42e937db621564Steve Block
89d0825bca7fe65beaee391d30da42e937db621564Steve Block    const SecurityOrigin* activeSecurityOrigin = activeWindow->securityOrigin();
90d0825bca7fe65beaee391d30da42e937db621564Steve Block    const SecurityOrigin* targetSecurityOrigin = targetWindow->securityOrigin();
91d0825bca7fe65beaee391d30da42e937db621564Steve Block
92d0825bca7fe65beaee391d30da42e937db621564Steve Block    // We have seen crashes were the security origin of the target has not been
93d0825bca7fe65beaee391d30da42e937db621564Steve Block    // initialized. Defend against that.
94d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!targetSecurityOrigin)
95d0825bca7fe65beaee391d30da42e937db621564Steve Block        return false;
96d0825bca7fe65beaee391d30da42e937db621564Steve Block
97d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (activeSecurityOrigin->canAccess(targetSecurityOrigin))
98d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
99d0825bca7fe65beaee391d30da42e937db621564Steve Block
100d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Allow access to a "about:blank" page if the dynamic context is a
101d0825bca7fe65beaee391d30da42e937db621564Steve Block    // detached context of the same frame as the blank page.
102d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (targetSecurityOrigin->isEmpty() && activeWindow->frame() == targetWindow->frame())
103d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
104d0825bca7fe65beaee391d30da42e937db621564Steve Block
105d0825bca7fe65beaee391d30da42e937db621564Steve Block    return false;
106d0825bca7fe65beaee391d30da42e937db621564Steve Block}
107d0825bca7fe65beaee391d30da42e937db621564Steve Block
108d0825bca7fe65beaee391d30da42e937db621564Steve Block} // namespace WebCore
109