# lib/goog/html/trustedresourceurl.js

1 | // Copyright 2013 The Closure Library Authors. All Rights Reserved.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS-IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | /**
16 | * @fileoverview The TrustedResourceUrl type and its builders.
17 | *
18 | * TODO(xtof): Link to document stating type contract.
19 | */
20 |
21 | goog.provide('goog.html.TrustedResourceUrl');
22 |
23 | goog.require('goog.asserts');
24 | goog.require('goog.i18n.bidi.Dir');
25 | goog.require('goog.i18n.bidi.DirectionalString');
26 | goog.require('goog.string.Const');
27 | goog.require('goog.string.TypedString');
28 |
29 |
30 |
31 | /**
32 | * A URL which is under application control and from which script, CSS, and
33 | * other resources that represent executable code, can be fetched.
34 | *
35 | * Given that the URL can only be constructed from strings under application
36 | * control and is used to load resources, bugs resulting in a malformed URL
37 | * should not have a security impact and are likely to be easily detectable
38 | * during testing. Given the wide number of non-RFC compliant URLs in use,
39 | * stricter validation could prevent some applications from being able to use
40 | * this type.
41 | *
42 | * Instances of this type must be created via the factory method,
43 | * ({@code goog.html.TrustedResourceUrl.fromConstant}), and not by invoking its
44 | * constructor. The constructor intentionally takes no parameters and the type
45 | * is immutable; hence only a default instance corresponding to the empty
46 | * string can be obtained via constructor invocation.
47 | *
48 | * @see goog.html.TrustedResourceUrl#fromConstant
49 | * @constructor
50 | * @final
51 | * @struct
52 | * @implements {goog.i18n.bidi.DirectionalString}
53 | * @implements {goog.string.TypedString}
54 | */
55 | goog.html.TrustedResourceUrl = function() {
56 | /**
57 | * The contained value of this TrustedResourceUrl. The field has a purposely
58 | * ugly name to make (non-compiled) code that attempts to directly access this
59 | * field stand out.
60 | * @private {string}
61 | */
62 | this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ = '';
63 |
64 | /**
65 | * A type marker used to implement additional run-time type checking.
66 | * @see goog.html.TrustedResourceUrl#unwrap
67 | * @const
68 | * @private
69 | */
70 | this.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
71 | goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
72 | };
73 |
74 |
75 | /**
76 | * @override
77 | * @const
78 | */
79 | goog.html.TrustedResourceUrl.prototype.implementsGoogStringTypedString = true;
80 |
81 |
82 | /**
83 | * Returns this TrustedResourceUrl's value as a string.
84 | *
85 | * IMPORTANT: In code where it is security relevant that an object's type is
86 | * indeed {@code TrustedResourceUrl}, use
87 | * {@code goog.html.TrustedResourceUrl.unwrap} instead of this method. If in
88 | * doubt, assume that it's security relevant. In particular, note that
89 | * goog.html functions which return a goog.html type do not guarantee that
90 | * the returned instance is of the right type. For example:
91 | *
92 | * <pre>
93 | * var fakeSafeHtml = new String('fake');
94 | * fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
95 | * var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
96 | * // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
97 | * // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml instanceof
98 | * // goog.html.SafeHtml.
99 | * </pre>
100 | *
101 | * @see goog.html.TrustedResourceUrl#unwrap
102 | * @override
103 | */
104 | goog.html.TrustedResourceUrl.prototype.getTypedStringValue = function() {
105 | return this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;
106 | };
107 |
108 |
109 | /**
110 | * @override
111 | * @const
112 | */
113 | goog.html.TrustedResourceUrl.prototype.implementsGoogI18nBidiDirectionalString =
114 | true;
115 |
116 |
117 | /**
118 | * Returns this URLs directionality, which is always {@code LTR}.
119 | * @override
120 | */
121 | goog.html.TrustedResourceUrl.prototype.getDirection = function() {
122 | return goog.i18n.bidi.Dir.LTR;
123 | };
124 |
125 |
126 | if (goog.DEBUG) {
127 | /**
128 | * Returns a debug string-representation of this value.
129 | *
130 | * To obtain the actual string value wrapped in a TrustedResourceUrl, use
131 | * {@code goog.html.TrustedResourceUrl.unwrap}.
132 | *
133 | * @see goog.html.TrustedResourceUrl#unwrap
134 | * @override
135 | */
136 | goog.html.TrustedResourceUrl.prototype.toString = function() {
137 | return 'TrustedResourceUrl{' +
138 | this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ + '}';
139 | };
140 | }
141 |
142 |
143 | /**
144 | * Performs a runtime check that the provided object is indeed a
145 | * TrustedResourceUrl object, and returns its value.
146 | *
147 | * @param {!goog.html.TrustedResourceUrl} trustedResourceUrl The object to
148 | * extract from.
149 | * @return {string} The trustedResourceUrl object's contained string, unless
150 | * the run-time type check fails. In that case, {@code unwrap} returns an
151 | * innocuous string, or, if assertions are enabled, throws
152 | * {@code goog.asserts.AssertionError}.
153 | */
154 | goog.html.TrustedResourceUrl.unwrap = function(trustedResourceUrl) {
155 | // Perform additional Run-time type-checking to ensure that
156 | // trustedResourceUrl is indeed an instance of the expected type. This
157 | // provides some additional protection against security bugs due to
158 | // application code that disables type checks.
159 | // Specifically, the following checks are performed:
160 | // 1. The object is an instance of the expected type.
161 | // 2. The object is not an instance of a subclass.
162 | // 3. The object carries a type marker for the expected type. "Faking" an
163 | // object requires a reference to the type marker, which has names intended
164 | // to stand out in code reviews.
165 | if (trustedResourceUrl instanceof goog.html.TrustedResourceUrl &&
166 | trustedResourceUrl.constructor === goog.html.TrustedResourceUrl &&
167 | trustedResourceUrl
168 | .TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
169 | goog.html.TrustedResourceUrl
170 | .TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
171 | return trustedResourceUrl
172 | .privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;
173 | } else {
174 | goog.asserts.fail('expected object of type TrustedResourceUrl, got \'' +
175 | trustedResourceUrl + '\'');
176 | return 'type_error:TrustedResourceUrl';
177 |
178 | }
179 | };
180 |
181 |
182 | /**
183 | * Creates a TrustedResourceUrl object from a compile-time constant string.
184 | *
185 | * Compile-time constant strings are inherently program-controlled and hence
186 | * trusted.
187 | *
188 | * @param {!goog.string.Const} url A compile-time-constant string from which to
189 | * create a TrustedResourceUrl.
190 | * @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object
191 | * initialized to {@code url}.
192 | */
193 | goog.html.TrustedResourceUrl.fromConstant = function(url) {
194 | return goog.html.TrustedResourceUrl
195 | .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(
196 | goog.string.Const.unwrap(url));
197 | };
198 |
199 |
200 | /**
201 | * Type marker for the TrustedResourceUrl type, used to implement additional
202 | * run-time type checking.
203 | * @const {!Object}
204 | * @private
205 | */
206 | goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
207 |
208 |
209 | /**
210 | * Package-internal utility method to create TrustedResourceUrl instances.
211 | *
212 | * @param {string} url The string to initialize the TrustedResourceUrl object
213 | * with.
214 | * @return {!goog.html.TrustedResourceUrl} The initialized TrustedResourceUrl
215 | * object.
216 | * @package
217 | */
218 | goog.html.TrustedResourceUrl.
219 | createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse = function(url) {
220 | var trustedResourceUrl = new goog.html.TrustedResourceUrl();
221 | trustedResourceUrl.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ =
222 | url;
223 | return trustedResourceUrl;
224 | };