Skip to content

Commit

Permalink
Merge pull request #41572 from ballerina-platform/add-content-type-op…
Browse files Browse the repository at this point in the history
…tions-header

[1.2.x] Add content type options header
  • Loading branch information
TharmiganK authored Oct 31, 2023
2 parents e6f4e71 + 36ca003 commit 3227189
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ public class HttpConstants {
public static final String SESSION = "Session";
public static final String HTTP_ONLY = "HttpOnly";
public static final String SECURE = "Secure";
public static final String X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
public static final String NO_SNIFF = "nosniff";

public static final String ALLOW_ORIGIN = "allowOrigins";
public static final String ALLOW_CREDENTIALS = "allowCredentials";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
import static org.ballerinalang.net.http.HttpConstants.MUTUAL_SSL_CERTIFICATE;
import static org.ballerinalang.net.http.HttpConstants.MUTUAL_SSL_HANDSHAKE_RECORD;
import static org.ballerinalang.net.http.HttpConstants.NEVER;
import static org.ballerinalang.net.http.HttpConstants.NO_SNIFF;
import static org.ballerinalang.net.http.HttpConstants.PACKAGE;
import static org.ballerinalang.net.http.HttpConstants.PASSWORD;
import static org.ballerinalang.net.http.HttpConstants.PKCS_STORE_TYPE;
Expand All @@ -177,6 +178,7 @@
import static org.ballerinalang.net.http.HttpConstants.SSL_CONFIG_SSL_VERIFY_CLIENT;
import static org.ballerinalang.net.http.HttpConstants.SSL_PROTOCOL_VERSION;
import static org.ballerinalang.net.http.HttpConstants.TRANSPORT_MESSAGE;
import static org.ballerinalang.net.http.HttpConstants.X_CONTENT_TYPE_OPTIONS;
import static org.ballerinalang.net.http.nativeimpl.pipelining.PipeliningHandler.sendPipelinedResponse;
import static org.ballerinalang.stdlib.io.utils.IOConstants.DETAIL_RECORD_TYPE_NAME;
import static org.ballerinalang.stdlib.io.utils.IOConstants.IO_PACKAGE_ID;
Expand Down Expand Up @@ -441,6 +443,10 @@ public static HttpCarbonMessage createErrorMessage(String payload, int statusCod
if (payload != null) {
payload = lowerCaseTheFirstLetter(payload);
response.addHttpContent(new DefaultLastHttpContent(Unpooled.wrappedBuffer(payload.getBytes())));
// This header is added to block content sniffing in the old browsers where
// the response payload may contain executable scripts
// Related issue: ballerina-platform/ballerina-standard-library/issues/5088
response.setHeader(X_CONTENT_TYPE_OPTIONS, NO_SNIFF);
} else {
response.addHttpContent(new DefaultLastHttpContent());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import static org.ballerinalang.mime.util.MimeConstants.APPLICATION_FORM;
import static org.ballerinalang.mime.util.MimeConstants.APPLICATION_JSON;
import static org.ballerinalang.mime.util.MimeConstants.TEXT_PLAIN;
import static org.ballerinalang.net.http.HttpConstants.NO_SNIFF;
import static org.ballerinalang.net.http.HttpConstants.X_CONTENT_TYPE_OPTIONS;

/**
* Service/Resource dispatchers test class.
Expand Down Expand Up @@ -104,18 +106,24 @@ public void testServiceDispatchingWithWorker() {
public void testServiceAvailabilityCheck() {
HTTPTestRequest requestMsg = MessageUtils.generateHTTPMessage("/foo/message", "GET");
HttpCarbonMessage responseMsg = Services.invoke(TEST_ENDPOINT_1_PORT, requestMsg);
Assert.assertNotNull(responseMsg);
String responseMsgPayload = StringUtils
.getStringFromInputStream(new HttpMessageDataStreamer(responseMsg).getInputStream());
Assert.assertEquals(responseMsgPayload, "no matching service found for path : /foo/message");
String contentTypeOptions = responseMsg.getHeader(X_CONTENT_TYPE_OPTIONS);
Assert.assertEquals(contentTypeOptions, NO_SNIFF);
}

@Test(description = "Test for resource availability check")
public void testResourceAvailabilityCheck() {
HTTPTestRequest requestMsg = MessageUtils.generateHTTPMessage("/echo/bar", "GET");
HttpCarbonMessage responseMsg = Services.invoke(TEST_ENDPOINT_1_PORT, requestMsg);
Assert.assertNotNull(responseMsg);
String responseMsgPayload = StringUtils
.getStringFromInputStream(new HttpMessageDataStreamer(responseMsg).getInputStream());
Assert.assertEquals(responseMsgPayload, "no matching resource found for path : /echo/bar , method : GET");
String contentTypeOptions = responseMsg.getHeader(X_CONTENT_TYPE_OPTIONS);
Assert.assertEquals(contentTypeOptions, NO_SNIFF);
}

@Test
Expand Down

0 comments on commit 3227189

Please sign in to comment.