2 * Copyright (C) 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
30 #include "modules/webdatabase/DatabaseAuthorizer.h"
32 #include "wtf/PassRefPtr.h"
36 PassRefPtrWillBeRawPtr<DatabaseAuthorizer> DatabaseAuthorizer::create(const String& databaseInfoTableName)
38 return adoptRefWillBeNoop(new DatabaseAuthorizer(databaseInfoTableName));
41 DatabaseAuthorizer::DatabaseAuthorizer(const String& databaseInfoTableName)
42 : m_securityEnabled(false)
43 , m_databaseInfoTableName(databaseInfoTableName)
46 addWhitelistedFunctions();
49 void DatabaseAuthorizer::reset()
51 m_lastActionWasInsert = false;
52 m_lastActionChangedDatabase = false;
53 m_permissions = ReadWriteMask;
56 void DatabaseAuthorizer::resetDeletes()
61 void DatabaseAuthorizer::addWhitelistedFunctions()
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");
68 m_whitelistedFunctions.add("glob");
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");
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");
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");
114 // SQLite FTS functions
115 m_whitelistedFunctions.add("match");
116 m_whitelistedFunctions.add("snippet");
117 m_whitelistedFunctions.add("offsets");
118 m_whitelistedFunctions.add("optimize");
120 // SQLite ICU functions
121 // like(), lower() and upper() are already in the list
122 m_whitelistedFunctions.add("regexp");
125 int DatabaseAuthorizer::createTable(const String& tableName)
130 m_lastActionChangedDatabase = true;
131 return denyBasedOnTableName(tableName);
134 int DatabaseAuthorizer::createTempTable(const String& tableName)
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
142 return denyBasedOnTableName(tableName);
145 int DatabaseAuthorizer::dropTable(const String& tableName)
150 return updateDeletesBasedOnTableName(tableName);
153 int DatabaseAuthorizer::dropTempTable(const String& tableName)
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
161 return updateDeletesBasedOnTableName(tableName);
164 int DatabaseAuthorizer::allowAlterTable(const String&, const String& tableName)
169 m_lastActionChangedDatabase = true;
170 return denyBasedOnTableName(tableName);
173 int DatabaseAuthorizer::createIndex(const String&, const String& tableName)
178 m_lastActionChangedDatabase = true;
179 return denyBasedOnTableName(tableName);
182 int DatabaseAuthorizer::createTempIndex(const String&, const String& tableName)
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
190 return denyBasedOnTableName(tableName);
193 int DatabaseAuthorizer::dropIndex(const String&, const String& tableName)
198 return updateDeletesBasedOnTableName(tableName);
201 int DatabaseAuthorizer::dropTempIndex(const String&, const String& tableName)
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
209 return updateDeletesBasedOnTableName(tableName);
212 int DatabaseAuthorizer::createTrigger(const String&, const String& tableName)
217 m_lastActionChangedDatabase = true;
218 return denyBasedOnTableName(tableName);
221 int DatabaseAuthorizer::createTempTrigger(const String&, const String& tableName)
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
229 return denyBasedOnTableName(tableName);
232 int DatabaseAuthorizer::dropTrigger(const String&, const String& tableName)
237 return updateDeletesBasedOnTableName(tableName);
240 int DatabaseAuthorizer::dropTempTrigger(const String&, const String& tableName)
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
248 return updateDeletesBasedOnTableName(tableName);
251 int DatabaseAuthorizer::createView(const String&)
253 return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
256 int DatabaseAuthorizer::createTempView(const String&)
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);
264 int DatabaseAuthorizer::dropView(const String&)
273 int DatabaseAuthorizer::dropTempView(const String&)
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
285 int DatabaseAuthorizer::createVTable(const String& tableName, const String& moduleName)
290 // Allow only the FTS3 extension
291 if (!equalIgnoringCase(moduleName, "fts3"))
294 m_lastActionChangedDatabase = true;
295 return denyBasedOnTableName(tableName);
298 int DatabaseAuthorizer::dropVTable(const String& tableName, const String& moduleName)
303 // Allow only the FTS3 extension
304 if (!equalIgnoringCase(moduleName, "fts3"))
307 return updateDeletesBasedOnTableName(tableName);
310 int DatabaseAuthorizer::allowDelete(const String& tableName)
315 return updateDeletesBasedOnTableName(tableName);
318 int DatabaseAuthorizer::allowInsert(const String& tableName)
323 m_lastActionChangedDatabase = true;
324 m_lastActionWasInsert = true;
325 return denyBasedOnTableName(tableName);
328 int DatabaseAuthorizer::allowUpdate(const String& tableName, const String&)
333 m_lastActionChangedDatabase = true;
334 return denyBasedOnTableName(tableName);
337 int DatabaseAuthorizer::allowTransaction()
339 return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
342 int DatabaseAuthorizer::allowRead(const String& tableName, const String&)
344 if (m_permissions & NoAccessMask && m_securityEnabled)
347 return denyBasedOnTableName(tableName);
350 int DatabaseAuthorizer::allowReindex(const String&)
352 return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
355 int DatabaseAuthorizer::allowAnalyze(const String& tableName)
357 return denyBasedOnTableName(tableName);
360 int DatabaseAuthorizer::allowPragma(const String&, const String&)
362 return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
365 int DatabaseAuthorizer::allowAttach(const String&)
367 return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
370 int DatabaseAuthorizer::allowDetach(const String&)
372 return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
375 int DatabaseAuthorizer::allowFunction(const String& functionName)
377 if (m_securityEnabled && !m_whitelistedFunctions.contains(functionName))
383 void DatabaseAuthorizer::disable()
385 m_securityEnabled = false;
388 void DatabaseAuthorizer::enable()
390 m_securityEnabled = true;
393 bool DatabaseAuthorizer::allowWrite()
395 return !(m_securityEnabled && (m_permissions & ReadOnlyMask || m_permissions & NoAccessMask));
398 void DatabaseAuthorizer::setPermissions(int permissions)
400 m_permissions = permissions;
403 int DatabaseAuthorizer::denyBasedOnTableName(const String& tableName) const
405 if (!m_securityEnabled)
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;
414 if (equalIgnoringCase(tableName, m_databaseInfoTableName))
420 int DatabaseAuthorizer::updateDeletesBasedOnTableName(const String& tableName)
422 int allow = denyBasedOnTableName(tableName);