Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/base/nsTreeSanitizer.h
Line
Count
Source (jump to first uncovered line)
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#ifndef nsTreeSanitizer_h_
6
#define nsTreeSanitizer_h_
7
8
#include "nsIPrincipal.h"
9
#include "mozilla/dom/Element.h"
10
11
class nsIContent;
12
13
/**
14
 * See the documentation of nsIParserUtils::sanitize for documentation
15
 * about the default behavior and the configuration options of this sanitizer.
16
 */
17
class MOZ_STACK_CLASS nsTreeSanitizer {
18
19
  public:
20
21
    /**
22
     * The constructor.
23
     *
24
     * @param aFlags Flags from nsIParserUtils
25
     */
26
    explicit nsTreeSanitizer(uint32_t aFlags = 0);
27
28
    static void InitializeStatics();
29
    static void ReleaseStatics();
30
31
    /**
32
     * Sanitizes a disconnected DOM fragment freshly obtained from a parser.
33
     * The fragment must have just come from a parser so that it can't have
34
     * mutation event listeners set on it.
35
     */
36
    void Sanitize(mozilla::dom::DocumentFragment* aFragment);
37
38
    /**
39
     * Sanitizes a disconnected (not in a docshell) document freshly obtained
40
     * from a parser. The document must not be embedded in a docshell and must
41
     * not have had a chance to get mutation event listeners attached to it.
42
     * The root element must be <html>.
43
     */
44
    void Sanitize(nsIDocument* aDocument);
45
46
  private:
47
48
    /**
49
     * Whether <style> and style="" are allowed.
50
     */
51
    bool mAllowStyles;
52
53
    /**
54
     * Whether comment nodes are allowed.
55
     */
56
    bool mAllowComments;
57
58
    /**
59
     * Whether HTML <font>, <center>, bgcolor="", etc., are dropped.
60
     */
61
    bool mDropNonCSSPresentation;
62
63
    /**
64
     * Whether to remove forms and form controls (excluding fieldset/legend).
65
     */
66
    bool mDropForms;
67
68
    /**
69
     * Whether only cid: embeds are allowed.
70
     */
71
    bool mCidEmbedsOnly;
72
73
    /**
74
     * Whether to drop <img>, <video>, <audio> and <svg>.
75
     */
76
    bool mDropMedia;
77
78
    /**
79
     * Whether we are sanitizing a full document (as opposed to a fragment).
80
     */
81
    bool mFullDocument;
82
83
    /**
84
     * Whether we should notify to the console for anything that's stripped.
85
     */
86
    bool mLogRemovals;
87
88
    /**
89
     * We have various tables of static atoms for elements and attributes.
90
     */
91
    class AtomsTable : public nsTHashtable<nsPtrHashKey<const nsStaticAtom>>
92
    {
93
    public:
94
        explicit AtomsTable(uint32_t aLength)
95
          : nsTHashtable<nsPtrHashKey<const nsStaticAtom>>(aLength)
96
0
        {}
97
98
        bool Contains(nsAtom* aAtom)
99
0
        {
100
0
            // Because this table only contains static atoms, if aAtom isn't
101
0
            // static we can immediately fail.
102
0
            return aAtom->IsStatic() && GetEntry(aAtom->AsStatic());
103
0
        }
104
    };
105
106
    void SanitizeChildren(nsINode* aRoot);
107
108
    /**
109
     * Queries if an element must be replaced with its children.
110
     * @param aNamespace the namespace of the element the question is about
111
     * @param aLocal the local name of the element the question is about
112
     * @return true if the element must be replaced with its children and
113
     *         false if the element is to be kept
114
     */
115
    bool MustFlatten(int32_t aNamespace, nsAtom* aLocal);
116
117
    /**
118
     * Queries if an element including its children must be removed.
119
     * @param aNamespace the namespace of the element the question is about
120
     * @param aLocal the local name of the element the question is about
121
     * @param aElement the element node itself for inspecting attributes
122
     * @return true if the element and its children must be removed and
123
     *         false if the element is to be kept
124
     */
125
    bool MustPrune(int32_t aNamespace,
126
                     nsAtom* aLocal,
127
                     mozilla::dom::Element* aElement);
128
129
    /**
130
     * Checks if a given local name (for an attribute) is on the given list
131
     * of URL attribute names.
132
     * @param aURLs the list of URL attribute names
133
     * @param aLocalName the name to search on the list
134
     * @return true if aLocalName is on the aURLs list and false otherwise
135
     */
136
    bool IsURL(const nsStaticAtom* const* aURLs, nsAtom* aLocalName);
137
138
    /**
139
     * Struct for what attributes and their values are allowed.
140
     */
141
    struct AllowedAttributes
142
    {
143
      // The whitelist of permitted local names to use.
144
      AtomsTable* mNames = nullptr;
145
      // The local names of URL-valued attributes for URL checking.
146
      const nsStaticAtom* const* mURLs = nullptr;
147
      // Whether XLink attributes are allowed.
148
      bool mXLink = false;
149
      // Whether the style attribute is allowed.
150
      bool mStyle = false;
151
      // Whether to leave the value of the src attribute unsanitized.
152
      bool mDangerousSrc = false;
153
    };
154
155
    /**
156
     * Removes dangerous attributes from the element. If the style attribute
157
     * is allowed, its value is sanitized. The values of URL attributes are
158
     * sanitized, except src isn't sanitized when it is allowed to remain
159
     * potentially dangerous.
160
     *
161
     * @param aElement the element whose attributes should be sanitized
162
     * @param aAllowed options for sanitizing attributes
163
     */
164
    void SanitizeAttributes(mozilla::dom::Element* aElement,
165
                            AllowedAttributes aAllowed);
166
167
    /**
168
     * Remove the named URL attribute from the element if the URL fails a
169
     * security check.
170
     *
171
     * @param aElement the element whose attribute to possibly modify
172
     * @param aNamespace the namespace of the URL attribute
173
     * @param aLocalName the local name of the URL attribute
174
     * @return true if the attribute was removed and false otherwise
175
     */
176
    bool SanitizeURL(mozilla::dom::Element* aElement,
177
                     int32_t aNamespace,
178
                     nsAtom* aLocalName);
179
180
    /**
181
     * Checks a style rule for the presence of the 'binding' CSS property and
182
     * removes that property from the rule.
183
     *
184
     * @param aDeclaration The style declaration to check
185
     * @return true if the rule was modified and false otherwise
186
     */
187
    bool SanitizeStyleDeclaration(mozilla::DeclarationBlock* aDeclaration);
188
189
    /**
190
     * Parses a style sheet and reserializes it with the 'binding' property
191
     * removed if it was present.
192
     *
193
     * @param aOrigin the original style sheet source
194
     * @param aSanitized the reserialization without 'binding'; only valid if
195
     *                   this method return true
196
     * @param aDocument the document the style sheet belongs to
197
     * @param aBaseURI the base URI to use
198
     * @return true if the 'binding' property was encountered and false
199
     *              otherwise
200
     */
201
    bool SanitizeStyleSheet(const nsAString& aOriginal,
202
                              nsAString& aSanitized,
203
                              nsIDocument* aDocument,
204
                              nsIURI* aBaseURI);
205
206
    /**
207
     * Removes all attributes from an element node.
208
     */
209
    void RemoveAllAttributes(mozilla::dom::Element* aElement);
210
211
    /**
212
     * Log a Console Service message to indicate we removed something.
213
     * If you pass an element and/or attribute, their information will
214
     * be appended to the message.
215
     *
216
     * @param aMessage   the basic message to log.
217
     * @param aDocument  the base document we're modifying
218
     *                   (used for the error message)
219
     * @param aElement   optional, the element being removed or modified.
220
     * @param aAttribute optional, the attribute being removed or modified.
221
     */
222
    void LogMessage(const char* aMessage, nsIDocument* aDoc,
223
                    Element* aElement = nullptr, nsAtom* aAttr = nullptr);
224
225
    /**
226
     * The whitelist of HTML elements.
227
     */
228
    static AtomsTable* sElementsHTML;
229
230
    /**
231
     * The whitelist of non-presentational HTML attributes.
232
     */
233
    static AtomsTable* sAttributesHTML;
234
235
    /**
236
     * The whitelist of presentational HTML attributes.
237
     */
238
    static AtomsTable* sPresAttributesHTML;
239
240
    /**
241
     * The whitelist of SVG elements.
242
     */
243
    static AtomsTable* sElementsSVG;
244
245
    /**
246
     * The whitelist of SVG attributes.
247
     */
248
    static AtomsTable* sAttributesSVG;
249
250
    /**
251
     * The whitelist of SVG elements.
252
     */
253
    static AtomsTable* sElementsMathML;
254
255
    /**
256
     * The whitelist of MathML attributes.
257
     */
258
    static AtomsTable* sAttributesMathML;
259
260
    /**
261
     * Reusable null principal for URL checks.
262
     */
263
    static nsIPrincipal* sNullPrincipal;
264
};
265
266
#endif // nsTreeSanitizer_h_