2009-03-25 2 views
25

저는 회사 인트라넷에 작은 설문 조사 웹 페이지를 만들었습니다. 이 웹 페이지는 외부에서 액세스 할 수 없습니다.INSERT시 SQL 삽입

양식은 단순히 몇 개의 라디오 버튼과 설명 상자입니다.

나는 좋은 코딩 방법을 유지하고 싶습니다. 그리고 SQL Injections에 대해 경계하고 싶습니다.

텍스트 삽입 주석문이있는 삽입 문에서 SQL 삽입을 실행할 수 있습니까? 그렇다면 .NET 2.0을 사용하여 어떻게 방지 할 수 있습니까?

+0

추가 정보 : 웹 페이지를 작성할 때 SQL 삽입에만 집중하지 마십시오. 텍스트를 데이터베이스에 삽입하기 전에 텍스트의 XSS 위험을 확인하십시오. Server.HtmlEncode (...)를 통해 모든 출력 코드를 보호합니까? –

답변

54

주입이 모든 SQL 문에서 올바르게 실행되지 않을 때 발생할 수 있습니다.

예를 들어, 댓글 테이블에 정수 ID와 댓글 문자열이라는 두 개의 필드가 있다고 가정 해 보겠습니다. 그냥 어떤 processesing없이 SQL에 주석 문자열을 넣으면이에 당신의 단일 INSERT를 돌 수 있었다

'); DELETE FROM users; -- 

:

INSERT INTO COMMENTS VALUES(122,'I like this website'); 

는 다음과 같은 코멘트를 입력하는 사람을 생각해 다음과 같이 그래서 당신은 INSERT을 거라고 다음 두 문장에 주석이옵니다.

INSERT INTO COMMENTS VALUES(123,''); DELETE FROM users; -- '); 

이렇게하면 users 테이블의 내용이 모두 삭제됩니다. 시행 착오와 다양한 트릭을 사용하여 하루 종일 올바른 tablename을 비우는 데 기꺼이 쓰는 사람들이 있습니다. Here's a description of how you could perform an SQL Injection attack.

이 문제를 방지하려면 parameterized SQL statements을 사용해야합니다.

그리고 이것은 보안상의 이유로 만있는 것이 아닙니다. 당신은 순진 다음 주석을 SQL 문을 만드는 경우 예를 들어, :

I'm just loving this website 

는 닫는 따옴표로 SQL에 의해 해석되고 있기 때문에 아포스트로피의 SQL 구문 오류가 발생합니다.

+2

아포스트로피의 멋진 점 - string.replace 메서드를 사용하고 있습니다. 그러나이 방법이 훨씬 쉽습니다. – Brad

+0

매우 잘 설명되어 있습니다. 잘 했어. –

+1

O'Tool, O'Rourke와 같이 매개 변수로 사용하지 않으면 이름조차도 문제가됩니다. – Martin

27

텍스트가 자동으로 인용되도록 매개 변수가있는 쿼리를 사용하십시오.

SqlCommand command = connection.CreateCommand(); 
command.CommandText = "insert into dbo.Table (val1,val2,txt) values (@val1,@val2,@txt)"; 
command.AddParameterWithValue("val1", value1); 
command.AddParameterWithValue("val2", value2); 
command.AddParameterWithValue("txt", text); 

... 
-4

