2008-12-16 3 views
9

주제가 제시 한대로 .NET을 사용하여 매개 변수로 테이블 이름을 전달할 수 있기를 원합니다 (실제로 언어는 중요하지 않음). SQL Server..NET/SQL의 Parameterise 테이블 이름?

값에 대해이 작업을 수행하는 방법을 알고 있습니다. command.Parameters.AddWithValue("whatever", whatever)@whatever을 쿼리에 사용하여 매개 변수를 나타냅니다. 것은 내가 열 및 테이블 이름과 같은 쿼리의 다른 부분으로이 작업을 수행 할 수 있기를 바란다.

이것은 이상적인 상황은 아니지만 코드를 사용하는 사람 만 최종 사용자가 아닌이 테이블 이름을 설정할 수 있기 때문에 SQL 인젝션에 취약하지 않습니다. 그러나 그것은 지저분하다.

그래서 내가 원하는 것은 무엇입니까?

편집 : SQL 주입에 대한 요점을 없애기 위해 테이블 ​​이름은 상황에 따라 소스 코드에 의해서만 전달됩니다. 이것을 지정하는 개발자입니다. 어쨌든 개발자는 데이터베이스 계층에 대한 액세스 권한을 가지므로 보안을 위해 많은 것을 요구하지는 않지만 코드를보다 명확하게 작성해야합니다.

답변

3

나는 을 생각한다. 내가 본 모든 SQL 언어에서이 기능을 본 적이있다. 그러나 전문 분야는 아니다.

문자를 AZ, az, 0-9, '.', '_'및 ''-로 제한 한 다음 데이터베이스에 적절한 브라케팅을 사용하는 것이 좋습니다 (예 : [] for SQL Server, I 믿는다). 그런 다음 바로 SQL에 배치하십시오.

SQL 주입 위험이 아니라는 것을 의미하는 것이 명확하지 않습니다. 이름이 소스 코드와 소스 코드에만 있다는 의미입니까? 그렇다면 일을 더 잘하는 데 동의합니다. (개발자가 고의적이든 아니든)으로 개발자를 신뢰하는 경우 자동으로 브라케팅을 수행 할 필요조차 없습니다.

+0

넵, 소스 코드 및 소스 코드에서만. 이 작업을 리팩토링하는 동안 업데이트/삽입 문을 작성하는 것이 더 쉬운 작업입니다. – Damien

4

다른 매개 변수처럼 테이블 이름을 매개 변수로 전달할 수 있습니다. 핵심은 동적 SQL 문을 작성해야한다는 것입니다. 그러면 응용 프로그램 계층 또는 procs에 SQL 문을 작성하는 것이 더 쉬운지 고려해야합니다.

create procedure myProc 

@tableName nvarchar(50) 

as 

sp_executesql N'select * from ' + @tablename 

fyi이 코드 샘플은 메모리에서 sp_executesql의 올바른 구문에 대해 살펴 봅니다.

또한 SQL 인젝션을하는 데 매우 어렵습니다. 문제는 아니지만이 글을 읽는 사람은 누구나 이와 같은 쿼리를 생성하기 위해 입력을 받아들이는 것을 매우 조심해야합니다.

+0

'* from'+ @tablename을 선택하겠습니까? 그 다음에는 매개 변수가 있습니까? (저장 프로 시저가 아닌 VB.Net 코드 사용). – Damien

+0

vb.net에서 쿼리를 작성하면 @table을 매개 변수화 할 필요가 없습니다. 귀하의 VB 코드는 sqlString = "select * from"+ tableName처럼 보일 것입니다. 그런 다음 sqlString을 명령 객체를 사용하여 실행합니다. (명령 유형을 텍스트로 설정) – JoshBerke

3

SQL 쿼리 매개 변수는 리터럴 값 대신 사용할 수 있습니다. 테이블 이름, 열 이름, 값 목록 또는 다른 SQL 구문에 매개 변수를 사용할 수 없습니다. 이는 모든 브랜드 데이터베이스에서 표준 SQL 동작입니다.

테이블 이름을 동적으로 만드는 유일한 방법은 해당 문자열을 문으로 준비하기 전에 SQL 쿼리에 변수를 삽입하는 것입니다.

그렇다면 SQL 주입의 위험이 없다고 생각하면 속일 수 있습니다. 테이블 이름을 동적으로 쿼리에 삽입하는 경우 변수에서 보간 된 문자열 리터럴 주위의 따옴표를 사용하는 것처럼 테이블 이름을 중심으로 delimited identifiers을 사용해야합니다.

5

테이블 이름을 직접 매개 변수화 할 수 없습니다.sp_ExecuteSQL을 통해 간접적으로 수행 할 수 있지만 C# (테이블 이름은 연결하지만 다른 값은 연결하지 않음)에서 (매개 변수가있는) TSQL을 작성하여 명령으로 전송할 수 있습니다. 동일한 보안 모델 (예 : 명시적인 SELECT 등이 필요하며 서명되지 않았다고 가정).

또한 테이블 이름을 반드시 화이트리스트해야합니다.

2

SQL 삽입에 취약하지 않다는 생각은 잘못되었습니다. 프런트 엔드 사용자로부터 덜 SQL 인젝션 경향이 있지만 여전히 SQL 인젝션을하는 경향이 있습니다. 데이터베이스에 대한 대부분의 공격은 최종 사용자가 아니라 공격받는 회사 내부에서 발생합니다.

직원은 원한을 가질 수있다, 그들은 부정직 할 수있다, 그들은 불만 될 수도 있고 너무 밝은하지하고 그것이 그들이 생각 이 짓을해야한다는 것입니다 무엇이든 할 우회 보안에 대한 확인 있다고 생각

데이터 베이스.

+0

나는 이것을 말할 것이고, 대신에 투표했다. 매개 변수가 하드 코드 된 선택 사항이 아니라면이 방법은 바람직하지 않습니다. –

+3

글쎄, 회사의 사람들도 액세스 할 수 없었을 것입니다. 필드 및 테이블 이름을 지정할 수있는 것은 호출하는 메소드뿐입니다. 실제로, 비즈니스 로직에 액세스 할 수있는 사람은 누구나 데이터 액세스 코드에도 액세스 할 수 있습니다. – Damien

0

사용자 Vimvq1987에 의해이 게시물 대답을 참조하십시오 MySqlParameter as TableName

는 기본적으로 먼저 테이블 이름이 파라미터 방식으로 사용되는 스키마에 테이블 이름을 확인합니다. 그런 다음 모두 괜찮 으면 표 이름이 적합합니다.

인용 함 기본적인 아이디어는 다음과 같습니다

SELECT table_name 
    FROM information_schema.tables 
    WHERE table_schema = 'databasename' 
    AND table_name = @table; 

    cmd.Parameters.AddWithValue("@table",TableName); 

이 테이블 이름, 메인 쿼리와 진행에 확인을 반환하면 ...

0

난 그냥 아이디어를 방지하는 것입니다 select OBJECT_ID(@tablename) 을 확인할 것 injection 당신이 테이블 이름을 가지고 있다는 것을 알고 있습니다. 이것이 숫자를 반환한다면 실제 쿼리를 실행할 것입니다.