changeset 5202:3a410992c626 db-protobuf

integration mainline->db-protobuf
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 29 Mar 2023 12:03:45 +0200
parents e9f3bddd30cc (current diff) 345dac17a349 (diff)
children 6b7f3ec30ac4
files
diffstat 9 files changed, 71 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Mon Mar 27 21:18:37 2023 +0200
+++ b/NEWS	Wed Mar 29 12:03:45 2023 +0200
@@ -5,31 +5,39 @@
 -----------
 
 * Enforce the existence of the patient/study/instance while creating its archive
+* Security: New configuration option "RestApiWriteToFileSystemEnabled"
+  to allow "/instances/../export" that is now disabled by default.
 
 Bug Fixes
 ---------
 
 * Fix issue 214: VOILUTSequence is not returned in Wado-RS
-
-
-version 1.11.3 (2023-02-03)
+* Fix /tools/reset crashing when ExtraMainDicomTags were defined
+
+
+Version 1.11.3 (2023-02-03)
 ===========================
 
 General
 -------
 
-* C-Store SCU now gives priority to the preferred TransferSyntax proposed by the receiving SCP
-  instead of Orthanc own AcceptedTransferSyntaxes.
-* Made the default SQLite DB more robust wrt future updates like adding new columns in DB.
+* C-Store SCU now gives priority to the preferred TransferSyntax
+  proposed by the receiving SCP instead of Orthanc own
+  AcceptedTransferSyntaxes.
+* Made the default SQLite DB more robust wrt future updates like
+  adding new columns in DB.
 * Made the HTTP Client errors more verbose by including the url in the logs.
-* Optimization: now using multiple threads to transcode files for asynchronous download of studies archive.
+* Optimization: now using multiple threads to transcode files for
+  asynchronous download of studies archive.
 * New configuration "KeepAliveTimeout" with a default value of 1 second.
 * ResourceModification jobs (/modify + /anonymize) can now use multiple threads to speed up processing
   - New configuration "JobsEngineThreadsCount.ResourceModification" to configure the number of threads.
-* For systems using glibc > 2.8 (most of Linux systems except LSB binaries):
-  Introduced a new Housekeeper thread in Orthanc (different from the Housekeeper sample plugin).  This thread
-  regularly try to give back memory that Orthanc no longer uses to the system.  This reduces the overall memory
-  consumption.  More information in  OrthancServer/Resources/ImplementationNotes/memory_consumption.txt.
+* For systems using glibc > 2.8 (most of Linux systems except LSB
+  binaries): Introduced a new thread for to trim memory in Orthanc (different
+  from the Housekeeper sample plugin). This thread regularly try to
+  give back memory that Orthanc no longer uses to the system. This
+  reduces the overall memory consumption. More information in
+  OrthancServer/Resources/ImplementationNotes/memory_consumption.txt.
 
 REST API
 --------
@@ -69,7 +77,7 @@
 * Fix issue #212 (Anonymization process transcodes data and loses resource link).
 
 
-version 1.11.2 (2022-08-30)
+Version 1.11.2 (2022-08-30)
 ===========================
 
 General
--- a/OrthancFramework/Sources/DicomFormat/DicomMap.h	Mon Mar 27 21:18:37 2023 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomMap.h	Wed Mar 29 12:03:45 2023 +0200
@@ -31,10 +31,6 @@
 #include <map>
 #include <json/value.h>
 
-#if ORTHANC_BUILD_UNIT_TESTS == 1
-#  include <gtest/gtest_prod.h>
-#endif
-
 namespace Orthanc
 {
   class ORTHANC_PUBLIC DicomMap : public boost::noncopyable
@@ -48,10 +44,6 @@
     friend class FromDcmtkBridge;
     friend class ParsedDicomFile;
 
-#if ORTHANC_BUILD_UNIT_TESTS == 1
-    friend class DicomMapMainTagsTests;
-#endif
-
     Content content_;
 
     // Warning: This takes the ownership of "value"
@@ -59,12 +51,11 @@
                           uint16_t element, 
                           DicomValue* value);
 
