CVE-2021-32054 (published 2021-05-14T21:15Z)

Firely/Incendi Spark before 1.5.5-r4 lacks Content-Disposition headers in certain situations, which may cause crafted files to be delivered to clients such that they are rendered directly in a victim's web browser.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:P/A:N)
CVSS v3 base score: 6.1, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)

Weakness information:
cwe_id: CWE-706
cwe_name: Use of Incorrectly-Resolved Name or Reference
description: The product uses a name or reference to access a resource, but the name/reference resolves to a resource that is outside of the intended control sphere.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/FirelyTeam/spark
commit_details: repo_url: https://github.com/FirelyTeam/spark
author: Kenneth Myhra
author_date: 2021-05-07 14:40:15+02:00
msg: refactor: Add constants for HTTP Header field names

Added constants for HTTP Header field names

Set Content-Disposition header to attachment for Binary requests
repository: repo_url: https://github.com/FirelyTeam/spark
repo_name: FirelyTeam/spark
description: Firely and Incendi's open source FHIR server
repo_language: C#
owner: FirelyTeam
file_changes: filename: HttpHeaderName.cs
change_type: ModificationType.ADD
diff: @@ -0,0 +1,15 @@
+﻿namespace Spark.Engine.Core
+{
+    internal static class HttpHeaderName
+    {
+        public const string ACCEPT = "Accept";
+        public const string CONTENT_DISPOSITION = "Content-Disposition";
+        public const string CONTENT_LOCATION = "Content-Location";
+        public const string CONTENT_TYPE = "Content-Type";
+        public const string ETAG = "ETag";
+        public const string LOCATION = "Location";
+        public const string LAST_MODIFIED = "Last-Modified";
+
+        public const string X_CONTENT_TYPE = "X-Content-Type";
+    }
+}

programming_language: C#
filename: HttpRequestFhirExtensions.cs
change_type: ModificationType.MODIFY
diff: @@ -158,17 +158,17 @@ namespace Spark.Engine.Extensions
         {
             if (fhirResponse.Key != null)
             {
-                response.Headers.Add("ETag", ETag.Create(fhirResponse.Key.VersionId)?.ToString());
+                response.Headers.Add(HttpHeaderName.ETAG, ETag.Create(fhirResponse.Key.VersionId)?.ToString());
 
                 Uri location = fhirResponse.Key.ToUri();
-                response.Headers.Add("Location", location.OriginalString);
+                response.Headers.Add(HttpHeaderName.LOCATION, location.OriginalString);
 
                 if (response.Body != null)
                 {
-                    response.Headers.Add("Content-Location", location.OriginalString);
+                    response.Headers.Add(HttpHeaderName.CONTENT_LOCATION, location.OriginalString);
                     if (fhirResponse.Resource != null && fhirResponse.Resource.Meta != null)
                     {
-                        response.Headers.Add("Last-Modified", fhirResponse.Resource.Meta.LastUpdated.Value.ToString("R"));
+                        response.Headers.Add(HttpHeaderName.LAST_MODIFIED, fhirResponse.Resource.Meta.LastUpdated.Value.ToString("R"));
                     }
                 }
             }
@@ -192,6 +192,10 @@ namespace Spark.Engine.Extensions
                     {
                         response.Content.Headers.LastModified = fhirResponse.Resource.Meta.LastUpdated;
                     }
+                    if(fhirResponse.Resource is Binary)
+                    {
+                        response.Content.Headers.Add(HttpHeaderName.CONTENT_DISPOSITION, "attachment");
+                    }
                 }
             }
         }

programming_language: C#
filename: BinaryOutputFormatter.cs
change_type: ModificationType.MODIFY
diff: @@ -37,6 +37,7 @@ namespace Spark.Engine.Formatters
                 }
                 if (binary == null) return;
 
+                context.HttpContext.Response.Headers.Add(HttpHeaderName.CONTENT_DISPOSITION, "attachment");
                 context.HttpContext.Response.ContentType = binary.ContentType;
 
                 Stream stream = new MemoryStream(binary.Data);

programming_language: C#
filename: FormatTypeHandler.cs
change_type: ModificationType.MODIFY
diff: @@ -25,11 +25,11 @@ namespace Spark.Engine.Handlers.NetCore
                 ResourceFormat accepted = ContentType.GetResourceFormatFromFormatParam(format);
                 if (accepted != ResourceFormat.Unknown)
                 {
-                    if (context.Request.Headers.ContainsKey("Accept")) context.Request.Headers.Remove("Accept");
+                    if (context.Request.Headers.ContainsKey(HttpHeaderName.ACCEPT)) context.Request.Headers.Remove(HttpHeaderName.ACCEPT);
                     if (accepted == ResourceFormat.Json)
-                        context.Request.Headers.Add("Accept", new StringValues(ContentType.JSON_CONTENT_HEADER));
+                        context.Request.Headers.Add(HttpHeaderName.ACCEPT, new StringValues(ContentType.JSON_CONTENT_HEADER));
                     else
-                        context.Request.Headers.Add("Accept", new StringValues(ContentType.XML_CONTENT_HEADER));
+                        context.Request.Headers.Add(HttpHeaderName.ACCEPT, new StringValues(ContentType.XML_CONTENT_HEADER));
                 }
             }
 
@@ -38,7 +38,7 @@ namespace Spark.Engine.Handlers.NetCore
                 if (!HttpRequestExtensions.IsContentTypeHeaderFhirMediaType(context.Request.ContentType))
                 {
                     string contentType = context.Request.ContentType;
-                    context.Request.Headers.Add("X-Content-Type", contentType);
+                    context.Request.Headers.Add(HttpHeaderName.X_CONTENT_TYPE, contentType);
                     context.Request.ContentType = FhirMediaType.OctetStreamMimeType;
                 }
             }

programming_language: C#