- You're making the view harder to read and you're missing a chance to reuse your code.
- You're not properly escaping e-mail address (see RFC5322 RFC5322 and Wikipedia). If you don't then you're open to Code Injection attack (see later).
- Some (older) browsers won't accept the trailing comma after the last array item (see MDN).
- You're making the view harder to read and you're missing a chance to reuse your code.
- You're not properly escaping e-mail address (see RFC5322 and Wikipedia). If you don't then you're open to Code Injection attack (see later).
- Some (older) browsers won't accept the trailing comma after the last array item (see MDN).
- You're making the view harder to read and you're missing a chance to reuse your code.
- You're not properly escaping e-mail address (see RFC5322 and Wikipedia). If you don't then you're open to Code Injection attack (see later).
- Some (older) browsers won't accept the trailing comma after the last array item (see MDN).
static string AsJsArrayStringAsJsArrayString<T>(this IEnumerable<T> items)
{
var array = new StringBuilder();
array.Append('[');
array.Append(String.Join(",", items.Select(x => $"'{x}'")));
array.Append(']');
return array.ToString();
}
$("#email").emailautocomplete({
domains: @Html.Raw(Model.Organisations.Select(x => x.EmailDomain).AsJsArrayString())
});
Now we can look at second issue. E-mail addresses may contain invalid characters for a JavaScript string (for example "
or '
), JavaScript escaping is not the same as JSON escaping (done with Json.Encode()
) but fortunately we have an ad-hoc function HttpUtility.JavaScriptStringEncode()
(JavaScriptEncoder
for .NET Core, see later):
static string AsJsArrayString(this IEnumerable<string> items)
=> "[" + String.Join(",", items.Select(x => "'" + HttpUtility.JavaScriptStringEncode(x) + "'")) + "]";
@functions {
public static string ToJsArrayString(IEnumerable<string> items)
{
return "["
+ String.Join(",", items.Select(x => "'" + HttpUtility.JavaScriptStringEncode(x) + "'"))
+ "]";
}
}
$("#email").emailautocomplete({
domains: @ToJsArrayString(Model.Organisations.Select(x => x.EmailDomain))
});
HttpUtility
is a .NET thing, in .NET Core you have a brand you class JavaScriptEncoder
. Let's write an extension method for that:
public static string Encode<T>(this JavaScriptEncoder encoder, IEnumerable<T> items)
{
return '[' + String.Join(",", items.Select(x => EncodeAndQuote(x))) + ']';
string EncodeAndQuote(string text)
=> '"' + encoder.Encode(text) + '"';
}
Used like this:
$("#email").emailautocomplete({
domains: @JavaScriptEncoder.Encode(Model.Organisations.Select(x => x.EmailDomain))
});
In short: do not EVER trust user input, even when you think you do not need escaping (and of course use the right escape function unless you want an half baked solution).
static string AsJsArrayString(this IEnumerable<T> items)
{
var array = new StringBuilder();
array.Append('[');
array.Append(String.Join(",", items.Select(x => $"'{x}'"));
array.Append(']');
return array.ToString();
}
$("#email").emailautocomplete({
domains: @Html.Raw(Model.Organisations.Select(x => x.EmailDomain).AsJsArrayString())
});
Now we can look at second issue. E-mail addresses may contain invalid characters for a JavaScript string (for example "
or '
), JavaScript escaping is not the same as JSON escaping (done with Json.Encode()
) but fortunately we have an ad-hoc function HttpUtility.JavaScriptStringEncode()
:
static string AsJsArrayString(this IEnumerable<string> items)
=> "[" + String.Join(",", items.Select(x => "'" + HttpUtility.JavaScriptStringEncode(x) + "'") + "]";
@functions {
public static string ToJsArrayString(IEnumerable<string> items)
{
return "["
+ String.Join(",", items.Select(x => "'" + HttpUtility.JavaScriptStringEncode(x) + "'")
+ "]";
}
}
$("#email").emailautocomplete({
domains: @ToJsArrayString(Model.Organisations.Select(x => x.EmailDomain))
});
In short: do not EVER trust user input, even when you think you do not need escaping (and of course use the right escape function unless you want an half baked solution).
static string AsJsArrayString<T>(this IEnumerable<T> items)
{
var array = new StringBuilder();
array.Append('[');
array.Append(String.Join(",", items.Select(x => $"'{x}'")));
array.Append(']');
return array.ToString();
}
$("#email").emailautocomplete({
domains: @Html.Raw(Model.Organisations.Select(x => x.EmailDomain).AsJsArrayString())
});
Now we can look at second issue. E-mail addresses may contain invalid characters for a JavaScript string (for example "
or '
), JavaScript escaping is not the same as JSON escaping (done with Json.Encode()
) but fortunately we have an ad-hoc function HttpUtility.JavaScriptStringEncode()
(JavaScriptEncoder
for .NET Core, see later):
static string AsJsArrayString(this IEnumerable<string> items)
=> "[" + String.Join(",", items.Select(x => "'" + HttpUtility.JavaScriptStringEncode(x) + "'")) + "]";
@functions {
public static string ToJsArrayString(IEnumerable<string> items)
{
return "["
+ String.Join(",", items.Select(x => "'" + HttpUtility.JavaScriptStringEncode(x) + "'"))
+ "]";
}
}
$("#email").emailautocomplete({
domains: @ToJsArrayString(Model.Organisations.Select(x => x.EmailDomain))
});
HttpUtility
is a .NET thing, in .NET Core you have a brand you class JavaScriptEncoder
. Let's write an extension method for that:
public static string Encode<T>(this JavaScriptEncoder encoder, IEnumerable<T> items)
{
return '[' + String.Join(",", items.Select(x => EncodeAndQuote(x))) + ']';
string EncodeAndQuote(string text)
=> '"' + encoder.Encode(text) + '"';
}
Used like this:
$("#email").emailautocomplete({
domains: @JavaScriptEncoder.Encode(Model.Organisations.Select(x => x.EmailDomain))
});
In short: do not EVER trust user input, even when you think you do not need escaping.
- You're making tothe view harder to read and you're missing a chance to reuse your code.
- You're not properly escaping e-mail address (see RFC5322 and Wikipedia). If you don't then you're open to Code Injection attack (see later).
- Some (older) browsers won't accept the trailing comma after the last array item (see MDN).
Now we can look at second issue. E-mail addresses may contain invalid characters for a JavaScript string (for example "
or '
), JavaScript escaping is not the same as JSON escaping JavaScript escaping is not the same as JSON escaping(done with Json.Encode()
) but fortunately we have an ad-hoc function HttpUtility.JavaScriptStringEncode()
:
$("#email").emailautocomplete({
domains: @ToJsArrayString(Model.Organisations.Select(x => x.EmailDomain))
});
Code injection. Unfortunately I've not been clear, domain names can contain characters that need to be escaped. In case you think it's not an issue: would you allow your users to have a perfectly valid and usable email address that, however, will break your Javascript code (I guess in an administrative page) with a chance to execute arbitrary code? I would not.
Let's pick this perfectly valid e-mail address: john.smith@(here\I\can\write\anything)example.com
. If not escaped then it will break your JavaScript code. An easy way to block your service until you will find the issue and fix the problem.
Worse that that, they can execute code with the privileges of the user of that page (and it seems an administrative page). Imagine they write this perfectly valid e-mail address:
john.smith@(",$.post('/api/customers/delete'),")example.com
Your JavaScript code isn't broken but you're executing code they injected, in this case an innocent AJAX POST.
In short: do not EVER trust user input, even when you think you do not need escaping (and of course use the right escape function unless you want an half baked solution).
- You're making to view harder to read.
- You're not properly escaping e-mail address (see RFC5322 and Wikipedia).
- Some (older) browsers won't accept the trailing comma after the last array item (see MDN).
Now we can look at second issue. E-mail addresses may contain invalid characters for a JavaScript string (for example "
or '
), JavaScript escaping is not the same as JSON escaping (done with Json.Encode()
) but fortunately we have an ad-hoc function HttpUtility.JavaScriptStringEncode()
:
$("#email").emailautocomplete({
domains: @ToJsArrayString(Model.Organisations.Select(x => x.EmailDomain))
});
- You're making the view harder to read and you're missing a chance to reuse your code.
- You're not properly escaping e-mail address (see RFC5322 and Wikipedia). If you don't then you're open to Code Injection attack (see later).
- Some (older) browsers won't accept the trailing comma after the last array item (see MDN).
Now we can look at second issue. E-mail addresses may contain invalid characters for a JavaScript string (for example "
or '
), JavaScript escaping is not the same as JSON escaping(done with Json.Encode()
) but fortunately we have an ad-hoc function HttpUtility.JavaScriptStringEncode()
:
$("#email").emailautocomplete({
domains: @ToJsArrayString(Model.Organisations.Select(x => x.EmailDomain))
});
Code injection. Unfortunately I've not been clear, domain names can contain characters that need to be escaped. In case you think it's not an issue: would you allow your users to have a perfectly valid and usable email address that, however, will break your Javascript code (I guess in an administrative page) with a chance to execute arbitrary code? I would not.
Let's pick this perfectly valid e-mail address: john.smith@(here\I\can\write\anything)example.com
. If not escaped then it will break your JavaScript code. An easy way to block your service until you will find the issue and fix the problem.
Worse that that, they can execute code with the privileges of the user of that page (and it seems an administrative page). Imagine they write this perfectly valid e-mail address:
john.smith@(",$.post('/api/customers/delete'),")example.com
Your JavaScript code isn't broken but you're executing code they injected, in this case an innocent AJAX POST.
In short: do not EVER trust user input, even when you think you do not need escaping (and of course use the right escape function unless you want an half baked solution).