私のウェブサイトで小さなプログラミングパズルを作りたいです。タスクがあります。ユーザーは、ソリューションを含むC++ソースファイルをアップロードするよう求められます。ファイルはコンパイルされ、何らかの入力で実行され、正しい出力を生成するかどうかが確認されます。セキュリティ上のリスクは何ですか?アップロードされたファイルが悪意のあるものを実行できないようにするにはどうすればよいですか?
また、C++コードをコンパイルして実行できる Tutorials Point のようなサイトもあります。彼らはどのようにセキュリティを管理していますか?
プログラムを分析して、悪意のある動作をするかどうかを調べることはできません。これは、ソースコードとコンパイル済みコードのどちらを分析しようとしているかに関係なく当てはまります。
あなたが求めていることを行う方法は、サンドボックスでコードをコンパイルして実行することによって行われます。プログラムが終了したら(またはタイムアウト後に決めた)サンドボックスを破棄します。
このような構造のセキュリティは、使用しているサンドボックスと同じくらい安全です。サンドボックスを実行するために必要なコードの要件に応じて、Linuxセキュアコンピューティングモードのような単純なものでも、本格的な仮想マシンのような複雑なものでも(理想的にはネットワーク接続なしで)できます。
サンドボックスが複雑になるほど、サンドボックスのセキュリティの脆弱性が高まり、それ以外の点では優れた設計が損なわれるリスクが大きくなります。
一部の言語は、サンドボックスの外部で安全にコンパイルできます。しかし、それらをコンパイルしても予測できない量のリソースを消費する可能性がある言語があります。これは姉妹サイトの question で、小さなソースコードが大きな出力に膨らむ例を示しています。
コンパイラ自体に脆弱性がない場合、CPU、メモリ、およびディスクスペースが消費できる量に制限を設定するだけで十分な場合があります。セキュリティを高めるために、仮想マシン内でコンパイラを実行できます。
もちろん、これらの方法を組み合わせて、セキュリティをさらに強化することができます。そのようなシステムを構築する場合、仮想マシンを起動し、仮想マシン内でulimitを使用して、コンパイラーのリソース使用を制限します。次に、コンパイルされたコードをラッパーにリンクして、セキュアコンピューティングモードで実行します。最後に、仮想マシン内で、リンクされた実行可能ファイルを実行します。
これは本当に難しい問題であり、すべてのオンラインコードジャッジが解決しなければならない問題の1つです。基本的に、あなたはあなたのマシンで任意のコードを実行できる誰かがそれを乗っ取ることを防ぐ方法を尋ねています。
私は10年ほどオンライン裁判官( Kattis )をコーディングしてきました。この種のシナリオのセキュリティソリューションを構築した経験の一部を以下に示します。
Dockerや仮想マシンなどのコンテナーは人気がありますが、この種のシナリオでは、セキュリティソリューションに最適な選択ではない場合があります。おそらく必要な細かい制御とリソースの監視を取得することは困難です。悪意のあるプロセスがコンテナーの内部でねじ込まれるのを防ぐことは困難であり、コンテナーの起動と破棄には多くのオーバーヘッドがあります。
パズルのウェブサイトの特定のケースでは、代替案を検討してください:気にしないでください。信頼できないコードを実行する必要がないように、出力をアップロードするよう参加者に依頼します。これにより、計算能力が節約され、セキュリティリスクが回避され、人々はあらゆる言語で競争することができます。懸賞がかかっている場合は、後で手動で入賞を確認できます。
パズルの形式が許せば、ランダムな入力を生成して検証を書くことで、コピーアンドペーストのソリューションを挫折させることができます。これがGoogle Code Jamの仕組みです。 https://code.google.com/codejam/problem-preparation.html#iogen を参照してください