最终我需要的是:一个组合框和一个文本字段。从组合框中选择项目将填充文本字段中的值。组合框中的项目来自用户输入。
这是我当前的代码很好用:
function fill() {
var select = document.getElementById("select");
var value = select.options[select.selectedIndex].value;
var textfield = document.getElementById("textfield");
switch (value) {
case "1":
textfield.value = "some user-provided text";
break;
case "2":
textfield.value = "containing possibly < > & etc.";
break;
}
}
<select id="select" onchange="fill()">
<option>Select something...</option>
<option value="1">Select option 1</option>
<option value="2">Select option 2</option>
</select>
<input type="text" id="textfield"/>
如果要填充的用户提供的文本包含危险字符,我不知道该怎么办。通常我会在HTML代码中编写之前对其进行HTML编码,但现在我将其编写为JavaScript代码。
所有JavaScript都是由Java后端生成的。我无法真正创建它:
String value = getValueFromUser();
write("textfield.value = \"" + value + "\";");
因为有人会输入"; somethingBad(); //
,而其他一些用户会选择此选项,执行somethingBad()
。
如果我对值进行HTML编码:
String value = htmlEncode(getValueFromUser());
write("textfield.value = \"" + value + "\";");
然后(除了安全问题)在组合框中选择一个值之后,文本字段将填充HTML编码的文本。
如何对用户提供的值进行编码,以便:
答案 0 :(得分:2)
让我提出自己的想法。
我的Java代码生成包含来自用户的HTML编码输入的隐藏HTML元素(例如spans):
<span id="case1" class="hidden">some user-provided text</span>
<span id="case2" class="hidden">containing possibly > < & etc.</span>
然后我的JavaScript代码将使用此处的值:
function fill() {
var select = document.getElementById("select");
var value = select.options[select.selectedIndex].value;
var textfield = document.getElementById("textfield");
switch (value) {
case "1":
textfield.value = document.getElementById("case1").innerHTML;
break;
case "2":
textfield.value = document.getElementById("case2").innerHTML;
break;
}
}
这样我就不用担心编码用户输入在JavaScript代码中是安全的 - 它永远不会在JS代码中!它只是在HTML内部,众所周知如何进行HTML编码以确保安全。
明显的缺点是生成隐藏的HTML元素,但这似乎是一种可接受的妥协......
答案 1 :(得分:1)
存储您的值转义,然后:
String value = getEscapedValueFromUser();
write("textfield.value = unescape(\"" + value + "\");");
这将从您存储的字符串中删除括号,引号和“=”,以防止任何恶意代码。
在以下评论之后编辑:
当您验证输入并将其完全转义存储时,您最好的选择是在js中转义它()。然后你只需要将unescape()添加到“...”之外的write()行,如上面的代码所示。
这编码了大多数特殊的字符[只是google'js escape()'以供参考]你肯定无法摆脱“......”,如果有线就没有进入下一行休息,没有需要包含在恶意代码中的字符,字符串总是最终作为输入,因为escape / unescape是互补的,你不会忘记任何事情,并且不会意外地将真正的'\ n'编码为[enter]目标字串。
如果您不想这样做,因为您可能已经在数据库中收集了大量未转义的值,或者在其他地方使用它们并且无法更改数据库以保存额外的字段,则应复制转义函数在java中你认为你需要它[在进一步认为是安全的之后你应该编码所有控制字符和"'()%=;
,或者只是复制整个函数,不会太难]。
答案 2 :(得分:0)
我通常使用以下函数返回一个字符串,以显示任何类型的文本:
function RemoveEntities (TextToReplace)
{
var ReplacedText='';
var CurrentChar='';
if (typeof TextToReplace=='number') {TextToReplace=TextToReplace.toString();}
for (i=0;i<TextToReplace.length;i++)
{
CurrentChar=TextToReplace.substring(i,i+1);
if (CurrentChar=="&") {ReplacedText=ReplacedText+"&";}
else if (CurrentChar=="<") {ReplacedText=ReplacedText+"<";}
else if (CurrentChar==">") {ReplacedText=ReplacedText+">";}
else if (CurrentChar==" ") {ReplacedText=ReplacedText+" ";}
else if (CurrentChar=="'") {ReplacedText=ReplacedText+"'";}
else if (CurrentChar=='"') {ReplacedText=ReplacedText+""";}
else if (escape(CurrentChar)=='%0A' || escape(CurrentChar)=='%0C') {ReplacedText=ReplacedText+"<br/>";}
else {ReplacedText=ReplacedText+CurrentChar;}
}
return ReplacedText;
}
这应该适用于短文本输入。也可以缩短+ =或全局替换语句,但我还没有优化它(不是瓶颈)。