diff --git a/core/model/ComponentSet.php b/core/model/ComponentSet.php index 01684066d..75a30a771 100755 --- a/core/model/ComponentSet.php +++ b/core/model/ComponentSet.php @@ -152,7 +152,7 @@ class ComponentSet extends DataObjectSet { $extraKeys = $extraValues = ''; if($extraFields) foreach($extraFields as $k => $v) { $extraKeys .= ", \"$k\""; - $extraValues .= ", '" . DB::getConn()->addslashes($v) . "'"; + $extraValues .= ", '" . Convert::raw2sql($v) . "'"; } DB::query("INSERT INTO \"$this->tableName\" (\"$parentField\",\"$childField\" $extraKeys) VALUES ({$this->ownerObj->ID}, {$item->ID} $extraValues)"); diff --git a/core/model/MySQLDatabase.php b/core/model/MySQLDatabase.php index 53b699b30..164ef6f26 100755 --- a/core/model/MySQLDatabase.php +++ b/core/model/MySQLDatabase.php @@ -347,9 +347,9 @@ class MySQLDatabase extends SS_Database { if($field['Default'] || $field['Default'] === "0") { if(is_numeric($field['Default'])) - $fieldSpec .= " default " . addslashes($field['Default']); + $fieldSpec .= " default " . Convert::raw2sql($field['Default']); else - $fieldSpec .= " default '" . addslashes($field['Default']) . "'"; + $fieldSpec .= " default '" . Convert::raw2sql($field['Default']) . "'"; } if($field['Extra']) $fieldSpec .= " $field[Extra]"; @@ -862,8 +862,7 @@ class MySQLDatabase extends SS_Database { } /* - * This will return text which has been escaped in a database-friendly manner - * Using PHP's addslashes method won't work in MSSQL + * This will return text which has been escaped in a database-friendly manner. */ function addslashes($value){ return mysql_real_escape_string($value, $this->dbConn); diff --git a/core/model/Versioned.php b/core/model/Versioned.php index 069263ac3..60fe29ef3 100755 --- a/core/model/Versioned.php +++ b/core/model/Versioned.php @@ -392,7 +392,7 @@ class Versioned extends DataObjectDecorator { // Add any extra, unchanged fields to the version record. $data = DB::query("SELECT * FROM \"$table\" WHERE \"ID\" = $id")->record(); if($data) foreach($data as $k => $v) { - if (!isset($newManipulation['fields'][$k])) $newManipulation['fields'][$k] = "'" . DB::getConn()->addslashes($v) . "'"; + if (!isset($newManipulation['fields'][$k])) $newManipulation['fields'][$k] = "'" . Convert::raw2sql($v) . "'"; } // Set up a new entry in (table)_versions diff --git a/core/model/fieldtypes/Boolean.php b/core/model/fieldtypes/Boolean.php index cb4b155e0..135416157 100644 --- a/core/model/fieldtypes/Boolean.php +++ b/core/model/fieldtypes/Boolean.php @@ -59,7 +59,7 @@ class Boolean extends DBField { */ function prepValueForDB($value) { if(strpos($value, '[')!==false) - return addslashes($value); + return Convert::raw2sql($value); else { if($value && strtolower($value) != 'f') { return "'1'"; diff --git a/core/model/fieldtypes/Decimal.php b/core/model/fieldtypes/Decimal.php index 08a1d33c5..57671b632 100644 --- a/core/model/fieldtypes/Decimal.php +++ b/core/model/fieldtypes/Decimal.php @@ -59,9 +59,9 @@ class Decimal extends DBField { if(strpos($value, '[')===false) return '0'; else - return addslashes($value); + return Convert::raw2sql($value); } else { - return addslashes($value); + return Convert::raw2sql($value); } } diff --git a/core/model/fieldtypes/Int.php b/core/model/fieldtypes/Int.php index 2f14a725e..4f34376d7 100644 --- a/core/model/fieldtypes/Int.php +++ b/core/model/fieldtypes/Int.php @@ -57,9 +57,9 @@ class Int extends DBField { if(strpos($value, '[')===false) return '0'; else - return addslashes($value); + return Convert::raw2sql($value); } else { - return addslashes($value); + return Convert::raw2sql($value); } } diff --git a/docs/en/topics/security.md b/docs/en/topics/security.md index 902980fd7..f162f6e53 100644 --- a/docs/en/topics/security.md +++ b/docs/en/topics/security.md @@ -16,8 +16,10 @@ See [http://shiflett.org/articles/sql-injection](http://shiflett.org/articles/sq ### Automatic escaping -SilverStripe automatically runs [addslashes()](http://php.net/addslashes) in DataObject::write() wherever possible. Data -is escaped when saving back to the database, not when writing to object-properties. +SilverStripe automatically escapes data in `[api:DataObject::write()]` wherever possible, +through database-specific methods (see `[api:Database->addslashes()]`). +For `[api:MySQLDatabase]`, this will be `[mysql_real_escape_string()](http://de3.php.net/mysql_real_escape_string)`. +Data is escaped when saving back to the database, not when writing to object-properties. * DataObject::get_by_id() * DataObject::update() diff --git a/filesystem/Folder.php b/filesystem/Folder.php index 04695586e..185b6a530 100755 --- a/filesystem/Folder.php +++ b/filesystem/Folder.php @@ -77,7 +77,7 @@ class Folder extends File { // First, merge any children that are duplicates $duplicateChildrenNames = DB::query("SELECT \"Name\" FROM \"File\" WHERE \"ParentID\" = $parentID GROUP BY \"Name\" HAVING count(*) > 1")->column(); if($duplicateChildrenNames) foreach($duplicateChildrenNames as $childName) { - $childName = DB::getConn()->addslashes($childName); + $childName = Convert::raw2sql($childName); // Note, we do this in the database rather than object-model; otherwise we get all sorts of problems about deleting files $children = DB::query("SELECT \"ID\" FROM \"File\" WHERE \"Name\" = '$childName' AND \"ParentID\" = $parentID")->column(); if($children) { @@ -184,10 +184,10 @@ class Folder extends File { if(Member::currentUser()) $ownerID = Member::currentUser()->ID; else $ownerID = 0; - $filename = DB::getConn()->addslashes($this->Filename . $name); + $filename = Convert::raw2sql($this->Filename . $name); if($className == 'Folder' ) $filename .= '/'; - $name = DB::getConn()->addslashes($name); + $name = Convert::raw2sql($name); DB::query("INSERT INTO \"File\" (\"ClassName\", \"ParentID\", \"OwnerID\", \"Name\", \"Filename\", \"Created\", \"LastEdited\", \"Title\") diff --git a/search/AdvancedSearchForm.php b/search/AdvancedSearchForm.php index 074f8b34f..e5abe8cc1 100755 --- a/search/AdvancedSearchForm.php +++ b/search/AdvancedSearchForm.php @@ -82,7 +82,7 @@ class AdvancedSearchForm extends SearchForm { foreach($_REQUEST['OnlyShow'] as $section => $checked) { $items = explode(",", $section); foreach($items as $item) { - $page = DataObject::get_one('SiteTree', "\"URLSegment\" = '" . DB::getConn()->addslashes($item) . "'"); + $page = DataObject::get_one('SiteTree', "\"URLSegment\" = '" . Convert::raw2sql($item) . "'"); $pageList[] = $page->ID; if(!$page) user_error("Can't find a page called '$item'", E_USER_WARNING); $page->loadDescendantIDListInto($pageList);