Adding a list of whitelisted sqlite functions that users are
authordumi@chromium.org <dumi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Jan 2010 03:29:39 +0000 (03:29 +0000)
committerdumi@chromium.org <dumi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Jan 2010 03:29:39 +0000 (03:29 +0000)
allowed to use.

Reviewed by Adam Barth.

https://bugs.webkit.org/show_bug.cgi?id=33549

* platform/sql/SQLiteDatabase.cpp:
(WebCore::SQLiteDatabase::authorizerFunction):
* storage/DatabaseAuthorizer.cpp:
(WebCore::DatabaseAuthorizer::DatabaseAuthorizer):
(WebCore::DatabaseAuthorizer::addWhitelistedFunctions):
(WebCore::DatabaseAuthorizer::allowFunction):
* storage/DatabaseAuthorizer.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@53177 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/platform/sql/SQLiteDatabase.cpp
WebCore/storage/DatabaseAuthorizer.cpp
WebCore/storage/DatabaseAuthorizer.h

index 8a2c4365df632afe24d709c5dc68f0580ea78a25..9235c358adcf8ea6d16f1c112e36350d1b22c3f7 100644 (file)
@@ -1,3 +1,20 @@
+2010-01-12  Dumitru Daniliuc  <dumi@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        Adding a list of whitelisted sqlite functions that users are
+        allowed to use.
+
+        https://bugs.webkit.org/show_bug.cgi?id=33549
+
+        * platform/sql/SQLiteDatabase.cpp:
+        (WebCore::SQLiteDatabase::authorizerFunction):
+        * storage/DatabaseAuthorizer.cpp:
+        (WebCore::DatabaseAuthorizer::DatabaseAuthorizer):
+        (WebCore::DatabaseAuthorizer::addWhitelistedFunctions):
+        (WebCore::DatabaseAuthorizer::allowFunction):
+        * storage/DatabaseAuthorizer.h:
+
 2010-01-12  Fumitoshi Ukai  <ukai@chromium.org>
 
         Reviewed by Simon Hausmann.
index 9a4e32a36e605df3539181c97995886d80d20fdc..d170db58e7d553e490cc6d74ecbf569909d2ce3d 100644 (file)
@@ -320,7 +320,7 @@ int SQLiteDatabase::authorizerFunction(void* userData, int actionCode, const cha
         case SQLITE_DROP_VTABLE:
             return auth->dropVTable(parameter1, parameter2);
         case SQLITE_FUNCTION:
-            return auth->allowFunction(parameter1);
+            return auth->allowFunction(parameter2);
 #endif
         default:
             ASSERT_NOT_REACHED();
index 93f91067ffc49d0ca7121c2a2df9fbf3068b9591..d0654804ecbb907fcd8c5ef601c31eebce3e3464 100644 (file)
@@ -38,6 +38,7 @@ DatabaseAuthorizer::DatabaseAuthorizer()
     : m_securityEnabled(false)
 {
     reset();
+    addWhitelistedFunctions();
 }
 
 void DatabaseAuthorizer::reset()
@@ -47,6 +48,69 @@ void DatabaseAuthorizer::reset()
     m_readOnly = false;
 }
 
