7

Pythonと同様:変数を演算子(+、/、*、-)と等しくする

ユーザーが実行する比較のタイプと、比較する値を選択できるコードが少しあります。Javascriptに、ユーザーが提供した比較値を実際の比較に変換して、次のようなことができるようにする方法があるかどうか知りたいです。

if (user_val user_comparison other_val) {
    do_something();
}

次のようなことをする代わりに:

if (user_comparison = '<') {
    if (user_val < other_val) {
        do_something();
    }
else if (user_comparison = '<=') {
    if (user_val <= other_val) {
        do_something();
    }
....etc

比較のいずれかが一致した場合、同じコードが実行されることに注意してください。

4

3 に答える 3

16

いいえ、それは不可能です。しかし、より良い方法でコードを構造化することができます。たとえば、ルックアップテーブルを作成できます。

var operator_table = {
    '>': function(a, b) { return a > b; },
    '<': function(a, b) { return a < b; }
    // ...
};

以降:

if(operator_table[user_comparison](user_val, other_val)) {
    // do something
}

user_comparisonもちろん、テーブルにが存在しない場合も処理する必要があります。

これらにより、許可された演算子と許可されていない演算子をより適切に制御することもできます。

これは@Jesseによって作成されたデモです。

于 2012-05-14T21:29:25.783 に答える
5

ユーザー提供のオペランドと演算子を適切にチェックして、他の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/

于 2012-05-14T21:27:47.893 に答える
-2

@SusamPalコードが機能していないため。作業バージョンを投稿しています

<html>
  <head>
   <script>
       function CompareSomething(val1, compareString, val2) {  
           eval('if(' + val1 + ' ' + compareString + ' ' + val2 + '){conditionPassed();}else{conditionFailed();}'); 
  }
  function compare(a, op, b) { 
      if (eval(a + op + b))
          conditionPassed();
      else
         conditionFailed();
  }
  function conditionPassed() {
      alert('condition passed');
  }
  function conditionFailed() {
      alert('condition failed');
  }
    </script>
  </head> 
<body>
a:<input id='txt1' type="text" />&nbsp;op:<input id='txt2' type="text" />&nbsp;b:<input id='txt3' type="text" /><br/>
<button id='compare'  onclick='CompareSomething(document.getElementById("txt1").value,document.getElementById("txt2").value,document.getElementById("txt3").value)'>Compare Esen Method</button><br/>
<button id='compare'  onclick='Compare(document.getElementById("txt1").value,document.getElementById("txt2").value,document.getElementById("txt3").value)'>Compare Susam Method</button>
  </body>
 </html>
于 2012-05-14T21:37:42.523 に答える