XSS と SQL インジェクションは、サニタイズされていないユーザー入力による 2 つの主なセキュリティ リスクです。
XSS は (WYSIWYG がない場合) htmlspecialchars() を使用して防止でき、SQL インジェクションはパラメーター化されたクエリとバインドされた変数を使用して防止できます。
これら 2 つの方法を使用することで、サニタイズされていないすべての入力を安全に使用できますか?
XSS と SQL インジェクションは、サニタイズされていないユーザー入力による 2 つの主なセキュリティ リスクです。
XSS は (WYSIWYG がない場合) htmlspecialchars() を使用して防止でき、SQL インジェクションはパラメーター化されたクエリとバインドされた変数を使用して防止できます。
これら 2 つの方法を使用することで、サニタイズされていないすべての入力を安全に使用できますか?
SQL インジェクションは、コード インジェクションの広範な脅威の 1 つの例にすぎません。つまり、ユーザー入力 (またはその他の信頼できないコンテンツ) がコードとして実行される場合です。
これにはeval()などが含まれますが、他のベクトルもかなりの数含まれます。@thebod からの回答には、優れた StackOverflow スレッドへのリンクが含まれています: Exploitable PHP functions。
SQL インジェクションでさえ、パラメータやエスケープによって 100% 解決することはできません。これらの手法はどちらも、SQL 式の個々の値をサニタイズするのに役立ちます。テーブル、列、SQL キーワード、または式全体を選択するためにユーザー入力を許可する必要がある場合もあります。それらの場合、パラメーターとエスケープは役に立ちません。例:
$sql = "SELECT * FROM mytable ORDER BY $sortcolumn $asc_or_desc";
その例では、ソートする列名と方向 ( ASC
vs. DESC
) は変数に基づいています。変数は信頼できる入力から設定されましたか、それとも $_GET パラメーターが逐語的に使用されたため、SQL インジェクションの脆弱性が生じましたか?
このような場合のより良い解決策は、許可リストに登録することです。つまり、ユーザー入力を取得し、この動的クエリで許可されている列名のリストと比較し、ユーザー入力がこれらの事前定義された選択肢のいずれにも一致しない場合は、失敗するか、デフォルト値を使用します。
XSS と SQL インジェクション以外に考えられるいくつかの問題:
simplexml_load_[file|string]()
: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processingunserialize()
: http://www.exploit-db.com/exploits/22398/system()
、popen()
などによるコマンド実行strcmp()
配列を使用してバイパスするユーザー入力をどこに渡すか、およびそれをどのようにサニタイズするかによって常に異なります。たとえば、SQL 操作には常に PDO を使用します。これは、適切にエスケープしても、攻撃者は引用符なしで SQL コードを挿入できるためです。
SELECT title, content FROM cms WHERE id = 1
攻撃者はこれを次のように変更できます。
SELECT title, content FROM cms WHERE id = -1 UNION SELECT username AS title, password AS content from users LIMIT 1
この場合はintval()
、エスケープ (mysql_real_escape_string、magic_quotes、addslashes など) だけが役に立ち、まったく役に立ちません。
こちらもご覧ください: Exploitable PHP functions
これらのメソッドを使用することで、ユーザー入力の大部分はすでにサニタイズされています。さらに一歩進めたい場合は、SQL コードを実行する前に、入力に対して検証チェックを行うことができます。例として、数字が数値のみであることを確認したり、ユーザー入力の長さを確認したりします。