나는이 같은 체외 쿼리를 건물입니다 :Ecto에서 원시 SQL을 기록 할 수 있습니까?
from item in query,
where: like(item.description, ^"%#{text}%")
내가이 text
에서 SQL 주입을 허용하는 걱정. 이 문제를 해결하기 전에 실제로 쿼리가 데이터베이스로 어떻게 보내지는지보고 싶습니다.
내가 inspect the query이거나 기록 된 것을 보면 일부 SQL이 표시되지만 유효하지 않습니다. 내가 Repo.all
이 쿼리를 전달하면
{"SELECT i0.\"id\", i0.\"store_id\", i0.\"title\", i0.\"description\"
FROM \"items\" AS i0 WHERE (i0.\"description\" LIKE $1)",
["%foo%"]}
, 그것은이 기록합니다 : 예를 들어
가 쿼리를 검사하는 것은이 나에게 보여 내가 복사 psql
붙여 넣 경우
SELECT i0."id", i0."store_id", i0."title", i0."description"
FROM "items" AS i0 WHERE (i0."description" LIKE $1) ["%foo%"]
을하지만, PostgreSQL은 다음과 같은 오류 메시지를 표시합니다 :
ERROR: 42P02: there is no parameter $1
ough 체외 사실이처럼 parameterized query을 수행 할 수있다 : 그렇다면
PREPARE bydesc(text) AS SELECT i0."id",
i0."store_id", i0."title", i0."description"
FROM "items" AS i0 WHERE (i0."description" LIKE $1);
EXECUTE bydesc('foo');
, 나는 그 SQL 주입을 방지 할 생각한다. 하지만 저는 이것이 Ecto가하는 일이라고 추측합니다.
Ecto가 실행중인 실제 SQL을 어떻게 볼 수 있습니까?
"쿼리 구문은 어떤 SQL 주입이 가능하지 컴파일시에 확인합니다." Ecto가'like (item.description,^"% # {text} %")'를 컴파일하면'text'에 이스케이프가 추가되는 것을 말하고 있습니까? PostgreSQL은 미리 준비된 문장을 사용하고 있기 때문에 안전합니다. 그래서 PostgreSQL은 미리 (예를 들어) 하나의 SELECT와 DROP TABLE 뒤에 SELECT를 실행하지 않을 것입니다. –
이스케이프 처리를하지 않고 매개 변수를 사용합니다. '% foo %'는 쿼리의 일부가 아니므로 결코 쿼리에 아무것도 삽입 할 수 없습니다. 이것은 준비된 명령문에 매개 변수로서 완전히 분리되어 전달됩니다. – michalmuskala
또한 - 준비된 명령문에는 하나의 명령문 만 포함될 수 있으므로'-;와 같은 것을 추가 할 수 없습니다. DROP TABLE' - 포스트 그레스 (Postgres)는 두 개의 표현식을 하나에 넣으려고하고 있다고 bork가 말합니다. – michalmuskala