-    // used for unit tests only
-    static void ResetDefaultMainDicomTags();
-
   public:
     ~DicomMap();
 
+    static void ResetDefaultMainDicomTags();
+
     size_t GetSize() const;
     
     DicomMap* Clone() const;
--- a/OrthancServer/Resources/Configuration.json	Mon Mar 27 21:18:37 2023 +0200
+++ b/OrthancServer/Resources/Configuration.json	Wed Mar 29 12:03:45 2023 +0200
@@ -50,7 +50,7 @@
   // By default, the patients are recycled ("Recycle" mode).
   // In "Reject" mode, the sender will receive a 0xA700 DIMSE status code
   // if the instance was sent through C-Store, a 507 HTTP status code
-  // if using the Rest API and a 0xA700 Failure reason when using
+  // if using the REST API and a 0xA700 Failure reason when using
   // DicomWeb Stow-RS 
   // Allowed values: "Recycle", "Reject"
   // (new in Orthanc 1.11.2)
@@ -766,6 +766,11 @@
   // with Orthanc 1.5.8, this URI is disabled by default for security.
   "ExecuteLuaEnabled" : false,
 
+  // Whether the REST API can write to the filesystem (e.g. in 
+  // /instances/../export route). Starting with Orthanc 1.12.0, 
+  // this URI is disabled by default for security.
+  "RestApiWriteToFileSystemEnabled": false,
+
   // Set the timeout while serving HTTP requests by the embedded Web
   // server, in seconds. This corresponds to option
   // "request_timeout_ms" of Mongoose/Civetweb. It will set the socket
--- a/OrthancServer/Sources/OrthancInitialization.cpp	Mon Mar 27 21:18:37 2023 +0200
+++ b/OrthancServer/Sources/OrthancInitialization.cpp	Wed Mar 29 12:03:45 2023 +0200
@@ -204,6 +204,8 @@
   {
     static const char* const EXTRA_MAIN_DICOM_TAGS = "ExtraMainDicomTags";
     
+    DicomMap::ResetDefaultMainDicomTags();
+
     if (configuration.type() != Json::objectValue ||
         !configuration.isMember(EXTRA_MAIN_DICOM_TAGS) ||
         configuration[EXTRA_MAIN_DICOM_TAGS].type() != Json::objectValue)
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Mon Mar 27 21:18:37 2023 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Wed Mar 29 12:03:45 2023 +0200
@@ -428,7 +428,12 @@
       call.GetDocumentation()
         .SetTag("Instances")
         .SetSummary("Write DICOM onto filesystem")
-        .SetDescription("Write the DICOM file onto the filesystem where Orthanc is running")
+        .SetDescription("Write the DICOM file onto the filesystem where Orthanc is running.  This is insecure for "
+                        "Orthanc servers that are remotely accessible since one could overwrite any system file.  "
+                        "Since Orthanc 1.12.0, this route is disabled by default and can be enabled thanks to "
+                        "the `RestApiWriteToFileSystemEnabled` configuration.")
+        .AddRequestType(MimeType_PlainText, "The Lua script to be executed")
+
         .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest")
         .AddRequestType(MimeType_PlainText, "Target path on the filesystem");
       return;
@@ -436,6 +441,14 @@
 
     ServerContext& context = OrthancRestApi::GetContext(call);
 
+    if (!context.IsRestApiWriteToFileSystemEnabled())
+    {
+      LOG(ERROR) << "The URI /instances/../export is disallowed for security, "
+                 << "check your configuration option `RestApiWriteToFileSystemEnabled`";
+      call.GetOutput().SignalError(HttpStatus_403_Forbidden);
+      return;
+    }
+
     std::string publicId = call.GetUriComponent("id", "");
 
     std::string dicom;
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Mon Mar 27 21:18:37 2023 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Wed Mar 29 12:03:45 2023 +0200
@@ -259,7 +259,8 @@
         .SetTag("System")
         .SetSummary("Execute Lua script")
         .SetDescription("Execute the provided Lua script by the Orthanc server. This is very insecure for "
-                        "Orthanc servers that are remotely accessible, cf. configuration option `ExecuteLuaEnabled`")
+                        "Orthanc servers that are remotely accessible.  Since Orthanc 1.5.8, this route "
+                        "is disabled by default and can be enabled thanks to the `ExecuteLuaEnabled` configuration.")
         .AddRequestType(MimeType_PlainText, "The Lua script to be executed")
         .AddAnswerType(MimeType_PlainText, "Output of the Lua script");
       return;
