$db = JFactory::getDBO();
$searchP = JRequest::getVar('key');
$sql = "SELECT name FROM people LIKE " . "'%" . $searchP . "%'";
$db->setQuery($sql);
$fileR = $db->loadObjectList();
同じ文字列に2つのSQLステートメントがあると、setQuery()はエラーをスローしますか?
たとえば、私のコードによると、次のクエリパラメータまたは同様のものを渡すことにより、テーブルの削除コマンドを実行できます。
key=a'; DROP TABLE people; #
さらに次のようなものを使用します
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query ->setLimit('1');
$query ->select($db->quoteName('name'));
$query ->from($db->quoteName('people'));
$query ->like($db->quoteName($searchP));
$db->setQuery($query);
クエリオブジェクトのクエリ制限が1に設定されているため、インジェクションを防止しますか?
quote()
(またはq()
)とquoteName()
(またはqn()
)を使用する場合、SQLインジェクション攻撃について心配する必要はありません。メソッドを適切に。
から https://docs.joomla.org/Secure_coding_guidelines#Secure_on_search
安全な検索
ワイルドカード文字%を含むLIKE句には、サービス拒否攻撃の可能性を回避するために特別なエスケープが必要になるため、特に注意が必要です。 LIKE句は次のように処理できます。
//ユーザーが指定した文字列をエスケープし、必要に応じて手動で%ワイルドカード文字を追加して、検索語を作成します。
_$search = '%' . $db->escape( $search, true ) . '%' );
_// SQLクエリを作成します。ダブルエスケープを防ぐために、Quoteのデフォルトの動作を抑制します。
_$query = 'SELECT * FROM #__table WHERE `field` LIKE ' . $db->quote( $search, false );
_
->like()
は、私が調査した限りでは存在しません。したがって、上記のドキュメントの推奨事項に基づいて、name
列を検索することを想定して、次のコードブロックを提案します。
_$db = JFactory::getDBO();
$query = $db->getQuery(true)
->select($db->qn('name'))
->from($db->qn('people'))
->where($db->qn('name') . ' LIKE ' . $db->q('%' . $db->escape($searchP, true) . '%', false));
$db->setQuery($query);
_
LIKE
クエリを実行する場合、結果セットで複数行のデータを受け取るのが論理的であることがよくあります。セキュリティ対策としてsetLimit()
メソッドを使用していたと思いますので、クエリを改善するために削除します。
inf3rnoのコメント の記述にかかわらず、 最新のドキュメント によるbind()
メソッドはありません。 (私はとにかく_:needle
_と_?
_の両方をプレースホルダーとして使用してスニペットをテストし、受信しました:致命的なエラー:nullのメンバー関数bind()への呼び出し) Joomla-landに入る前に、クエリに供給されるすべての外部/信頼できないデータのプレースホルダーを備えた準備されたステートメントを使用するので、この方法でなかったらいいのにと思います。
2014年のLodderからの関連記事 Joomlaで準備されたステートメントについて。
上記のコードブロックのquote(escape())メソッドの目的/効果は、クエリに渡される文字列に関係なく、文字列が常に式の単一の値として扱われるようにすることです。これはmysqli_real_escape()
と同等のようです(ただし、Joomlaの内部では確認していません)。残念ながら、多くのStackOverflow開発者はmysqli_real_escape()
に次善のフラグを立て、代わりにプレースホルダーを使用した準備済みステートメントを推奨しています。 bind()
メソッドが利用可能になり次第、すべてのJoomlaプロジェクトを更新します。
Joomla 3.8.6で次のテストを実行しました。
_$needle = "key=a'; INSERT INTO [... redacted query that would be successful on its own ...]; #";
try {
$db = JFactory::getDbo();
$sql = "SELECT [redacted] FROM [redacted] WHERE [redacted] LIKE " . "'%" . $needle . "%'";
$db->setQuery($sql);
var_export($db->loadAssocList());
} catch (Exception $e) {
echo $e->getMessage();
}
_
そして受け取った:
1064 SQL構文にエラーがあります。 MySQLサーバーのバージョンに対応するマニュアルで、 'INSERT INTO'の近くで使用する正しい構文を確認してください
これは、JoomlaのsetQuery()
メソッドが複数のクエリで窒息することを示しています。