Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/js/xpconnect/wrappers/AccessCheck.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef __AccessCheck_h__
8
#define __AccessCheck_h__
9
10
#include "js/Id.h"
11
#include "js/Wrapper.h"
12
#include "nsString.h"
13
14
class nsIPrincipal;
15
16
namespace xpc {
17
18
class AccessCheck {
19
  public:
20
    static bool subsumes(JSObject* a, JSObject* b);
21
    static bool wrapperSubsumes(JSObject* wrapper);
22
    static bool subsumesConsideringDomain(JS::Compartment* a, JS::Compartment* b);
23
    static bool subsumesConsideringDomainIgnoringFPD(JS::Compartment* a,
24
                                                     JS::Compartment* b);
25
    static bool isChrome(JS::Compartment* compartment);
26
    static bool isChrome(JSObject* obj);
27
    static bool isCrossOriginAccessPermitted(JSContext* cx, JS::HandleObject obj,
28
                                             JS::HandleId id, js::Wrapper::Action act);
29
    static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper,
30
                                          JS::HandleValue value);
31
    static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper,
32
                                          const JS::CallArgs& args);
33
    // Called to report the correct sort of exception when our policy denies and
34
    // should throw.  The accessType argument should be one of "access",
35
    // "define", "delete", depending on which operation is being denied.
36
    static void reportCrossOriginDenial(JSContext* cx, JS::HandleId id,
37
                                        const nsACString& accessType);
38
};
39
40
enum CrossOriginObjectType {
41
    CrossOriginWindow,
42
    CrossOriginLocation,
43
    CrossOriginOpaque
44
};
45
CrossOriginObjectType IdentifyCrossOriginObject(JSObject* obj);
46
47
struct Policy {
48
0
    static bool checkCall(JSContext* cx, JS::HandleObject wrapper, const JS::CallArgs& args) {
49
0
        MOZ_CRASH("As a rule, filtering wrappers are non-callable");
50
0
    }
51
};
52
53
// This policy allows no interaction with the underlying callable. Everything throws.
54
struct Opaque : public Policy {
55
0
    static bool check(JSContext* cx, JSObject* wrapper, jsid id, js::Wrapper::Action act) {
56
0
        return false;
57
0
    }
58
    static bool deny(JSContext* cx, js::Wrapper::Action act, JS::HandleId id,
59
0
                     bool mayThrow) {
60
0
        return false;
61
0
    }
62
0
    static bool allowNativeCall(JSContext* cx, JS::IsAcceptableThis test, JS::NativeImpl impl) {
63
0
        return false;
64
0
    }
65
};
66
67
// Like the above, but allows CALL.
68
struct OpaqueWithCall : public Policy {
69
0
    static bool check(JSContext* cx, JSObject* wrapper, jsid id, js::Wrapper::Action act) {
70
0
        return act == js::Wrapper::CALL;
71
0
    }
72
    static bool deny(JSContext* cx, js::Wrapper::Action act, JS::HandleId id,
73
0
                     bool mayThrow) {
74
0
        return false;
75
0
    }
76
0
    static bool allowNativeCall(JSContext* cx, JS::IsAcceptableThis test, JS::NativeImpl impl) {
77
0
        return false;
78
0
    }
79
0
    static bool checkCall(JSContext* cx, JS::HandleObject wrapper, const JS::CallArgs& args) {
80
0
        return AccessCheck::checkPassToPrivilegedCode(cx, wrapper, args);
81
0
    }
82
};
83
84
// This policy only permits access to properties that are safe to be used
85
// across origins.
86
struct CrossOriginAccessiblePropertiesOnly : public Policy {
87
0
    static bool check(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, js::Wrapper::Action act) {
88
0
        return AccessCheck::isCrossOriginAccessPermitted(cx, wrapper, id, act);
89
0
    }
90
    static bool deny(JSContext* cx, js::Wrapper::Action act, JS::HandleId id,
91
0
                     bool mayThrow) {
92
0
        // Silently fail for enumerate-like operations.
93
0
        if (act == js::Wrapper::ENUMERATE) {
94
0
            return true;
95
0
        }
96
0
        if (mayThrow) {
97
0
            AccessCheck::reportCrossOriginDenial(cx, id,
98
0
                                                 NS_LITERAL_CSTRING("access"));
99
0
        }
100
0
        return false;
101
0
    }
102
0
    static bool allowNativeCall(JSContext* cx, JS::IsAcceptableThis test, JS::NativeImpl impl) {
103
0
        return false;
104
0
    }
105
};
106
107
// This class used to support permitting access to properties if they
108
// appeared in an access list on the object, but now it acts like an
109
// Opaque wrapper, with the exception that it fails silently for GET,
110
// ENUMERATE, and GET_PROPERTY_DESCRIPTOR. This is done for backwards
111
// compatibility. See bug 1397513.
112
struct OpaqueWithSilentFailing : public Policy {
113
0
    static bool check(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, js::Wrapper::Action act) {
114
0
        return false;
115
0
    }
116
117
    static bool deny(JSContext* cx, js::Wrapper::Action act, JS::HandleId id,
118
                     bool mayThrow);
119
0
    static bool allowNativeCall(JSContext* cx, JS::IsAcceptableThis test, JS::NativeImpl impl) {
120
0
        return false;
121
0
    }
122
};
123
124
} // namespace xpc
125
126
#endif /* __AccessCheck_h__ */