2

渡されたパラメーターとして$sortを使用していない限り、ソートが機能する理由がわかりません。以下の例は、並べ替えに使用できます。

$sort = "quantity desc";

$sql = " with items as (
SELECT i.[item_id]
,i.[name]
,i.[value]
,i.[quantity]
,i.[available]
,isnull(r.awarded, 0) as awarded
, ROW_NUMBER() OVER(
  ORDER BY $sort
) rowNumber 
FROM [Intranet].[dbo].[Goodwell_Item] i
LEFT JOIN (
SELECT r.item_id
, COUNT(1) awarded 
from [Intranet].[dbo].[Goodwell_Reward] r
group by r.item_id
) as r
ON i.item_id = r.item_id
)
SELECT * 
FROM items 
WHERE rowNumber BETWEEN (?) and (?)
and ( (?) = '' OR (available = (?)))
";

$params = array( $pagify['startFrom'], $end, $available, $available );

$stmt = sqlsrv_query( $conn, $sql, $params );

ただし、ORDERBYの行を次のように変更すると次のようになります。

ORDER BY (?)

そしてそれを私の$paramsに次のように追加します:

$params = array($sort, $pagify['startFrom'], $end, $available, $available );

その後、何らかの理由でソートが無視されます。

SQLインジェクションを許可しない方法でソートを機能させる方法を教えてください。

4

1 に答える 1

0

私は今まさにこの問題に取り組んでおり、オンラインで役立つものを見つけることができません。

私が試してみました:

 $query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? ";
 $result = $conn->getData($query, array($seriesID,$sortBy));

$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? ?";
$result = $conn->getData($query, array($seriesID,$sortBy,$sortOrder));

どちらの場合も、エラーも結果もありません。

これを安全に解決する唯一の方法は、クエリの前に switch ステートメントを使用して、許容値を手動で検証することだと思います。ただし、1 つのテーブルだけを扱っている場合を除き、SortBy 列の可能な値を知ることはできません。

ただし、この時点での値が既にクリーンアップされているという仮定だけを使用する場合は、次のようにパラメーター化されていないバージョンを使用できます。

 $query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY " . $sortBy . " " . $sortOrder;
 $result = $conn->getData($query, array($seriesID));

私が計画しているのは、このコードを含むメソッドに渡す前に、sortBy と sortOrder を検証することです。このようにすることで、コードを呼び出す各場所が、データを送信する前に検証する責任を負います。呼び出し元のコードは、呼び出しているテーブル (この場合はビュー) の有効な可能な値を知っています。(この場合、私は両方のコードの作成者なので、安全であることはわかっています。)

要するに、コードのこの時点での値がすでにクリーンで安全であることを確認し、その責任をこのコードを呼び出すコードの 1 レベル上に押し上げます。

于 2015-02-04T21:19:54.037 に答える