@@ -270,7 +271,7 @@
     if (!context.IsExecuteLuaEnabled())
     {
       LOG(ERROR) << "The URI /tools/execute-script is disallowed for security, "
-                 << "check your configuration file";
+                 << "check your configuration option `ExecuteLuaEnabled`";
       call.GetOutput().SignalError(HttpStatus_403_Forbidden);
       return;
     }
--- a/OrthancServer/Sources/ServerContext.cpp	Mon Mar 27 21:18:37 2023 +0200
+++ b/OrthancServer/Sources/ServerContext.cpp	Wed Mar 29 12:03:45 2023 +0200
@@ -327,6 +327,7 @@
     metricsRegistry_(new MetricsRegistry),
     isHttpServerSecure_(true),
     isExecuteLuaEnabled_(false),
+    isRestApiWriteToFileSystemEnabled_(false),
     overwriteInstances_(false),
     dcmtkTranscoder_(new DcmtkTranscoder),
     isIngestTranscoding_(false),
--- a/OrthancServer/Sources/ServerContext.h	Mon Mar 27 21:18:37 2023 +0200
+++ b/OrthancServer/Sources/ServerContext.h	Wed Mar 29 12:03:45 2023 +0200
@@ -248,6 +248,7 @@
     std::unique_ptr<MetricsRegistry>  metricsRegistry_;
     bool isHttpServerSecure_;
     bool isExecuteLuaEnabled_;
+    bool isRestApiWriteToFileSystemEnabled_;
     bool overwriteInstances_;
 
     std::unique_ptr<StorageCommitmentReports>  storageCommitmentReports_;
@@ -487,6 +488,16 @@
       return isExecuteLuaEnabled_;
     }
 
+    void SetRestApiWriteToFileSystemEnabled(bool enabled)
+    {
+      isRestApiWriteToFileSystemEnabled_ = enabled;
+    }
+
+    bool IsRestApiWriteToFileSystemEnabled() const
+    {
+      return isRestApiWriteToFileSystemEnabled_;
+    }
+
     void SetOverwriteInstances(bool overwrite)
     {
       overwriteInstances_ = overwrite;
--- a/OrthancServer/Sources/main.cpp	Mon Mar 27 21:18:37 2023 +0200
+++ b/OrthancServer/Sources/main.cpp	Wed Mar 29 12:03:45 2023 +0200
@@ -1172,6 +1172,18 @@
         LOG(WARNING) << "Remote LUA script execution is disabled";
       }
 
+      if (lock.GetConfiguration().GetBooleanParameter("RestApiWriteToFileSystemEnabled", false))
+      {
+        context.SetRestApiWriteToFileSystemEnabled(true);
+        LOG(WARNING) << "====> Your REST API can write to the FileSystem.  Review your configuration option \"RestApiWriteToFileSystemEnabled\". "
+                     << "Your setup is POSSIBLY INSECURE <====";
+      }
+      else
+      {
+        context.SetRestApiWriteToFileSystemEnabled(false);
+        LOG(WARNING) << "REST API can not write to the file system.";
+      }
+
       if (lock.GetConfiguration().GetBooleanParameter("WebDavEnabled", true))
       {
         const bool allowDelete = lock.GetConfiguration().GetBooleanParameter("WebDavDeleteAllowed", false);