【问题标题】:Why PasswordField use String instead of char[] in Vaadin?为什么 PasswordField 在 Vaadin 中使用 String 而不是 char[]?
【发布时间】:2016-08-11 06:36:25
【问题描述】:

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

下面是PasswordField的默认构造函数,

public PasswordField() {
  setValue("");
}

我的问题:

  • 在 Vaadin 中使用 PasswordField 是否安全?
  • 内部 API 做什么来确保密码的安全?

【问题讨论】:

  • 我不明白使用字符串是如何易受攻击的。字符串也用于其他 java 框架。此外,正则表达式可用于设置密码模式。
  • @cdaiga see this 解释了为什么char[]String 更安全

标签: java vaadin vaadin7


【解决方案1】:

TL;DR Vaadin PasswordField 是一个简单的 TextField。输入只是在客户端隐藏,在服务器端以明文传输。

虽然您可以使用getConvertedValue()setConvertedValue(Object value) 来获取/设置您自己类型的值。请注意,您必须在使用之前设置setConverter(Converter<T,?> converter)

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


完整说明

Vaadin TextFieldPasswordFieldTextArea 都是 AbstractField<String> 的子级。

详细说明:

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

PasswordFieldString 一起工作,因为它的父母,否则它应该实现 AbstractField&lt;char[]&gt;

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

您应该注意PasswordField 隐藏了输入仅对“过肩”目视观察。除非使用 HTTPS 等安全连接对服务器连接进行加密,否则输入以明文形式传输,并且可能被任何对网络具有低级别访问权限的人截获。通过利用浏览器中的 JavaScript 执行安全漏洞,拦截浏览器中的输入的网络钓鱼攻击也可能发生。


虽然 AbstractField&lt;T&gt;getConvertedValue()setConvertedValue(Object value) 允许在您喜欢的 Object 中获取/设置值。注意,使用前需要设置setConverter(Converter&lt;T,?&gt; converter)

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

简而言之:

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

转换器类

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;
    }
}

主类

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】:

    这个聚会有点晚了,但我想把我的 2 美分加到已经讨论过的内容上。

    这可能是纯粹的舒适和代码重用,因为 PasswordField 只是在 BE 端扩展 AbstractTextField,基本上是 AbstractField&lt;String&gt;,所以所有的值操作逻辑、事件处理等都已经存在。

    否则可能不得不实现AbstractField&lt;char[]&gt; 并为此从AbstractTextField 复制粘贴几乎所有内容。或者生成AbstractTextField 或类似的东西......

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

    关于 FE,VPasswordField 对应方创建 an input of type password,并且在 Paolo Forgia 的回答中已经讨论了与 FE-BE 通信有关的安全问题。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-01
        • 2015-11-10
        • 2021-02-17
        • 1970-01-01
        相关资源
        最近更新 更多