Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / webdatabase / DatabaseAuthorizer.cpp
1 /*
2  * Copyright (C) 2007 Apple 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
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "modules/webdatabase/DatabaseAuthorizer.h"
31
32 #include "wtf/PassRefPtr.h"
33
34 namespace blink {
35
36 PassRefPtrWillBeRawPtr<DatabaseAuthorizer> DatabaseAuthorizer::create(const String& databaseInfoTableName)
37 {
38     return adoptRefWillBeNoop(new DatabaseAuthorizer(databaseInfoTableName));
39 }
40
41 DatabaseAuthorizer::DatabaseAuthorizer(const String& databaseInfoTableName)
42     : m_securityEnabled(false)
43     , m_databaseInfoTableName(databaseInfoTableName)
44 {
45     reset();
46     addWhitelistedFunctions();
47 }
48
49 void DatabaseAuthorizer::reset()
50 {
51     m_lastActionWasInsert = false;
52     m_lastActionChangedDatabase = false;
53     m_permissions = ReadWriteMask;
54 }
55
56 void DatabaseAuthorizer::resetDeletes()
57 {
58     m_hadDeletes = false;
59 }
60
61 void DatabaseAuthorizer::addWhitelistedFunctions()
62 {
63     // SQLite functions used to help implement some operations
64     // ALTER TABLE helpers
65     m_whitelistedFunctions.add("sqlite_rename_table");
66     m_whitelistedFunctions.add("sqlite_rename_trigger");
67     // GLOB helpers
68     m_whitelistedFunctions.add("glob");
69
70     // SQLite core functions
71     m_whitelistedFunctions.add("abs");
72     m_whitelistedFunctions.add("changes");
73     m_whitelistedFunctions.add("coalesce");
74     m_whitelistedFunctions.add("glob");
75     m_whitelistedFunctions.add("ifnull");
76     m_whitelistedFunctions.add("hex");
77     m_whitelistedFunctions.add("last_insert_rowid");
78     m_whitelistedFunctions.add("length");
79     m_whitelistedFunctions.add("like");
80     m_whitelistedFunctions.add("lower");
81     m_whitelistedFunctions.add("ltrim");
82     m_whitelistedFunctions.add("max");
83     m_whitelistedFunctions.add("min");
84     m_whitelistedFunctions.add("nullif");
85     m_whitelistedFunctions.add("quote");
86     m_whitelistedFunctions.add("replace");
87     m_whitelistedFunctions.add("round");
88     m_whitelistedFunctions.add("rtrim");
89     m_whitelistedFunctions.add("soundex");
90     m_whitelistedFunctions.add("sqlite_source_id");
91     m_whitelistedFunctions.add("sqlite_version");
92     m_whitelistedFunctions.add("substr");
93     m_whitelistedFunctions.add("total_changes");
94     m_whitelistedFunctions.add("trim");
95     m_whitelistedFunctions.add("typeof");
96     m_whitelistedFunctions.add("upper");
97     m_whitelistedFunctions.add("zeroblob");
98
99     // SQLite date and time functions
100     m_whitelistedFunctions.add("date");
101     m_whitelistedFunctions.add("time");
102     m_whitelistedFunctions.add("datetime");
103     m_whitelistedFunctions.add("julianday");
104     m_whitelistedFunctions.add("strftime");
105
106     // SQLite aggregate functions
107     // max() and min() are already in the list
108     m_whitelistedFunctions.add("avg");
109     m_whitelistedFunctions.add("count");
110     m_whitelistedFunctions.add("group_concat");
111     m_whitelistedFunctions.add("sum");
112     m_whitelistedFunctions.add("total");
113
114     // SQLite FTS functions
115     m_whitelistedFunctions.add("match");
116     m_whitelistedFunctions.add("snippet");
117     m_whitelistedFunctions.add("offsets");
118     m_whitelistedFunctions.add("optimize");
119
120     // SQLite ICU functions
121     // like(), lower() and upper() are already in the list
122     m_whitelistedFunctions.add("regexp");
123 }
124
125 int DatabaseAuthorizer::createTable(const String& tableName)
126 {
127     if (!allowWrite())
128         return SQLAuthDeny;
129
130     m_lastActionChangedDatabase = true;
131     return denyBasedOnTableName(tableName);
132 }
133
134 int DatabaseAuthorizer::createTempTable(const String& tableName)
135 {
136     // SQLITE_CREATE_TEMP_TABLE results in a UPDATE operation, which is not
137     // allowed in read-only transactions or private browsing, so we might as
138     // well disallow SQLITE_CREATE_TEMP_TABLE in these cases
139     if (!allowWrite())
140         return SQLAuthDeny;
141
142     return denyBasedOnTableName(tableName);
143 }
144
145 int DatabaseAuthorizer::dropTable(const String& tableName)
146 {
147     if (!allowWrite())
148         return SQLAuthDeny;
149
150     return updateDeletesBasedOnTableName(tableName);
151 }
152
153 int DatabaseAuthorizer::dropTempTable(const String& tableName)
154 {
155     // SQLITE_DROP_TEMP_TABLE results in a DELETE operation, which is not
156     // allowed in read-only transactions or private browsing, so we might as
157     // well disallow SQLITE_DROP_TEMP_TABLE in these cases
158     if (!allowWrite())
159         return SQLAuthDeny;
160
161     return updateDeletesBasedOnTableName(tableName);
162 }
163
164 int DatabaseAuthorizer::allowAlterTable(const String&, const String& tableName)
165 {
166     if (!allowWrite())
167         return SQLAuthDeny;
168
169     m_lastActionChangedDatabase = true;
170     return denyBasedOnTableName(tableName);
171 }
172
173 int DatabaseAuthorizer::createIndex(const String&, const String& tableName)
174 {
175     if (!allowWrite())
176         return SQLAuthDeny;
177
178     m_lastActionChangedDatabase = true;
179     return denyBasedOnTableName(tableName);
180 }
181
182 int DatabaseAuthorizer::createTempIndex(const String&, const String& tableName)
183 {
184     // SQLITE_CREATE_TEMP_INDEX should result in a UPDATE or INSERT operation,
185     // which is not allowed in read-only transactions or private browsing,
186     // so we might as well disallow SQLITE_CREATE_TEMP_INDEX in these cases
187     if (!allowWrite())
188         return SQLAuthDeny;
189
190     return denyBasedOnTableName(tableName);
191 }
192
193 int DatabaseAuthorizer::dropIndex(const String&, const String& tableName)
194 {
195     if (!allowWrite())
196         return SQLAuthDeny;
197
198     return updateDeletesBasedOnTableName(tableName);
199 }
200
201 int DatabaseAuthorizer::dropTempIndex(const String&, const String& tableName)
202 {
203     // SQLITE_DROP_TEMP_INDEX should result in a DELETE operation, which is
204     // not allowed in read-only transactions or private browsing, so we might
205     // as well disallow SQLITE_DROP_TEMP_INDEX in these cases
206     if (!allowWrite())
207         return SQLAuthDeny;
208
209     return updateDeletesBasedOnTableName(tableName);
210 }
211
212 int DatabaseAuthorizer::createTrigger(const String&, const String& tableName)
213 {
214     if (!allowWrite())
215         return SQLAuthDeny;
216
217     m_lastActionChangedDatabase = true;
218     return denyBasedOnTableName(tableName);
219 }
220
221 int DatabaseAuthorizer::createTempTrigger(const String&, const String& tableName)
222 {
223     // SQLITE_CREATE_TEMP_TRIGGER results in a INSERT operation, which is not
224     // allowed in read-only transactions or private browsing, so we might as
225     // well disallow SQLITE_CREATE_TEMP_TRIGGER in these cases
226     if (!allowWrite())
227         return SQLAuthDeny;
228
229     return denyBasedOnTableName(tableName);
230 }
231
232 int DatabaseAuthorizer::dropTrigger(const String&, const String& tableName)
233 {
234     if (!allowWrite())
235         return SQLAuthDeny;
236
237     return updateDeletesBasedOnTableName(tableName);
238 }
239
240 int DatabaseAuthorizer::dropTempTrigger(const String&, const String& tableName)
241 {
242     // SQLITE_DROP_TEMP_TRIGGER results in a DELETE operation, which is not
243     // allowed in read-only transactions or private browsing, so we might as
244     // well disallow SQLITE_DROP_TEMP_TRIGGER in these cases
245     if (!allowWrite())
246         return SQLAuthDeny;
247
248     return updateDeletesBasedOnTableName(tableName);
249 }
250
251 int DatabaseAuthorizer::createView(const String&)
252 {
253     return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
254 }
255
256 int DatabaseAuthorizer::createTempView(const String&)
257 {
258     // SQLITE_CREATE_TEMP_VIEW results in a UPDATE operation, which is not
259     // allowed in read-only transactions or private browsing, so we might as
260     // well disallow SQLITE_CREATE_TEMP_VIEW in these cases
261     return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
262 }
263
264 int DatabaseAuthorizer::dropView(const String&)
265 {
266     if (!allowWrite())
267         return SQLAuthDeny;
268
269     m_hadDeletes = true;
270     return SQLAuthAllow;
271 }
272
273 int DatabaseAuthorizer::dropTempView(const String&)
274 {
275     // SQLITE_DROP_TEMP_VIEW results in a DELETE operation, which is not
276     // allowed in read-only transactions or private browsing, so we might as
277     // well disallow SQLITE_DROP_TEMP_VIEW in these cases
278     if (!allowWrite())
279         return SQLAuthDeny;
280
281     m_hadDeletes = true;
282     return SQLAuthAllow;
283 }
284
285 int DatabaseAuthorizer::createVTable(const String& tableName, const String& moduleName)
286 {
287     if (!allowWrite())
288         return SQLAuthDeny;
289
290     // Allow only the FTS3 extension
291     if (!equalIgnoringCase(moduleName, "fts3"))
292         return SQLAuthDeny;
293
294     m_lastActionChangedDatabase = true;
295     return denyBasedOnTableName(tableName);
296 }
297
298 int DatabaseAuthorizer::dropVTable(const String& tableName, const String& moduleName)
299 {
300     if (!allowWrite())
301         return SQLAuthDeny;
302
303     // Allow only the FTS3 extension
304     if (!equalIgnoringCase(moduleName, "fts3"))
305         return SQLAuthDeny;
306
307     return updateDeletesBasedOnTableName(tableName);
308 }
309
310 int DatabaseAuthorizer::allowDelete(const String& tableName)
311 {
312     if (!allowWrite())
313         return SQLAuthDeny;
314
315     return updateDeletesBasedOnTableName(tableName);
316 }
317
318 int DatabaseAuthorizer::allowInsert(const String& tableName)
319 {
320     if (!allowWrite())
321         return SQLAuthDeny;
322
323     m_lastActionChangedDatabase = true;
324     m_lastActionWasInsert = true;
325     return denyBasedOnTableName(tableName);
326 }
327
328 int DatabaseAuthorizer::allowUpdate(const String& tableName, const String&)
329 {
330     if (!allowWrite())
331         return SQLAuthDeny;
332
333     m_lastActionChangedDatabase = true;
334     return denyBasedOnTableName(tableName);
335 }
336
337 int DatabaseAuthorizer::allowTransaction()
338 {
339     return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
340 }
341
342 int DatabaseAuthorizer::allowRead(const String& tableName, const String&)
343 {
344     if (m_permissions & NoAccessMask && m_securityEnabled)
345         return SQLAuthDeny;
346
347     return denyBasedOnTableName(tableName);
348 }
349
350 int DatabaseAuthorizer::allowReindex(const String&)
351 {
352     return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
353 }
354
355 int DatabaseAuthorizer::allowAnalyze(const String& tableName)
356 {
357     return denyBasedOnTableName(tableName);
358 }
359
360 int DatabaseAuthorizer::allowPragma(const String&, const String&)
361 {
362     return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
363 }
364
365 int DatabaseAuthorizer::allowAttach(const String&)
366 {
367     return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
368 }
369
370 int DatabaseAuthorizer::allowDetach(const String&)
371 {
372     return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
373 }
374
375 int DatabaseAuthorizer::allowFunction(const String& functionName)
376 {
377     if (m_securityEnabled && !m_whitelistedFunctions.contains(functionName))
378         return SQLAuthDeny;
379
380     return SQLAuthAllow;
381 }
382
383 void DatabaseAuthorizer::disable()
384 {
385     m_securityEnabled = false;
386 }
387
388 void DatabaseAuthorizer::enable()
389 {
390     m_securityEnabled = true;
391 }
392
393 bool DatabaseAuthorizer::allowWrite()
394 {
395     return !(m_securityEnabled && (m_permissions & ReadOnlyMask || m_permissions & NoAccessMask));
396 }
397
398 void DatabaseAuthorizer::setPermissions(int permissions)
399 {
400     m_permissions = permissions;
401 }
402
403 int DatabaseAuthorizer::denyBasedOnTableName(const String& tableName) const
404 {
405     if (!m_securityEnabled)
406         return SQLAuthAllow;
407
408     // Sadly, normal creates and drops end up affecting sqlite_master in an authorizer callback, so
409     // it will be tough to enforce all of the following policies
410     //if (equalIgnoringCase(tableName, "sqlite_master") || equalIgnoringCase(tableName, "sqlite_temp_master") ||
411     //    equalIgnoringCase(tableName, "sqlite_sequence") || equalIgnoringCase(tableName, Database::databaseInfoTableName()))
412     //        return SQLAuthDeny;
413
414     if (equalIgnoringCase(tableName, m_databaseInfoTableName))
415         return SQLAuthDeny;
416
417     return SQLAuthAllow;
418 }
419
420 int DatabaseAuthorizer::updateDeletesBasedOnTableName(const String& tableName)
421 {
422     int allow = denyBasedOnTableName(tableName);
423     if (allow)
424         m_hadDeletes = true;
425     return allow;
426 }
427
428 } // namespace blink