Update To 11.40.268.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 namespace blink {
33
34 DatabaseAuthorizer* DatabaseAuthorizer::create(const String& databaseInfoTableName)
35 {
36     return new DatabaseAuthorizer(databaseInfoTableName);
37 }
38
39 DatabaseAuthorizer::DatabaseAuthorizer(const String& databaseInfoTableName)
40     : m_securityEnabled(false)
41     , m_databaseInfoTableName(databaseInfoTableName)
42 {
43     reset();
44     addWhitelistedFunctions();
45 }
46
47 void DatabaseAuthorizer::reset()
48 {
49     m_lastActionWasInsert = false;
50     m_lastActionChangedDatabase = false;
51     m_permissions = ReadWriteMask;
52 }
53
54 void DatabaseAuthorizer::resetDeletes()
55 {
56     m_hadDeletes = false;
57 }
58
59 void DatabaseAuthorizer::addWhitelistedFunctions()
60 {
61     // SQLite functions used to help implement some operations
62     // ALTER TABLE helpers
63     m_whitelistedFunctions.add("sqlite_rename_table");
64     m_whitelistedFunctions.add("sqlite_rename_trigger");
65     // GLOB helpers
66     m_whitelistedFunctions.add("glob");
67
68     // SQLite core functions
69     m_whitelistedFunctions.add("abs");
70     m_whitelistedFunctions.add("changes");
71     m_whitelistedFunctions.add("coalesce");
72     m_whitelistedFunctions.add("glob");
73     m_whitelistedFunctions.add("ifnull");
74     m_whitelistedFunctions.add("hex");
75     m_whitelistedFunctions.add("last_insert_rowid");
76     m_whitelistedFunctions.add("length");
77     m_whitelistedFunctions.add("like");
78     m_whitelistedFunctions.add("lower");
79     m_whitelistedFunctions.add("ltrim");
80     m_whitelistedFunctions.add("max");
81     m_whitelistedFunctions.add("min");
82     m_whitelistedFunctions.add("nullif");
83     m_whitelistedFunctions.add("quote");
84     m_whitelistedFunctions.add("replace");
85     m_whitelistedFunctions.add("round");
86     m_whitelistedFunctions.add("rtrim");
87     m_whitelistedFunctions.add("soundex");
88     m_whitelistedFunctions.add("sqlite_source_id");
89     m_whitelistedFunctions.add("sqlite_version");
90     m_whitelistedFunctions.add("substr");
91     m_whitelistedFunctions.add("total_changes");
92     m_whitelistedFunctions.add("trim");
93     m_whitelistedFunctions.add("typeof");
94     m_whitelistedFunctions.add("upper");
95     m_whitelistedFunctions.add("zeroblob");
96
97     // SQLite date and time functions
98     m_whitelistedFunctions.add("date");
99     m_whitelistedFunctions.add("time");
100     m_whitelistedFunctions.add("datetime");
101     m_whitelistedFunctions.add("julianday");
102     m_whitelistedFunctions.add("strftime");
103
104     // SQLite aggregate functions
105     // max() and min() are already in the list
106     m_whitelistedFunctions.add("avg");
107     m_whitelistedFunctions.add("count");
108     m_whitelistedFunctions.add("group_concat");
109     m_whitelistedFunctions.add("sum");
110     m_whitelistedFunctions.add("total");
111
112     // SQLite FTS functions
113     m_whitelistedFunctions.add("match");
114     m_whitelistedFunctions.add("snippet");
115     m_whitelistedFunctions.add("offsets");
116     m_whitelistedFunctions.add("optimize");
117
118     // SQLite ICU functions
119     // like(), lower() and upper() are already in the list
120     m_whitelistedFunctions.add("regexp");
121 }
122
123 int DatabaseAuthorizer::createTable(const String& tableName)
124 {
125     if (!allowWrite())
126         return SQLAuthDeny;
127
128     m_lastActionChangedDatabase = true;
129     return denyBasedOnTableName(tableName);
130 }
131
132 int DatabaseAuthorizer::createTempTable(const String& tableName)
133 {
134     // SQLITE_CREATE_TEMP_TABLE results in a UPDATE operation, which is not
135     // allowed in read-only transactions or private browsing, so we might as
136     // well disallow SQLITE_CREATE_TEMP_TABLE in these cases
137     if (!allowWrite())
138         return SQLAuthDeny;
139
140     return denyBasedOnTableName(tableName);
141 }
142
143 int DatabaseAuthorizer::dropTable(const String& tableName)
144 {
145     if (!allowWrite())
146         return SQLAuthDeny;
147
148     return updateDeletesBasedOnTableName(tableName);
149 }
150
151 int DatabaseAuthorizer::dropTempTable(const String& tableName)
152 {
153     // SQLITE_DROP_TEMP_TABLE results in a DELETE operation, which is not
154     // allowed in read-only transactions or private browsing, so we might as
155     // well disallow SQLITE_DROP_TEMP_TABLE in these cases
156     if (!allowWrite())
157         return SQLAuthDeny;
158
159     return updateDeletesBasedOnTableName(tableName);
160 }
161
162 int DatabaseAuthorizer::allowAlterTable(const String&, const String& tableName)
163 {
164     if (!allowWrite())
165         return SQLAuthDeny;
166
167     m_lastActionChangedDatabase = true;
168     return denyBasedOnTableName(tableName);
169 }
170
171 int DatabaseAuthorizer::createIndex(const String&, const String& tableName)
172 {
173     if (!allowWrite())
174         return SQLAuthDeny;
175
176     m_lastActionChangedDatabase = true;
177     return denyBasedOnTableName(tableName);
178 }
179
180 int DatabaseAuthorizer::createTempIndex(const String&, const String& tableName)
181 {
182     // SQLITE_CREATE_TEMP_INDEX should result in a UPDATE or INSERT operation,
183     // which is not allowed in read-only transactions or private browsing,
184     // so we might as well disallow SQLITE_CREATE_TEMP_INDEX in these cases
185     if (!allowWrite())
186         return SQLAuthDeny;
187
188     return denyBasedOnTableName(tableName);
189 }
190
191 int DatabaseAuthorizer::dropIndex(const String&, const String& tableName)
192 {
193     if (!allowWrite())
194         return SQLAuthDeny;
195
196     return updateDeletesBasedOnTableName(tableName);
197 }
198
199 int DatabaseAuthorizer::dropTempIndex(const String&, const String& tableName)
200 {
201     // SQLITE_DROP_TEMP_INDEX should result in a DELETE operation, which is
202     // not allowed in read-only transactions or private browsing, so we might
203     // as well disallow SQLITE_DROP_TEMP_INDEX in these cases
204     if (!allowWrite())
205         return SQLAuthDeny;
206
207     return updateDeletesBasedOnTableName(tableName);
208 }
209
210 int DatabaseAuthorizer::createTrigger(const String&, const String& tableName)
211 {
212     if (!allowWrite())
213         return SQLAuthDeny;
214
215     m_lastActionChangedDatabase = true;
216     return denyBasedOnTableName(tableName);
217 }
218
219 int DatabaseAuthorizer::createTempTrigger(const String&, const String& tableName)
220 {
221     // SQLITE_CREATE_TEMP_TRIGGER results in a INSERT operation, which is not
222     // allowed in read-only transactions or private browsing, so we might as
223     // well disallow SQLITE_CREATE_TEMP_TRIGGER in these cases
224     if (!allowWrite())
225         return SQLAuthDeny;
226
227     return denyBasedOnTableName(tableName);
228 }
229
230 int DatabaseAuthorizer::dropTrigger(const String&, const String& tableName)
231 {
232     if (!allowWrite())
233         return SQLAuthDeny;
234
235     return updateDeletesBasedOnTableName(tableName);
236 }
237
238 int DatabaseAuthorizer::dropTempTrigger(const String&, const String& tableName)
239 {
240     // SQLITE_DROP_TEMP_TRIGGER results in a DELETE operation, which is not
241     // allowed in read-only transactions or private browsing, so we might as
242     // well disallow SQLITE_DROP_TEMP_TRIGGER in these cases
243     if (!allowWrite())
244         return SQLAuthDeny;
245
246     return updateDeletesBasedOnTableName(tableName);
247 }
248
249 int DatabaseAuthorizer::createView(const String&)
250 {
251     return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
252 }
253
254 int DatabaseAuthorizer::createTempView(const String&)
255 {
256     // SQLITE_CREATE_TEMP_VIEW results in a UPDATE operation, which is not
257     // allowed in read-only transactions or private browsing, so we might as
258     // well disallow SQLITE_CREATE_TEMP_VIEW in these cases
259     return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
260 }
261
262 int DatabaseAuthorizer::dropView(const String&)
263 {
264     if (!allowWrite())
265         return SQLAuthDeny;
266
267     m_hadDeletes = true;
268     return SQLAuthAllow;
269 }
270
271 int DatabaseAuthorizer::dropTempView(const String&)
272 {
273     // SQLITE_DROP_TEMP_VIEW results in a DELETE operation, which is not
274     // allowed in read-only transactions or private browsing, so we might as
275     // well disallow SQLITE_DROP_TEMP_VIEW in these cases
276     if (!allowWrite())
277         return SQLAuthDeny;
278
279     m_hadDeletes = true;
280     return SQLAuthAllow;
281 }
282
283 int DatabaseAuthorizer::createVTable(const String& tableName, const String& moduleName)
284 {
285     if (!allowWrite())
286         return SQLAuthDeny;
287
288     // Allow only the FTS3 extension
289     if (!equalIgnoringCase(moduleName, "fts3"))
290         return SQLAuthDeny;
291
292     m_lastActionChangedDatabase = true;
293     return denyBasedOnTableName(tableName);
294 }
295
296 int DatabaseAuthorizer::dropVTable(const String& tableName, const String& moduleName)
297 {
298     if (!allowWrite())
299         return SQLAuthDeny;
300
301     // Allow only the FTS3 extension
302     if (!equalIgnoringCase(moduleName, "fts3"))
303         return SQLAuthDeny;
304
305     return updateDeletesBasedOnTableName(tableName);
306 }
307
308 int DatabaseAuthorizer::allowDelete(const String& tableName)
309 {
310     if (!allowWrite())
311         return SQLAuthDeny;
312
313     return updateDeletesBasedOnTableName(tableName);
314 }
315
316 int DatabaseAuthorizer::allowInsert(const String& tableName)
317 {
318     if (!allowWrite())
319         return SQLAuthDeny;
320
321     m_lastActionChangedDatabase = true;
322     m_lastActionWasInsert = true;
323     return denyBasedOnTableName(tableName);
324 }
325
326 int DatabaseAuthorizer::allowUpdate(const String& tableName, const String&)
327 {
328     if (!allowWrite())
329         return SQLAuthDeny;
330
331     m_lastActionChangedDatabase = true;
332     return denyBasedOnTableName(tableName);
333 }
334
335 int DatabaseAuthorizer::allowTransaction()
336 {
337     return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
338 }
339
340 int DatabaseAuthorizer::allowRead(const String& tableName, const String&)
341 {
342     if (m_permissions & NoAccessMask && m_securityEnabled)
343         return SQLAuthDeny;
344
345     return denyBasedOnTableName(tableName);
346 }
347
348 int DatabaseAuthorizer::allowReindex(const String&)
349 {
350     return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
351 }
352
353 int DatabaseAuthorizer::allowAnalyze(const String& tableName)
354 {
355     return denyBasedOnTableName(tableName);
356 }
357
358 int DatabaseAuthorizer::allowPragma(const String&, const String&)
359 {
360     return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
361 }
362
363 int DatabaseAuthorizer::allowAttach(const String&)
364 {
365     return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
366 }
367
368 int DatabaseAuthorizer::allowDetach(const String&)
369 {
370     return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
371 }
372
373 int DatabaseAuthorizer::allowFunction(const String& functionName)
374 {
375     if (m_securityEnabled && !m_whitelistedFunctions.contains(functionName))
376         return SQLAuthDeny;
377
378     return SQLAuthAllow;
379 }
380
381 void DatabaseAuthorizer::disable()
382 {
383     m_securityEnabled = false;
384 }
385
386 void DatabaseAuthorizer::enable()
387 {
388     m_securityEnabled = true;
389 }
390
391 bool DatabaseAuthorizer::allowWrite()
392 {
393     return !(m_securityEnabled && (m_permissions & ReadOnlyMask || m_permissions & NoAccessMask));
394 }
395
396 void DatabaseAuthorizer::setPermissions(int permissions)
397 {
398     m_permissions = permissions;
399 }
400
401 int DatabaseAuthorizer::denyBasedOnTableName(const String& tableName) const
402 {
403     if (!m_securityEnabled)
404         return SQLAuthAllow;
405
406     // Sadly, normal creates and drops end up affecting sqlite_master in an authorizer callback, so
407     // it will be tough to enforce all of the following policies
408     //if (equalIgnoringCase(tableName, "sqlite_master") || equalIgnoringCase(tableName, "sqlite_temp_master") ||
409     //    equalIgnoringCase(tableName, "sqlite_sequence") || equalIgnoringCase(tableName, Database::databaseInfoTableName()))
410     //        return SQLAuthDeny;
411
412     if (equalIgnoringCase(tableName, m_databaseInfoTableName))
413         return SQLAuthDeny;
414
415     return SQLAuthAllow;
416 }
417
418 int DatabaseAuthorizer::updateDeletesBasedOnTableName(const String& tableName)
419 {
420     int allow = denyBasedOnTableName(tableName);
421     if (allow)
422         m_hadDeletes = true;
423     return allow;
424 }
425
426 } // namespace blink