Do not use `FormattedModelValue` in password editor template

- #135
- see also PR aspnet/Mvc#7430
- add quirk switch to reverse this if necessary
This commit is contained in:
Doug Bunting 2018-03-02 16:25:49 -08:00
Родитель f9e06d60e4
Коммит 2b7ac74060
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 888B4EB7822B32E9
2 изменённых файлов: 75 добавлений и 12 удалений

Просмотреть файл

@ -9,6 +9,7 @@ using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.Configuration;
using System.Web.Mvc.Properties;
using System.Web.Routing;
using System.Web.UI.WebControls;
@ -18,6 +19,7 @@ namespace System.Web.Mvc.Html
internal static class DefaultEditorTemplates
{
private const string HtmlAttributeKey = "htmlAttributes";
private const string UsePasswordValue = "Switch.System.Web.Mvc.UsePasswordValue";
internal static string BooleanTemplate(HtmlHelper html)
{
@ -149,11 +151,11 @@ namespace System.Web.Mvc.Html
MvcHtmlString hiddenResult;
if (htmlAttributesDict != null)
if (htmlAttributesDict != null)
{
hiddenResult = html.Hidden(String.Empty, model, htmlAttributesDict);
}
else
}
else
{
hiddenResult = html.Hidden(String.Empty, model, htmlAttributesObject);
}
@ -178,9 +180,9 @@ namespace System.Web.Mvc.Html
{
return MergeHtmlAttributes(htmlAttributesObject, className, inputType);
}
var htmlAttributes = new Dictionary<string, object>()
{
{
{ "class", className }
};
if (inputType != null)
@ -274,9 +276,21 @@ namespace System.Web.Mvc.Html
internal static string PasswordTemplate(HtmlHelper html)
{
return html.Password(String.Empty,
html.ViewContext.ViewData.TemplateInfo.FormattedModelValue,
CreateHtmlAttributes(html, "text-box single-line password")).ToHtmlString();
object value = null;
var usePasswordStrings = WebConfigurationManager.AppSettings.GetValues(UsePasswordValue);
bool usePasswordValue;
if (usePasswordStrings != null &&
usePasswordStrings.Length > 0 &&
bool.TryParse(usePasswordStrings[0], out usePasswordValue) &&
usePasswordValue)
{
value = html.ViewContext.ViewData.TemplateInfo.FormattedModelValue;
}
return html.Password(
name: String.Empty,
value: value,
htmlAttributes: CreateHtmlAttributes(html, "text-box single-line password")).ToHtmlString();
}
private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo)

Просмотреть файл

@ -731,14 +731,63 @@ namespace System.Web.Mvc.Html.Test
public void PasswordTemplateTests()
{
Assert.Equal(
"<input class=\"text-box single-line password\" id=\"FieldPrefix\" name=\"FieldPrefix\" type=\"password\" value=\"Value\" />",
"<input class=\"text-box single-line password\" id=\"FieldPrefix\" name=\"FieldPrefix\" type=\"password\" />",
DefaultEditorTemplates.PasswordTemplate(MakeHtmlHelper<string>("Value")));
Assert.Equal(
"<input class=\"text-box single-line password\" id=\"FieldPrefix\" name=\"FieldPrefix\" type=\"password\" value=\"&lt;script>alert(&#39;XSS!&#39;)&lt;/script>\" />",
"<input class=\"text-box single-line password\" id=\"FieldPrefix\" name=\"FieldPrefix\" type=\"password\" />",
DefaultEditorTemplates.PasswordTemplate(MakeHtmlHelper<string>("<script>alert('XSS!')</script>")));
}
[Fact]
public void PasswordTemplate_ReturnsInputElement_IgnoresValues()
{
// Arrange
var expected = "<input class=\"text-box single-line password\" id=\"FieldPrefix\" name=\"FieldPrefix\" " +
"type=\"password\" />";
// Template ignores Model and FormattedModelValue.
var helper = MakeHtmlHelper<string>(model: "Model string", formattedModelValue: "Formatted string");
var viewData = helper.ViewData;
var templateInfo = viewData.TemplateInfo;
templateInfo.HtmlFieldPrefix = "FieldPrefix";
// Template ignores ModelState and ViewData.
var valueProviderResult = new ValueProviderResult(
"Raw model string",
"Attempted model string",
CultureInfo.InvariantCulture);
viewData.ModelState.SetModelValue("FieldPrefix", valueProviderResult);
viewData["FieldPrefix"] = "ViewData string";
// Act
var result = DefaultEditorTemplates.PasswordTemplate(helper);
// Assert
Assert.Equal(expected, result);
}
[Fact]
public void PasswordTemplate_ReturnsInputElement_UsesHtmlAttributes()
{
// Arrange
var expected = "<input class=\"super text-box single-line password\" id=\"FieldPrefix\" " +
"name=\"FieldPrefix\" type=\"password\" value=\"Html attributes string\" />";
var helper = MakeHtmlHelper<string>(model: null);
var viewData = helper.ViewData;
var templateInfo = viewData.TemplateInfo;
templateInfo.HtmlFieldPrefix = "FieldPrefix";
viewData["htmlAttributes"] = new { @class = "super", value = "Html attributes string" };
// Act
var result = DefaultEditorTemplates.PasswordTemplate(helper);
// Assert
Assert.Equal(expected, result);
}
public static TheoryDataSet<object, string> PasswordTemplateHtmlAttributeData
{
get
@ -747,11 +796,11 @@ namespace System.Web.Mvc.Html.Test
{
{
new { @class = "form-control" },
"<input class=\"form-control text-box single-line password\" id=\"FieldPrefix\" name=\"FieldPrefix\" type=\"password\" value=\"Value\" />"
"<input class=\"form-control text-box single-line password\" id=\"FieldPrefix\" name=\"FieldPrefix\" type=\"password\" />"
},
{
new { @class = "form-control", custom = "foo" },
"<input class=\"form-control text-box single-line password\" custom=\"foo\" id=\"FieldPrefix\" name=\"FieldPrefix\" type=\"password\" value=\"Value\" />"
"<input class=\"form-control text-box single-line password\" custom=\"foo\" id=\"FieldPrefix\" name=\"FieldPrefix\" type=\"password\" />"
}
};
}