+void DatabaseAuthorizer::addWhitelistedFunctions()
+{
+    // SQLite functions used to help implement some operations
+    // ALTER TABLE helpers
+    m_whitelistedFunctions.add("sqlite_rename_table");
+    m_whitelistedFunctions.add("sqlite_rename_trigger");
+    // GLOB helpers
+    m_whitelistedFunctions.add("glob");
+
+    // SQLite core functions
+    m_whitelistedFunctions.add("abs");
+    m_whitelistedFunctions.add("changes");
+    m_whitelistedFunctions.add("coalesce");
+    m_whitelistedFunctions.add("glob");
+    m_whitelistedFunctions.add("ifnull");
+    m_whitelistedFunctions.add("hex");
+    m_whitelistedFunctions.add("last_insert_rowid");
+    m_whitelistedFunctions.add("length");
+    m_whitelistedFunctions.add("like");
+    m_whitelistedFunctions.add("lower");
+    m_whitelistedFunctions.add("ltrim");
+    m_whitelistedFunctions.add("max");
+    m_whitelistedFunctions.add("min");
+    m_whitelistedFunctions.add("nullif");
+    m_whitelistedFunctions.add("quote");
+    m_whitelistedFunctions.add("replace");
+    m_whitelistedFunctions.add("round");
+    m_whitelistedFunctions.add("rtrim");
+    m_whitelistedFunctions.add("soundex");
+    m_whitelistedFunctions.add("sqlite_source_id");
+    m_whitelistedFunctions.add("sqlite_version");
+    m_whitelistedFunctions.add("substr");
+    m_whitelistedFunctions.add("total_changes");
+    m_whitelistedFunctions.add("trim");
+    m_whitelistedFunctions.add("typeof");
+    m_whitelistedFunctions.add("upper");
+    m_whitelistedFunctions.add("zeroblob");
+
+    // SQLite date and time functions
+    m_whitelistedFunctions.add("date");
+    m_whitelistedFunctions.add("time");
+    m_whitelistedFunctions.add("datetime");
+    m_whitelistedFunctions.add("julianday");
+    m_whitelistedFunctions.add("strftime");
+
+    // SQLite aggregate functions
+    // max() and min() are already in the list
+    m_whitelistedFunctions.add("avg");
+    m_whitelistedFunctions.add("count");
+    m_whitelistedFunctions.add("group_concat");
+    m_whitelistedFunctions.add("sum");
+    m_whitelistedFunctions.add("total");
+
+    // SQLite FTS functions
+    m_whitelistedFunctions.add("snippet");
+    m_whitelistedFunctions.add("offsets");
+    m_whitelistedFunctions.add("optimize");
+
+    // SQLite ICU functions
+    // like(), lower() and upper() are already in the list
+    m_whitelistedFunctions.add("regexp");
+}
+
 int DatabaseAuthorizer::createTable(const String& tableName)
 {
     if (m_readOnly && m_securityEnabled)
@@ -278,12 +342,12 @@ int DatabaseAuthorizer::allowDetach(const String&)
     return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
 }
 
-int DatabaseAuthorizer::allowFunction(const String&)
+int DatabaseAuthorizer::allowFunction(const String& functionName)
 {
-    // FIXME: Are there any of these we need to prevent?  One might guess current_date, current_time, current_timestamp because
-    // they would violate the "sandbox environment" part of 4.11.3, but scripts can generate the local client side information via
-    // javascript directly, anyways.  Are there any other built-ins we need to be worried about?
-    return SQLAuthAllow;
+  if (m_securityEnabled && !m_whitelistedFunctions.contains(functionName.lower()))
+    return SQLAuthDeny;
+
+  return SQLAuthAllow;
 }
 
 void DatabaseAuthorizer::disable()
index 248b659d81763b89d68c44adeab9ea6e982091fe..2171561b30b4d10dff1e3ee3635c26450f4f6e43 100644 (file)
@@ -28,6 +28,8 @@
 #ifndef DatabaseAuthorizer_h
 #define DatabaseAuthorizer_h
 
+#include "StringHash.h"
+#include <wtf/HashSet.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/Threading.h>
 
@@ -94,12 +96,15 @@ public:
 
 private:
     DatabaseAuthorizer();
+    void addWhitelistedFunctions();
     int denyBasedOnTableName(const String&);
 
     bool m_securityEnabled : 1;
     bool m_lastActionWasInsert : 1;
     bool m_lastActionChangedDatabase : 1;
     bool m_readOnly : 1;
+
+    HashSet<String> m_whitelistedFunctions;
 };
 
 } // namespace WebCore