@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

4Answer

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

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

2Like

Comments

  1. @Sei2423

    Questioner

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

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

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

  2. @Sei2423
    そうだったんですね。(最初からそう言って欲しいです...)
    であればそこまでリスクは大きくないですが、
    現在はevalが有効であること自体がリスクで、
    evalを無効化する方法が存在したりします。

    そしてevalを使うと最適化が難しくなり速度が遅くなるので、
    難読化をするよりそのまま書く方が良いのではないでしょうか。

  3. eval等を難読化に使えるか

    使える/使えないで言えば使えるだろうけど、なんのために使うの?とは思う。
    一般的な難読化ではダメで、evalを使いたい理由を説明してもらえると生産的な議論が出来るかも。
    evalは速度等のセキュリティ以外の問題もあるので、積極的に使うものではなくどうしてもevalじゃないといけないだ、という場合に使うもの。

  4. @Sei2423

    Questioner

    @TNTSuperMan

    evalが有効であること自体がリスクなんですね、、、、
    evalによる難読化はいろいろ問題がありそうですね

    ありがとうございました。

  5. @Sei2423

    Questioner

    @midoribi

    なんのために使うの?

    バックエンドを使用せずにコードをできる限り隠したく思ったためです。

    ただ、動作速度やセキュリティ面ともに厳しそうなのでWebAssemblyとかにコンパイルした方がよさそうですね、、、

  6. @Sei2423

    Questioner

    今回この質問をさせてもらった意図としては、
    ・難読化をしたかった
    ・なぜevalが危険なのかを理解しておきたかった
    ・情報を鵜吞みにしたくなかった
    等の理由です。

    丁寧なご回答ありがとうございました。

  7. サーバを使用せずに、秘密情報をクライアントブラウザで処理するのは、JS、WebASMともに、危険です。手元のコンピュータののCPUで実行される以上、どんなに頑張っても「絶対」はありません。
    というのも、デバッガなどを使われれば、たとえば暗号化キーや、APIキーなどはすぐバレてしまいます。難読化の度合いにもよりますが、たとえばBASE64したコードを実行するなどは、もってのほかです。
    また、通信の解析もブラウザ搭載のデバッガでできてしまうので、それも意識する必要があります。
    ちょっと隠したい、程度の要求であればいいのですが、おっしゃる話を聞くと、方針から変えた方が良いと提言します。

  8. @Sei2423

    Questioner

    @mipsparc

    本当に隠し通す必要のあるほどの秘密情報ではなく、あんまり見られたくないし見られたら面白くないなという位の情報です。
    ただ確かにサーバーサイドで実行する方がいいかもしれないですね、、、

    ご回答ありがとうございました。

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)")のように直接的に記述していれば攻撃されることはなくなりますか?

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

  2. Function("alert(secret_login_token)")のように直接的に記述していれば攻撃されることはなくなりますか?

    任意のコードが実行される攻撃されなくなりますが、それなら文字列で指定せずに普通にコードを書けばいいので、そのような書き方をする意味はないですね。

  3. @Sei2423

    Questioner

    @culage

    世間で一般的に危険と言われいている理由が気になっていたので助かりました。
    ありがとうございました

フェッチの扱いがあり、そこから何かしらの情報を受け取るなら危険性は増します。

eval、Functionを使用した際の危険性の違い

形式以外にリスクの違いはありません。

わざわざリスクをおってまでeval()Function()を使おうという考えが危ないです。

0Like

Comments

  1. @Sei2423

    Questioner

    @STSynthe
    ご回答ありがとうございます。
    evalを使わないと出来ないちょっとした事があったのですが、使いたくないためどうしようか迷っていたため質問させていただきました

  2. @Sei2423
    なるほど事情があるのですね。

    迷ってるならevalを使わない回避方法が無いかアイデアを募るような質問の仕方が良いかもしれません。
    今の質問では似たような回答しか飛んでこないかと。

Your answer might help someone💌