Skip to content

Ensure SystemTextJsonHelper always HTML encodes output. #12808

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 5, 2019

Conversation

pranavkm
Copy link
Contributor

@pranavkm pranavkm commented Aug 1, 2019

Ensure JsonSerializer always HTML encodes output.

  • Update JsonOptions.JsonSerializerOptions to use encoder scheme that does not encode non-ASCII
    characters by default. This makes the encoding comparable to Json.NET's defaults
  • In SystemTextJsonHelper, ensure that the content is always HTML-encoded
  • Unskip skipped test

Fixes #9946
Fixes #11459


Description

System.Text.Json introduced a feature that allows configuring the encoding behavior including preventing encoding HTML content. In one case, MVC needs to guarantee the generated content is always HTML safe. This is important to prevent XSS.

Regression

The feature was added to System.Text.Json fairly recently and this is a reaction.

Customer Impact

n/a

Risk

n/a

* Update JsonOptions.JsonSerializerOptions to use encoder scheme that does not encode non-ASCII
  characters by default. This makes the encoding comparable to Json.NET's defaults
* In SystemTextJsonHelper, ensure that the content is always HTML-encoded
* Unskip skipped test

Fixes #9946
Fixes #11459
@pranavkm pranavkm changed the title Ensure JsonSerializer always HTML encodes output. Ensure SystemTextJsonHelper always HTML encodes output. Aug 1, 2019
@pranavkm pranavkm added the ask-mode This issue / PR is a patch candidate which we will bar-check internally before patching it. label Aug 1, 2019
@pranavkm pranavkm requested review from JamesNK and rynowak August 1, 2019 18:05

private static JsonSerializerOptions CreateHtmlSafeSerializerOptions(JsonSerializerOptions serializerOptions)
{
var htmlSafeOptions = new JsonSerializerOptions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahsonkhan @steveharter - these are the kinds of cases where a copy constructor would be massively useful.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 as a future feature.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Being tracked by an issue that @pranavkm opened earlier: https://github.com/dotnet/corefx/issues/39939

@Pilchie Pilchie added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Aug 1, 2019
@@ -26,6 +27,9 @@ public class JsonOptions

// Use camel casing for properties
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,

// Does not encode all non-ASCII characters which matches Json.NET"s behavior.
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is a dangerous place to put this line of code. The UnsafeRelaxedJsonEscaping property is only intended to be used in specific scenarios where the stack has tight control over how the data will be written to the wire and how the client will consume the data. Any other usage is dangerous, hence the term "unsafe" in the name.

Here, the part that causes me concern is that ASP.NET is configuring this setting in a place very far removed from its intended known-good usage scenario. Specifically, this particular escaping should only be set if we know for absolute certain that the response will contain a header Content-Type: application/json; charset=utf=8, but this line of code is so far removed from the component that sets the response Content-Type header that this risks introducing a vulnerability due to misuse.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What the heck is the point in having safe defaults if asp.net is going to dump all over them and turn it off?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might be able to localize this to the Json Formatter when the encoding is Uf8 and leave the defaults untouched. Would that be sufficient?

{
var jsonSerializerOptions = jsonOptions.JsonSerializerOptions;

if (jsonSerializerOptions.Encoder is null)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆙 📅

This limits the encoder to use the relaxed encoding specifically in the output formatter assuming the user hasn't already configured it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spoke to @GrabYourPitchforks offline. We decided limited this to the formatter is reasonable. The JsonHelper always defaults to using the Default encoding.

@pranavkm pranavkm merged commit 397f924 into release/3.0 Aug 5, 2019
@ghost ghost deleted the prkrishn/json-helper branch August 5, 2019 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates ask-mode This issue / PR is a patch candidate which we will bar-check internally before patching it.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants