入力の検証や表現の問題は、メタキャラクター、代替エンコーディング、数値表現などによって引き起こされます。セキュリティの問題は、入力を信頼することに起因します。この問題に含まれるのは、「Buffer Overflow」、「Cross-Site Scripting」攻撃、「SQL Injection」などです。
...
String address = request.getParameter("address");
Properties props = new Properties();
props.put(Provider_URL, "rmi://secure-server:1099/");
InitialContext ctx = new InitialContext(props);
ctx.lookup(address);
...
string name = Request["username"];
string template = "Hello @Model.Name! Welcome " + name + "!";
string result = Razor.Parse(template, new { Name = "World" });
...
operation
パラメーターが悪意のない値、たとえば "John" (この場合は result
変数に "Hello World!Welcome John!" の値が割り当てられる) などの場合に正しく動作します。しかし、攻撃者が有効かつ悪意のある言語操作を指定した場合、指定された操作は親プロセスの完全な権限で実行されます。このような攻撃は、基盤となる言語によってシステムリソースにアクセスできる場合や、システムコマンドの実行が認められている場合に、より危険性が高まります。たとえば、RazorでC#オブジェクトの呼び出しが可能です。攻撃者がname
の値として" @{ System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.EnableRaisingEvents=false; proc.StartInfo.FileName=\"calc\"; proc.Start(); }"を指定した場合、ホストシステムではシステムコマンドが実行されます。
...
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
userOps = request.getParameter("operation");
Object result = scriptEngine.eval(userOps);
...
operation
パラメーターが「8 + 7 * 2」などの悪意のない値である場合、プログラムは正しく動作します。この場合、result
変数には値 22 が割り当てられます。しかし、攻撃者が有効かつ悪意のある言語操作を指定した場合、指定された操作は親プロセスの完全な権限で実行されます。このような攻撃は、基盤となる言語によってシステムリソースにアクセスできる場合や、システムコマンドの実行が認められている場合に、より危険性が高まります。たとえば、JavaScript で Java オブジェクトの呼び出しが可能です。攻撃者が operation
の値として " java.lang.Runtime.getRuntime().exec("shutdown -h now")" を指定すると、ホスト システムで shutdown コマンドが実行されます。
...
userOp = form.operation.value;
calcResult = eval(userOp);
...
operation
パラメーターが「8 + 7 * 2」などの悪意のない値である場合、プログラムは正しく動作します。この場合、calcResult
変数には値 22 が割り当てられます。しかし、攻撃者が有効かつ悪意のある言語操作を指定した場合、指定された操作は親プロセスの完全な権限で実行されます。このような攻撃は、基盤となる言語によってシステムリソースにアクセスできる場合や、システムコマンドの実行が認められている場合に、より危険性が高まります。JavaScript の場合、攻撃者はこの脆弱性を利用してクロスサイト スクリプト攻撃を実行できます。
...
strUserOp = Request.Form('operation')
strResult = Eval(strUserOp)
...
operation
パラメーターが"8 + 7 * 2" である例に示されます。strResult
変数は、値 22 を戻します。しかし、ユーザーが有効なそのほかの言語操作を指定する場合、それらの操作は実行されるだけでなく、親プロセスの完全な権限で実行されます。基礎となる言語によってシステムリソースにアクセスできる場合やシステムコマンドの実行が認められている場合、任意のコード実行がもたらす危険性はより高まります。たとえば、攻撃者が operation
に " Shell('C:\WINDOWS\SYSTEM32\TSSHUTDN.EXE 0 /DELAY:0 /POWERDOWN')" を指定した場合、ホスト システムでは shutdown コマンドが実行されます。Delegate
フィールドによって、そのクラスのデシリアライズ以降に任意のコード実行の脆弱性が生じるおそれがあります。Delegate
タイプは、ユーザー コードで後に呼び出し可能なメソッド コールへの参照を保持するために使用されます。.NET では、Delegate
タイプのシリアライズ時にカスタム シリアライズを使用し、System.DelegateSerializationHolder
クラスを使用して Delegate
にアタッチまたはサブスクライブされたメソッド情報を保存します。そのため、シリアライズされた Delegate
オブジェクトのストリームは、永続的な保管やリモート アプリケーションへの転送には適していません。これは、攻撃者がそのメソッド情報を、悪意のあるオブジェクト グラフを参照する情報に置き換えることができ、それによってデシリアライズ以降の呼び出し時に任意のコード実行の脆弱性が生じる可能性があるためです。Delegate
フィールドが含まれ、Executor
メソッドで呼び出されています。
...
[Serializable]
class DynamicRunnner
{
Delegate _del;
string[] _arg;
public DynamicRunnner(Delegate dval, params string[] arg)
{
_del = dval;
_arg = arg;
}
public bool Executor()
{
return (bool)_del.DynamicInvoke(_arg);
}
}
...
Example 1
に記述されたクラスの信頼できないストリームをデシリアライズすると、攻撃者がそのメソッド情報を Process.Start
を参照する情報に置き換え、Executor
メソッドがコールされたときに任意のプロセスが作成されます。BeanUtilsHashMapper
を使用して Redis ハッシュをデシリアライズし、攻撃者がこのようなハッシュを制御して任意のコードを実行できるようにします。
HashMapper<Person, String, String> hashMapper = new BeanUtilsHashMapper<Person>(Person.class);
Person p = hashMapper.fromHash(untrusted_map);
EnableViewStateMac
プロパティの設定は、アプリケーションでのリモート コード実行の脆弱性の原因になるため、無視されます。ただし、開発者は aspnet:AllowInsecureDeserialization
設定によってこの機能を上書きすることで、アプリケーションをリモート コード実行に対して脆弱になるようにすることができます。aspnet:AllowInsecureDeserialization
が true
に設定されています。
<appSettings>
<add key="aspnet:AllowInsecureDeserialization" value="true" />
</appSettings>
Low
と Full
の 2 つのレベルの自動デシリアライズを提供します。デフォルト値の Low
は、リモーティングインフラストラクチャタイプの自動デシリアライズ、限定されたシステム実装タイプのセット、カスタムタイプの基本セットなど、最も基本的なリモーティング機能に関連付けられたタイプのみをデシリアライズすることにより、デシリアライズ攻撃に対する保護を提供します。Full
のデシリアライズ レベルは、リモーティングがすべての状況でサポートするすべてのタイプの自動デシリアライズをサポートします。typeFilterLevel
が Full
に設定されています。
<system.runtime.remoting>
<application>
<channels>
<channel ref="tcp" port="2000">
<serverProviders>
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
<clientProviders>
<formatter ref="binary"/>
</clientProviders>
</channel>
</channels>
</application>
...
</system.runtime.remoting>
TestService
メソッドを公開する RMIServiceExporter。例 2:
<bean id="testService" class="example.TestServiceImpl"/>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="TestService"/>
<property name="service" ref="testService"/>
<property name="serviceInterface" value="example.TestService"/>
<property name="registryPort" value="1199"/>
</bean>
TestService
メソッドを公開する JMSInvokerServiceExporter。例 3:
<bean id="testService" class="example.TestServiceImpl"/>
<bean class="org.springframework.jms.remoting.JmsInvokerServiceExporter">
<property name="serviceInterface" value="example.TestService"/>
<property name="service" ref="testService"/>
</bean>
TestService
メソッドを公開する HTTPInvokerServiceExporter。
<bean id="testService" class="example.TestServiceImpl"/>
<bean class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="serviceInterface" value="example.TestService"/>
<property name="service" ref="testService"/>
</bean>
The pickle module is not intended to be secure against erroneous or maliciously constructed data. Never unpickle data received from an untrusted or unauthenticated source.
__reduce__
メソッドを定義することによってデシリアライズする方法を宣言できます。このメソッドは callable
およびその引数を戻します。Pickle は、攻撃者が任意のコマンドを実行することを可能にする、新しいオブジェクトを構築するために指定された引数と一緒に関数を呼び出します。