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"
34 DatabaseAuthorizer* DatabaseAuthorizer::create(const String& databaseInfoTableName)
36 return new DatabaseAuthorizer(databaseInfoTableName);
39 DatabaseAuthorizer::DatabaseAuthorizer(const String& databaseInfoTableName)
40 : m_securityEnabled(false)
41 , m_databaseInfoTableName(databaseInfoTableName)
44 addWhitelistedFunctions();
47 void DatabaseAuthorizer::reset()
49 m_lastActionWasInsert = false;
50 m_lastActionChangedDatabase = false;
51 m_permissions = ReadWriteMask;
54 void DatabaseAuthorizer::resetDeletes()
59 void DatabaseAuthorizer::addWhitelistedFunctions()
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");
66 m_whitelistedFunctions.add("glob");
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");
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");
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");
112 // SQLite FTS functions
113 m_whitelistedFunctions.add("match");
114 m_whitelistedFunctions.add("snippet");
115 m_whitelistedFunctions.add("offsets");
116 m_whitelistedFunctions.add("optimize");
118 // SQLite ICU functions
119 // like(), lower() and upper() are already in the list
120 m_whitelistedFunctions.add("regexp");
123 int DatabaseAuthorizer::createTable(const String& tableName)
128 m_lastActionChangedDatabase = true;
129 return denyBasedOnTableName(tableName);
132 int DatabaseAuthorizer::createTempTable(const String& tableName)
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
140 return denyBasedOnTableName(tableName);
143 int DatabaseAuthorizer::dropTable(const String& tableName)
148 return updateDeletesBasedOnTableName(tableName);
151 int DatabaseAuthorizer::dropTempTable(const String& tableName)
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
159 return updateDeletesBasedOnTableName(tableName);
162 int DatabaseAuthorizer::allowAlterTable(const String&, const String& tableName)
167 m_lastActionChangedDatabase = true;
168 return denyBasedOnTableName(tableName);
171 int DatabaseAuthorizer::createIndex(const String&, const String& tableName)
176 m_lastActionChangedDatabase = true;
177 return denyBasedOnTableName(tableName);
180 int DatabaseAuthorizer::createTempIndex(const String&, const String& tableName)
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
188 return denyBasedOnTableName(tableName);
191 int DatabaseAuthorizer::dropIndex(const String&, const String& tableName)
196 return updateDeletesBasedOnTableName(tableName);
199 int DatabaseAuthorizer::dropTempIndex(const String&, const String& tableName)
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
207 return updateDeletesBasedOnTableName(tableName);
210 int DatabaseAuthorizer::createTrigger(const String&, const String& tableName)
215 m_lastActionChangedDatabase = true;
216 return denyBasedOnTableName(tableName);
219 int DatabaseAuthorizer::createTempTrigger(const String&, const String& tableName)
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
227 return denyBasedOnTableName(tableName);
230 int DatabaseAuthorizer::dropTrigger(const String&, const String& tableName)
235 return updateDeletesBasedOnTableName(tableName);
238 int DatabaseAuthorizer::dropTempTrigger(const String&, const String& tableName)
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
246 return updateDeletesBasedOnTableName(tableName);
249 int DatabaseAuthorizer::createView(const String&)
251 return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
254 int DatabaseAuthorizer::createTempView(const String&)
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);
262 int DatabaseAuthorizer::dropView(const String&)
271 int DatabaseAuthorizer::dropTempView(const String&)
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
283 int DatabaseAuthorizer::createVTable(const String& tableName, const String& moduleName)
288 // Allow only the FTS3 extension
289 if (!equalIgnoringCase(moduleName, "fts3"))
292 m_lastActionChangedDatabase = true;
293 return denyBasedOnTableName(tableName);
296 int DatabaseAuthorizer::dropVTable(const String& tableName, const String& moduleName)
301 // Allow only the FTS3 extension
302 if (!equalIgnoringCase(moduleName, "fts3"))
305 return updateDeletesBasedOnTableName(tableName);
308 int DatabaseAuthorizer::allowDelete(const String& tableName)
313 return updateDeletesBasedOnTableName(tableName);
316 int DatabaseAuthorizer::allowInsert(const String& tableName)
321 m_lastActionChangedDatabase = true;
322 m_lastActionWasInsert = true;
323 return denyBasedOnTableName(tableName);
326 int DatabaseAuthorizer::allowUpdate(const String& tableName, const String&)
331 m_lastActionChangedDatabase = true;
332 return denyBasedOnTableName(tableName);
335 int DatabaseAuthorizer::allowTransaction()
337 return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
340 int DatabaseAuthorizer::allowRead(const String& tableName, const String&)
342 if (m_permissions & NoAccessMask && m_securityEnabled)
345 return denyBasedOnTableName(tableName);
348 int DatabaseAuthorizer::allowReindex(const String&)
350 return (!allowWrite() ? SQLAuthDeny : SQLAuthAllow);
353 int DatabaseAuthorizer::allowAnalyze(const String& tableName)
355 return denyBasedOnTableName(tableName);
358 int DatabaseAuthorizer::allowPragma(const String&, const String&)
360 return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
363 int DatabaseAuthorizer::allowAttach(const String&)
365 return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
368 int DatabaseAuthorizer::allowDetach(const String&)
370 return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
373 int DatabaseAuthorizer::allowFunction(const String& functionName)
375 if (m_securityEnabled && !m_whitelistedFunctions.contains(functionName))
381 void DatabaseAuthorizer::disable()
383 m_securityEnabled = false;
386 void DatabaseAuthorizer::enable()
388 m_securityEnabled = true;
391 bool DatabaseAuthorizer::allowWrite()
393 return !(m_securityEnabled && (m_permissions & ReadOnlyMask || m_permissions & NoAccessMask));
396 void DatabaseAuthorizer::setPermissions(int permissions)
398 m_permissions = permissions;
401 int DatabaseAuthorizer::denyBasedOnTableName(const String& tableName) const
403 if (!m_securityEnabled)
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;
412 if (equalIgnoringCase(tableName, m_databaseInfoTableName))
418 int DatabaseAuthorizer::updateDeletesBasedOnTableName(const String& tableName)
420 int allow = denyBasedOnTableName(tableName);