# HG changeset patch # User Sebastien Jodogne # Date 1680084225 -7200 # Node ID 3a410992c6264b56ae8306bdbe3d57a397c64c73 # Parent e9f3bddd30cc0d425726806e20558fd99fdf53af# Parent 345dac17a3492e247da5b72145b982211f7f9125 integration mainline->db-protobuf diff -r e9f3bddd30cc -r 3a410992c626 NEWS --- 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 diff -r e9f3bddd30cc -r 3a410992c626 OrthancFramework/Sources/DicomFormat/DicomMap.h --- 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 #include -#if ORTHANC_BUILD_UNIT_TESTS == 1 -# include -#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; diff -r e9f3bddd30cc -r 3a410992c626 OrthancServer/Resources/Configuration.json --- 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 diff -r e9f3bddd30cc -r 3a410992c626 OrthancServer/Sources/OrthancInitialization.cpp --- 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) diff -r e9f3bddd30cc -r 3a410992c626 OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp --- 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; diff -r e9f3bddd30cc -r 3a410992c626 OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp --- 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; } diff -r e9f3bddd30cc -r 3a410992c626 OrthancServer/Sources/ServerContext.cpp --- 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), diff -r e9f3bddd30cc -r 3a410992c626 OrthancServer/Sources/ServerContext.h --- 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_; bool isHttpServerSecure_; bool isExecuteLuaEnabled_; + bool isRestApiWriteToFileSystemEnabled_; bool overwriteInstances_; std::unique_ptr storageCommitmentReports_; @@ -487,6 +488,16 @@ return isExecuteLuaEnabled_; } + void SetRestApiWriteToFileSystemEnabled(bool enabled) + { + isRestApiWriteToFileSystemEnabled_ = enabled; + } + + bool IsRestApiWriteToFileSystemEnabled() const + { + return isRestApiWriteToFileSystemEnabled_; + } + void SetOverwriteInstances(bool overwrite) { overwriteInstances_ = overwrite; diff -r e9f3bddd30cc -r 3a410992c626 OrthancServer/Sources/main.cpp --- 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);