여전히 주입 공격으로부터 QUOTENAME을 사용해야합니까? 공격의 완화로 사용된다고 사이트는 말합니다.

나는 오늘 오래된 저장 프로 시저를보고 있었고 quotename입력 매개 변수를 사용하고 있음을 알았습니다 . 그것이 정확히 무엇을 알아 내기 위해 약간의 파기를 한 후에 나는 이 사이트를 가로 질러왔다 . 나는 그것이 무엇을 어떻게 사용하는지 이해하지만 SQL 주입 공격의 완화로 사용된다고 사이트는 말합니다. asp.net을 사용하여 데이터베이스를 직접 쿼리 한 앱을 개발할 때 ADO.Net 매개 변수를 사용하여 사용자 입력을 리터럴 값으로 전달하고 실제로는 저장 프로 시저에서이를 보호하는 것에 대해 걱정할 필요가 없었습니다.

나는 지금 쓰지 않는 응용 프로그램에서 사용할 저장 프로 시저를 작성하고 있으므로 절차 수준에서 주입 공격을 시도하고 보호해야합니다. quotename이를 수행하는 가장 좋은 방법이거나 새로운 기능 / 더 나은가 방법?

이 사고 패턴을 얻은 코드 ( @parm1사용자 입력 매개 변수) :

'SELECT project [Project], project_desc [Description],
        customer [Customer], cpnyid [Company]
FROM PJPROJ (nolock)
where project like ' + quotename(@parm1,'''') + '


답변

예,이 영역에서는 많은 변화가 없었으므로 quotename동적 SQL에 사용되는 SQL Server 개체 이름 (특히 외부 코드가 코드에 제공되는 경우)에 사용해야합니다. 이는 SQL 주입 완화뿐만 아니라 비표준 식별자 이름에 대해 코드가 올바르게 작동 함을 의미합니다.

이 함수는 객체 이름 (예 : 테이블, 열, 데이터베이스 이름)에만 적합합니다.

sp_executesql쿼리 문자열에 매개 변수를 연결하지 않고 매개 변수를 전달하여 다른 모든 매개 변수를 시도하고 사용 하십시오.

이 주제에 대한 결정적인 기사는 여전히 동적 SQL의 저주와 축복입니다.


편집하다. 이제 코드 '에 외부 따옴표를 추가하고 작은 따옴표를 두 배로 늘려 문자열에 삽입하기 전에 두 번째 매개 변수를 전달하는 코드를 제공했습니다 . 따옴표를 잘 사용하지 않습니다. 문자열이 128자를 초과하면 실패 (null 반환)됩니다.

문자열이 U + 02BC가 포함되어있는 경우 또한 아직 표준 아포스트로피 대신 SQL 주입 가능성을 떠날 수 다음 문자열 (위생 후에 VARCHAR에 할당 이 자동으로 정기적 아포스트로피로 변환 얻을 수 있습니다 )

이를 수행하는 올바른 방법은 쿼리를 매개 변수화 된 상태로 두는 것입니다. 그런 다음 @parm1값을sys.sp_executesql

DECLARE @Sql NVARCHAR(MAX);

SET @Sql = '
SELECT project      [Project],
       project_desc [Description],
       customer     [Customer],
       cpnyid       [Company]
FROM   PJPROJ (nolock)
WHERE  project LIKE @parm1
';

EXEC sys.sp_executesql
  @Sql,
  N'@parm1 varchar(100)',
  @parm1 = 'foobar%';