データベースから値を出力しています(実際には一般公開されていませんが、会社のユーザーによって公開されています - つまり、私は心配していません 。 _ xss _ 。)
私はこのようなタグを出力しようとしています:
<a href="" onclick="DoEdit('DESCRIPTION');">Click Me</a>
DESCRIPTIONは実際にはデータベースからの値であり、これは次のようなものです。
Prelim Assess "Mini" Report
"\"に置き換えようとしましたが、何をしようと、FirefoxはWordAssessの後のスペースの後にJavaScript呼び出しを切り落とし続けています。問題の.
私は明白な答えを捨て去る必要がありますが、私の人生のために私はそれを理解することはできません。
誰かが私の馬鹿げたことを指摘することを気にかけますか?
これはHTMLページ全体です(最終的には ASP.NET ページになりますが、これを解決するために、問題コード以外はすべて取り除きました)。 )
<html>
<body>
<a href="#" onclick="DoEdit('Preliminary Assessment \"Mini\"'); return false;">edit</a>
</body>
</html>
二重引用符を削除するには、書き出す文字列をDoEdit
にエスケープする必要があります。それらはonclick
HTML属性を早めに閉じさせています。
JavaScriptのエスケープ文字\
を使用しても、HTMLのコンテキストでは不十分です。二重引用符を適切なXMLエンティティ表現"
に置き換える必要があります。
HTMLコンテキストのため、"
はこの特定のケースではうまく機能します。
ただし、JavaScriptコードを任意のコンテキストに対して個別にエスケープする場合は、ネイティブのJavaScriptエンコーディングを選択できます。'
は\x27
になります"
は\x22
になります
だからあなたのクリックは次のようになります。DoEdit('Preliminary Assessment \x22Mini\x22');
これは、たとえばJavaScript文字列をパラメータとして別のJavaScriptメソッドに渡すときにも機能します(alert()
はこのための簡単なテストメソッドです)。
重複したスタックオーバーフローの質問を参照しています。onClickハンドラ内のJavaScriptコード内の文字列をエスケープするにはどうすればよいですか?.
<html>
<body>
<a href="#" onclick="DoEdit('Preliminary Assessment "Mini"'); return false;">edit</a>
</body>
</html>
トリックをするべきです。
皆さん、JavaScriptには既にunescape
という関数があり、これは\"
のエスケープ解除を行います。
<script type="text/javascript">
var str="this is \"good\"";
document.write(unescape(str))
</script>
問題は、HTMLがエスケープ文字を認識しないことです。 HTML属性には一重引用符を使用し、onclickには二重引用符を使用することでこれを回避できます。
<a href="#" onclick='DoEdit("Preliminary Assessment \"Mini\""); return false;'>edit</a>
これが私のやり方、基本的にはstr.replace(/[\""]/g, '\\"')
です。
var display = document.getElementById('output');
var str = 'class="whatever-foo__input" id="node-key"';
display.innerHTML = str.replace(/[\""]/g, '\\"');
//will return class=\"whatever-foo__input\" id=\"node-key\"
<span id="output"></span>
HTMLをJavaで組み立てる場合は、Apache commons-langのこのNiceユーティリティクラスを使用して、すべてのエスケープを正しく実行できます。
org.Apache.commons.lang.StringEscapeUtils
Java、Java Script、HTML、XML、およびSQLの文字列のエスケープとアンエスケープ。
以下のコードで、正規表現を使用して入力文字列の一部として一重引用符をエスケープします。ユーザーが入力した文字列がカンマで区切られているかどうかを検証し、同時に文字列の一部として入力された単一引用符もエスケープします。一重引用符をエスケープするには、バックスラッシュとそれに続く一重引用符を入力します。 」 文字列の一部として。この例ではJQueryバリデータを使いました。
有効な文字列の例:
'こんにちは'
'こんにちは世界'
'こんにちは世界'
'こんにちは世界'、' '
「それは私の世界だ」、「私なしでは楽しめない」、「ようこそ、ゲスト」
HTML:
<tr>
<td>
<label class="control-label">
String Field:
</label>
<div class="inner-addon right-addon">
<input type="text" id="stringField"
name="stringField"
class="form-control"
autocomplete="off"
data-rule-required="true"
data-msg-required="Cannot be blank."
data-rule-commaSeparatedText="true"
data-msg-commaSeparatedText="Invalid comma separated value(s).">
</div>
</td>
JavaScript:
/**
*
* @param {type} param1
* @param {type} param2
* @param {type} param3
*/
jQuery.validator.addMethod('commaSeparatedText', function(value, element) {
if (value.length === 0) {
return true;
}
var expression = new RegExp("^((')([^\'\\\\]*(?:\\\\.[^\'\\\\])*)[\\w\\s,\\.\\-_\\[\\]\\)\\(]+([^\'\\\\]*(?:\\\\.[^\'\\\\])*)('))(((,)|(,\\s))(')([^\'\\\\]*(?:\\\\.[^\'\\\\])*)[\\w\\s,\\.\\-_\\[\\]\\)\\(]+([^\'\\\\]*(?:\\\\.[^\'\\\\])*)('))*$");
return expression.test(value);
}, 'Invalid comma seperated string values.');
私はjQueryを使ってサンプルをやった
var descr = 'test"inside"outside';
$(function(){
$("#div1").append('<a href="#" onclick="DoEdit(descr);">Click Me</a>');
});
function DoEdit(desc)
{
alert ( desc );
}
そしてこれはInternet ExplorerとFirefoxで動作します。
これらの2つの関数(以下にリスト)をコピーし、それらを使用してすべての引用符と特殊文字をエスケープ/エスケープできます。このためにjQueryや他のライブラリを使用する必要はありません。
function escape(s) {
return ('' + s)
.replace(/\\/g, '\\\\')
.replace(/\t/g, '\\t')
.replace(/\n/g, '\\n')
.replace(/\u00A0/g, '\\u00A0')
.replace(/&/g, '\\x26')
.replace(/'/g, '\\x27')
.replace(/"/g, '\\x22')
.replace(/</g, '\\x3C')
.replace(/>/g, '\\x3E');
}
function unescape(s) {
s = ('' + s)
.replace(/\\x3E/g, '>')
.replace(/\\x3C/g, '<')
.replace(/\\x22/g, '"')
.replace(/\\x27/g, "'")
.replace(/\\x26/g, '&')
.replace(/\\u00A0/g, '\u00A0')
.replace(/\\n/g, '\n')
.replace(/\\t/g, '\t');
return s.replace(/\\\\/g, '\\');
}
二重のバックスラッシュで引用符をエスケープする必要があります。
これは失敗します(PHPの json_encode によって生成されます)。
<script>
var jsonString = '[{"key":"my \"value\" "}]';
var parsedJson = JSON.parse(jsonString);
</script>
これは動作します:
<script>
var jsonString = '[{"key":"my \\"value\\" "}]';
var parsedJson = JSON.parse(jsonString);
</script>
あなたはescape()とunescape()のjqueryメソッドを使うことができます。
ユーザーエスケープ(str)文字列をエスケープし、unescape(str_esc)を使用して再度回復します。
空白もエスケープします。 Firefoxは1つではなく3つの引数を想定しているようです。
は改行なしのスペース文字です。それが問題全体ではないとしても、それはまだ良い考えかもしれません。