为什么 PasswordField 在 Vaadin 中使用 String 而不是 char[]?

Why PasswordField use String instead of char[] in Vaadin?

字符串对于密码值易受攻击。我注意到 Vaadin PasswordFieldpassword 作为 String 进行操作。

以下是PasswordField,

的默认构造函数
public PasswordField() {
  setValue("");
}

我的问题:

当 vaadin 代码在您的 Web 浏览器中运行时,它不再在 JVM 中,因此在这种情况下使用 String 是可以的。密码将在服务器端存储为 Java 字符串,因此为了访问该密码字符串,攻击者必须访问您的服务器。

您应该查看生成的 javascript 中如何处理该密码字段。

TL;DR 瓦丁 PasswordField is a simple TextField。输入仅在客户端隐藏,在服务器端以明文形式传输。

虽然可以先用getConvertedValue() and setConvertedValue(Object value) for getting/setting the value in your own type. Note that you have to set the setConverter(Converter<T,?> converter)再用

这里有一个如何正确使用对话的例子:Creating your own converter for String - MyType conversion


完整说明

瓦丁 TextField, PasswordField and TextArea are all children of AbstractField<String>.

详细:

java.lang.Object
  |_ com.vaadin.server.AbstractClientConnector
       |_ com.vaadin.ui.AbstractComponent
            |_ com.vaadin.ui.AbstractField<java.lang.String>
                 |_ com.vaadin.ui.AbstractTextField

PasswordField 由于其父项而与 String 一起工作,否则它应该实现 AbstractField<char[]>.

此外在PasswordField section from Vaadin Docs中明确表示:

You should note that the PasswordField hides the input only from "over the shoulder" visual observation. Unless the server connection is encrypted with a secure connection, such as HTTPS, the input is transmitted in clear text and may be intercepted by anyone with low-level access to the network. Also phishing attacks that intercept the input in the browser may be possible by exploiting JavaScript execution security holes in the browser.


虽然AbstractField<T> has getConvertedValue() and setConvertedValue(Object value) which allow to get/set the value in the Object you prefer. Note that before using it you need to set setConverter(Converter<T,?> converter).

这里有一个如何正确使用对话的例子:Creating your own converter for String - MyType conversion

从例子中简而言之:

Name 是一个简单的 POJO,带有 firstNamelastName 字段及其 getter/setter.

转换器class

public class StringToNameConverter implements Converter<String, Name> {

    public Name convertToModel(String text, Locale locale) {
        String[] parts = text.split(" ");
        return new Name(parts[0], parts[1]);
    }

    public String convertToPresentation(Name name, Locale locale)
            throws ConversionException {
        return name.getFirstName() + " " + name.getLastName();
    }

    public Class<Name> getModelType() {
        return Name.class;
    }

    public Class<String> getPresentationType() {
        return String.class;
    }
}

主要class

Name name = new Name("Rudolph", "Reindeer");
final TextField textField = new TextField("Name");
textField.setConverter(new StringToNameConverter());
textField.setConvertedValue(name);
addComponent(textField);
addComponent(new Button("Submit value", new ClickListener() {

    public void buttonClick(ClickEvent event) {
        Name name = (Name) textField.getConvertedValue();
    }

}));

完整来源

参加这个聚会有点晚了,但我想在已经讨论过的内容中加入我的 2 美分。

它可能纯粹是为了方便和代码重用,因为 PasswordField just extends AbstractTextField on the BE side which is basically an AbstractField<String> 所以所有的值操作逻辑、事件处理等都已经存在了。

否则,人们可能不得不为此实现 AbstractField<char[]> 并复制粘贴 AbstractTextField 中的几乎所有内容。或者泛化 AbstractTextField 或类似的东西...

无论哪种方式,如前所述,攻击者都需要访问服务器以转储内存,在这种情况下您可能会遇到更大的问题,无论是来自组织外部还是组织内部(肯定有自己的情况员工出于某些原因造成了伤害):-)

关于 FE,VPasswordField counterpart creates an input of type password,以及关于 FE-BE 通信的安全问题已经在 Paolo Forgia 的回答中讨论过。