@Sei2423 (Sei 2423)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

evalの危険性について

eval、Functionはなぜ危険なのか

色々なサイトに

eval() は呼び出し元の権限で渡されたコードを実行します。悪意のある第三者に影響を受ける可能性のある文字列で eval() を実行すると、そのウェブページや拡張機能の権限において、ユーザーのマシン上で悪意のあるコードを実行してしまう可能性があります。さらに重要なことに、サードパーティのコードが eval() が(直接的な eval であれば)呼び出されたスコープを見ることができるため、攻撃者がローカル変数を読み取ったり変更したりすることができてしまいます。
(引用元: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/eval#eval_を使わないでください!)

のような内容が書いてありますが、

Function("<通常のコード>")

のように、eval内へ外部からの影響がない場合にはどのような危険性があると考えられまsでしょうか。

また、eval、Functionを使用した際の危険性の違いに関しても教えていただきたいです。

0 likes

3Answer

自分が指定したコードのみしかevalに渡さない場合、セキュリティ的な問題があるか、ということ?
もしそうなら、問題はない。
ただし、そのコード自体が意味ない。

もし実行されるコードが事前にわかっているなら、それを関数として定義してそれを呼び出すだけ。なのでeval自体いらないし、使わない。
evalを使うタイミングは、ユーザが入力したコードを実行するとき等のあなたの言葉でいう"外部からの影響"があるときのみ。

2Like

Comments

  1. @Sei2423

    Questioner

    @midoribi
    ご回答ありがとうございます!!

    自分が指定したコードのみしかevalに渡さない場合、セキュリティ的な問題があるか、ということ?

    はい、そういうことです!
    eval等を難読化に使えるかなと疑問に思ったため質問させていただきました。

eval("<Code>")(直接eval)は、そのローカルスコープにアクセス出来ます。
そのため、攻撃者はスコープ内の変数のパスワード等を取得できます。

localScopeCode("count = 1");
function localScopeCode(code){
    let count = 0;
    eval(code); // "count = 1"を実行
    console.log(count); // evalした結果countが改竄される
}

new Function("<Code>")eval?.("<Code>")(間接eval)は
ローカルスコープにアクセスできません。しかしグローバルスコープ、
windowdocument.cookie等にはアクセスできるので、
攻撃者は偽画面を表示したりCookie、localStorageを取得できます。

localScopeCode("count = 1");
function localScopeCode(code, isEval){
    let count = 0;
    if(isEval) eval?.(code); // 間接eval
    else (new Function(code))(); // new Function()を実行
    console.log(count); // 上のコードはローカルスコープにアクセスできないので改竄されない
}
1Like

Comments

  1. @Sei2423

    Questioner

    ご回答ありがとうございます!!
    直接evalの場合、ローカルスコープの値を変更できてしまうのはとても危険ですね。

    あまり攻撃がどういうものが認識できていないのですが、
    例えば下のコードのような場合、
     「new Function(code)codeのみに攻撃ができて、その他の場所(例えばlet count = 0のような場所)には攻撃ができない」
    などということは実際に起こり得るのでしょうか?

    重ねての質問となってしまいますがご回答よろしくお願いします

例えば以下のような攻撃が可能です。

const secret_login_token="hogehoge";

const code = "alert(secret_login_token)";  // なんらかの手段で、攻撃者が実行させようとするコードが文字列として混入されてしまった

const f = Function(code);
f(); // それをFunctionで評価して実行する箇所があると、secret_login_token変数の中身が表示されてしまう。
1Like

Comments

  1. @Sei2423

    Questioner

    @culage
    ご回答ありがとうございます

    もしFunction(code)のように変数を介してではなく、 Function("alert(secret_login_token)")のように直接的に記述していれば攻撃されることはなくなりますか?

    重ねての質問で申し訳ありません。

Your answer might help someone💌