ユーザー提供のオペランドと演算子を適切にチェックして、他のjavascript実行可能コードの代わりに必要なデータが含まれていることを確認すると、2つのオペランドを演算子で連結し、フィードしeval()
て実行できます。
さて、JavaScriptコードを実行できるので危険eval()
です。ユーザーは、実行可能ファイルや悪意のあるJavaScriptコードをオペレーターとしてフィードし、それを評価することができます。したがって、連結を行う場合は、オペランドが安全であることを確認してから行う必要があります。この点を強調するために、私はコンピュータセキュリティの最も重要な信条の1つを大きなフォントで書きます。eval()
他の方法で証明されるまで、すべての入力は悪です。
eval()
また、 JavaScriptインタープリターを呼び出して、コードを解釈、コンパイル、実行することに注意してください。これは遅いです。たまに使用している場合は、観察可能なパフォーマンスの問題に気付かない場合がありますが、たとえば、すべてのキーイベントで頻繁にeval()
電話をかけている場合は、パフォーマンスの問題に気付く場合があります。eval()
のこれらの欠点を考慮するeval()
と、FelixKlingによって投稿されたようなより優れたソリューションを選択することをお勧めします。eval()
ただし、以下に示すように、安全な方法でこの問題を解決することもできます。
function compare(a, op, b)
{
// Check that we have two numbers and an operator fed as a string.
if (typeof a != 'number' || typeof b != 'number' || typeof op != 'string')
return
// Make sure that the string doesn't contain any executable code by checking
// it against a whitelist of allowed comparison operators.
if (['<', '>', '<=', '>=', '==', '!='].indexOf(op) == -1)
return
// If we have reached here, we are sure that a and b are two integers and
// op contains a valid comparison operator. It is now safe to concatenate
// them and make a JavaScript executable code.
if (eval(a + op + b))
doSomething();
}
ホワイトリストに対して入力を検証することは、ブラックリストに対して入力を検証するよりも、ほとんどの場合、より良い考えであることに注意してください。簡単な説明については、https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet#White_List_Input_Validationを参照してください。
このソリューションのデモンストレーションは次のとおりです。http://jsfiddle.net/YrQ4C/(コードも以下に複製されています):
function doSomething()
{
alert('done something!')
}
function compare(a, op, b)
{
if (typeof a != 'number' || typeof b != 'number' || typeof op != 'string')
return
if (['<', '>', '<=', '>=', '==', '!='].indexOf(op) == -1)
return
if (eval(a + op + b))
doSomething();
}
// Positive test cases
compare(2, '<', 3)
compare(2, '<=', 3)
// Negative test cases
compare(2, '>', 3)
compare(2, '>=', 3)
// Attack tests
compare('alert(', '"attack!"', ')')
// Edit: Adding a new attack test case given by Jesse
// in the comments below. This function prevents this
// attack successfully because the whitelist validation
// for the second argument would fail.
compare(1, ';console.log("executed code");2==', 2)
編集:ジェシーのテストケースを含むデモ:http://jsfiddle.net/99eP2/