이러한 형태의 SQL 삽입을 방지하는 가장 쉬운 방법은 실행할 SQL 문을 작성하는 대신 매개 변수와 저장 프로 시저를 사용하는 것입니다. (C# 또는 SQL Server 내부).

그러나 내부적으로 발생하는 가능성이 극히 적기 때문에 회사 정책이 아니라면이 시간을 많이 보내야한다고 확신하지는 못합니다. 그것이 누구인지 즉시 알 수 있습니다.

+0

물론 불만을 품은 직원은 절대로 회사 데이터베이스를 사용하지 않을 것입니다. 항상 보안에 대해 걱정하고 모범 사례를 따라야합니다. – tvanfosson

+0

나는 동의하지 않는다. 내부 웹 페이지로 전직 직원이 액세스 할 수 없어야합니다. 또한 모든 내부 트래픽이 기록된다는 것을 추측 할 수 있습니다. 보안 요구 사항은 다른 critiera와 함께 평가되어야하며 여러 상황에서 정당화 될 수 없습니다. – Bravax

+0

누가 당신이 불만을 표하기 위해 전직 직원이되어야한다고 말합니까? 좋은 보안은 손상을 방지하고 나중에 책임을 부여하지 않습니다. 이 경우 매개 변수가있는 쿼리를 사용하는 데 드는 비용은 그리 높지 않습니다. 수작업으로 쿼리를 구성 할 때 표준이되어야합니다. – tvanfosson

0

예, 가능합니다.의 클라이언트이 보내는 가정 해 봅시다 :

당신은

+0

질문은 명시 적으로 INSERT 문에 관한 것입니다. –

+0

참. 그러나 어쩌면리스트가 도움이 될 것입니다. – boj

0

예, 그러한 일이 발생할 수 있습니다. 이것을 막는 가장 쉬운 방법은 수동으로 SQL을 작성하는 대신 준비된 명령문을 사용하는 것입니다.

그래서, 오히려 이것보다 :

String sql = 
String.Format("INSERT INTO mytable (text_column) VALUES ('{0}')", 
    myTextBox.Text); // Unsafe! 

당신은 같은 것을 할 것입니다 :

String sql = "INSERT INTO mytable (text_column) VALUES (?)"; // Much safer 

그 다음에 원인이됩니다 DbCommand에 대한 매개 변수로 텍스트 상자의 텍스트를 추가 자동으로 이스케이프되고 "?" SQL에서. 당신은 또한해야 할 준비된 문 및 매개 변수를 사용하기보다는 당신의 SQL에 문자열을 연결하는 것 외에도

0

다음 서버 측

  1. 검증 및 형식 사용자 입력. 클라이언트 측 유효성 검사 및 제한은 WebScarab과 같은 도구를 사용하거나 양식을 스푸핑하여 쉽게 우회 할 수 있습니다.

  2. 데이터베이스 사용자 계정에 대한 적절한 사용 권한을 구성하십시오. 웹 응용 프로그램은 응용 프로그램을 실행하는 데 필요한 테이블, 뷰 및 절차로만 사용 권한이 제한된 데이터베이스에서 별도의 계정 또는 역할을 사용해야합니다. 사용자에게 시스템 테이블에 대한 선택 권한이 없음을 확인하십시오.

  3. 사용자의 자세한 오류 메시지를 숨기고 개체에 대한 일반적인 이름을 적게 사용하십시오. 오류 메시지에서 서버 유형 (oracle, mysql, sqlserver)을 확인하고 기본 스키마 정보를 찾은 다음 'user (s)', 'employee (s)'라는 테이블에서 정보를 가져 오는 빈도를 저에게 놀라게합니다. 당신은 (2)와 같이 사용 권한을 설정하지 않은 내가 서버 유형을 판별 할 수있는 경우는 information_schema.table

    FROM SELECT TABLE_NAME는 EXECUTE sp_help는이 foundTableName

    SQL Server에 대한이 같은 진술에 열려있는

3

SQL 주입은 데이터베이스에 쿼리를 다시 전달할 때마다 발생할 수 있습니다. 다음은 간단한 데모는 다음과 같습니다

SQL Injection Explained

열쇠, .NET 내에서, 데이브 웹이이 주신대로하는 것입니다. SQL Server가 쿼리를 변경하거나 추가 명령을 추가하기 위해 해석 할 수있는 모든 문자를 처리하면서 전체 문자열을 하나의 매개 변수로 포함하여 삽입 시도를 방지합니다.

그리고 SQL 주입은 웹 응용 프로그램뿐만 아니라 모든 응용 프로그램에서 발생할 수 있다는 점을 지적해야합니다. 내부 공격은 대개 조직에 가장 많은 비용이 듭니다. 하나의 공격은 내부에서 기인하지 않는다고 안전하게 추측 할 수 없습니다.

0

준비된 문을 사용하여 SQL 주입을 방지하십시오. placehoder (?)를 사용하면 sql Injection Vulnerability가 완전히 제거됩니다. 예 String sql = select user_table from username = '+ request.getparameter ("username") +'; statement.executeQuery (sql);

위의 진술은 SQL injection에 취약합니다.

SQL 삽입에 대해 안전하게하려면. 스 니펫 다음에 사용하기

String sql = select * from user_table where username =?; statement.setString (1, username);

+0

'? '구문은 모든 제공자/DB에 대해 작동하지 않습니다. –