diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 8c651312f5e9c06bebf6785c62bdba1e2a142aaa..8a567dc0623eabf0584fa9fb59328358591d2d14 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,11 @@
 Drupal 7.xx, xxxx-xx-xx (development version)
 -----------------------
 
+Drupal 7.65, 2019-03-20
+-----------------------
+- Fixed security issues:
+   - SA-CORE-2019-004
+
 Drupal 7.64, 2019-02-06
 -----------------------
 - [regression] Unset the 'host' header in drupal_http_request() during redirect
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index db2ac1f5d123e344c406b304b7ddaa36e9806cfc..1b5c53408f8a356036bdafd6f0eaf527594dc6ff 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -8,7 +8,7 @@
 /**
  * The current system version.
  */
-define('VERSION', '7.64');
+define('VERSION', '7.65');
 
 /**
  * Core API compatibility.
diff --git a/includes/file.inc b/includes/file.inc
index d6f315602ecf1241512450f775e63259e13ce2fd..8943d63a029a117e050906a89a12c5cc2bde1c67 100644
--- a/includes/file.inc
+++ b/includes/file.inc
@@ -997,8 +997,15 @@ function file_build_uri($path) {
  * @return
  *   The destination filepath, or FALSE if the file already exists
  *   and FILE_EXISTS_ERROR is specified.
+ *
+ * @throws RuntimeException
+ *   Thrown if the filename contains invalid UTF-8.
  */
 function file_destination($destination, $replace) {
+  $basename = drupal_basename($destination);
+  if (!drupal_validate_utf8($basename)) {
+    throw new RuntimeException(sprintf("Invalid filename '%s'", $basename));
+  }
   if (file_exists($destination)) {
     switch ($replace) {
       case FILE_EXISTS_REPLACE:
@@ -1006,7 +1013,6 @@ function file_destination($destination, $replace) {
         break;
 
       case FILE_EXISTS_RENAME:
-        $basename = drupal_basename($destination);
         $directory = drupal_dirname($destination);
         $destination = file_create_filename($basename, $directory);
         break;
@@ -1222,11 +1228,20 @@ function file_unmunge_filename($filename) {
  * @return
  *   File path consisting of $directory and a unique filename based off
  *   of $basename.
+ *
+ * @throws RuntimeException
+ *   Thrown if the $basename is not valid UTF-8 or another error occurs
+ *   stripping control characters.
  */
 function file_create_filename($basename, $directory) {
+  $original = $basename;
   // Strip control characters (ASCII value < 32). Though these are allowed in
   // some filesystems, not many applications handle them well.
   $basename = preg_replace('/[\x00-\x1F]/u', '_', $basename);
+  if (preg_last_error() !== PREG_NO_ERROR) {
+    throw new RuntimeException(sprintf("Invalid filename '%s'", $original));
+  }
+
   if (substr(PHP_OS, 0, 3) == 'WIN') {
     // These characters are not allowed in Windows filenames
     $basename = str_replace(array(':', '*', '?', '"', '<', '>', '|'), '_', $basename);
@@ -1567,7 +1582,13 @@ function file_save_upload($form_field_name, $validators = array(), $destination
   if (substr($destination, -1) != '/') {
     $destination .= '/';
   }
-  $file->destination = file_destination($destination . $file->filename, $replace);
+  try {
+    $file->destination = file_destination($destination . $file->filename, $replace);
+  }
+  catch (RuntimeException $e) {
+    drupal_set_message(t('The file %source could not be uploaded because the name is invalid.', array('%source' => $form_field_name)), 'error');
+    return FALSE;
+  }
   // If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
   // there's an existing file so we need to bail.
   if ($file->destination === FALSE) {
diff --git a/modules/simpletest/tests/file.test b/modules/simpletest/tests/file.test
index 55dd1906ee89c8ac377ba02321d5bad57e65e2cc..032f2cbac58c3772a31e291ecf72fed1926f33a2 100644
--- a/modules/simpletest/tests/file.test
+++ b/modules/simpletest/tests/file.test
@@ -957,6 +957,15 @@ class FileDirectoryTest extends FileTestCase {
     $path = file_create_filename($basename, $directory);
     $this->assertEqual($path, $expected, format_string('Creating a new filepath from %original equals %new.', array('%new' => $path, '%original' => $original)), 'File');
 
+    try {
+      $filename = "a\xFFtest\x80€.txt";
+      file_create_filename($filename, $directory);
+      $this->fail('Expected exception not thrown');
+    }
+    catch (RuntimeException $e) {
+      $this->assertEqual("Invalid filename '$filename'", $e->getMessage());
+    }
+
     // @TODO: Finally we copy a file into a directory several times, to ensure a properly iterating filename suffix.
   }
 
@@ -989,6 +998,14 @@ class FileDirectoryTest extends FileTestCase {
     $this->assertNotEqual($path, $destination, 'A new filepath destination is created when filepath destination already exists with FILE_EXISTS_RENAME.', 'File');
     $path = file_destination($destination, FILE_EXISTS_ERROR);
     $this->assertEqual($path, FALSE, 'An error is returned when filepath destination already exists with FILE_EXISTS_ERROR.', 'File');
+
+    try {
+      file_destination("core/misc/a\xFFtest\x80€.txt", FILE_EXISTS_REPLACE);
+      $this->fail('Expected exception not thrown');
+    }
+    catch (RuntimeException $e) {
+      $this->assertEqual("Invalid filename 'a\xFFtest\x80€.txt'", $e->getMessage());
+    }
   }
 
   /**
diff --git a/profiles/wcm_base/CHANGELOG.txt b/profiles/wcm_base/CHANGELOG.txt
index 95a733ad8caa245b7cc0d98b5a6a7625d00301b1..5f210c5f587e3948f0bf6e42adc1a2ba16653761 100644
--- a/profiles/wcm_base/CHANGELOG.txt
+++ b/profiles/wcm_base/CHANGELOG.txt
@@ -1,3 +1,7 @@
+WCM Base 7.x-1.13-rc2, 2019-03-20
+---------------------------------
+- WCM Base: Updated Drupal core to 7.65 per SA-CORE-2019-004.
+
 WCM Base 7.x-1.13-rc1, 2019-03-13
 ---------------------------------
 - WCM Base: