# HG changeset patch # User Sebastien Jodogne # Date 1702930001 -3600 # Node ID 514fd39f87a828487fe4fa4aea7bc8f7bb29e5c3 # Parent 47334eeaaa1a8afd63f28463b0ae5259ff0ddaac improved handling of X-Content-Type-Options diff -r 47334eeaaa1a -r 514fd39f87a8 OrthancFramework/Sources/HttpServer/HttpOutput.cpp --- a/OrthancFramework/Sources/HttpServer/HttpOutput.cpp Mon Dec 18 10:44:11 2023 +0100 +++ b/OrthancFramework/Sources/HttpServer/HttpOutput.cpp Mon Dec 18 21:06:41 2023 +0100 @@ -44,6 +44,8 @@ # endif #endif +static const std::string X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options"; + namespace Orthanc { @@ -58,7 +60,8 @@ contentLength_(0), contentPosition_(0), keepAlive_(isKeepAlive), - keepAliveTimeout_(keepAliveTimeout) + keepAliveTimeout_(keepAliveTimeout), + hasXContentTypeOptions_(false) { } @@ -142,6 +145,11 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls); } + if (header == X_CONTENT_TYPE_OPTIONS) + { + hasXContentTypeOptions_ = true; + } + headers_.push_back(header + ": " + value + "\r\n"); } @@ -178,9 +186,6 @@ if (state_ == State_WritingHeader) { - // always include this header to prevent MIME Confusion attacks: https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-content-type-options - AddHeader("X-Content-Type-Options", "nosniff"); - // Send the HTTP header before writing the body stream_.OnHttpStatusReceived(status_); @@ -220,6 +225,13 @@ s += *it; } + if (!hasXContentTypeOptions_) + { + // Always include this header to prevent MIME Confusion attacks: + // https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-content-type-options + s += X_CONTENT_TYPE_OPTIONS + ": nosniff\r\n"; + } + if (status_ != HttpStatus_200_Ok) { hasContentLength_ = false; @@ -369,8 +381,8 @@ if (messageSize > 0) { - // we assume that the body always contains a json description of the error - stateMachine_.SetContentType("application/json"); + // Assume that the body always contains a textual description of the error + stateMachine_.SetContentType("text/plain"); } stateMachine_.SendBody(message, messageSize); diff -r 47334eeaaa1a -r 514fd39f87a8 OrthancFramework/Sources/HttpServer/HttpOutput.h --- a/OrthancFramework/Sources/HttpServer/HttpOutput.h Mon Dec 18 10:44:11 2023 +0100 +++ b/OrthancFramework/Sources/HttpServer/HttpOutput.h Mon Dec 18 21:06:41 2023 +0100 @@ -64,6 +64,7 @@ bool keepAlive_; unsigned int keepAliveTimeout_; std::list headers_; + bool hasXContentTypeOptions_; std::string multipartBoundary_; std::string multipartContentType_; diff -r 47334eeaaa1a -r 514fd39f87a8 OrthancServer/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py --- a/OrthancServer/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py Mon Dec 18 10:44:11 2023 +0100 +++ b/OrthancServer/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py Mon Dec 18 21:06:41 2023 +0100 @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Orthanc - A Lightweight, RESTful DICOM Store # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics diff -r 47334eeaaa1a -r 514fd39f87a8 OrthancServer/Resources/Samples/ImportDicomFiles/OrthancImport.py --- a/OrthancServer/Resources/Samples/ImportDicomFiles/OrthancImport.py Mon Dec 18 10:44:11 2023 +0100 +++ b/OrthancServer/Resources/Samples/ImportDicomFiles/OrthancImport.py Mon Dec 18 21:06:41 2023 +0100 @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Orthanc - A Lightweight, RESTful DICOM Store # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics