입력 및 출력

완료됨

현재 애플리케이션의 가장 일반적인 보안 취약점은 외부 원본에서 받은 데이터, 특히 사용자 입력을 올바르게 처리하지 못하는 것입니다. 항상 입력을 면밀하게 살펴보고 유효성을 검사한 후 사용해야 합니다. 가능한 공격에 대해 사용자 입력을 분석하지 못하면 데이터가 손실 또는 노출되거나, 권한이 상승하거나, 심지어 다른 사용자의 컴퓨터에서 악성 코드가 실행될 수 있습니다.

이런 상황의 비극은 이 시나리오가 해결하기 쉬운 문제라는 것입니다. 이 단원에서는 데이터를 처리하는 방법, 다시 말해서 데이터를 언제 수신할 것인지, 데이터를 언제 화면에 표시할 것인지, 나중에 사용할 수 있도록 데이터를 언제 저장할 것인지에 대해 알아보겠습니다.

입력의 유효성을 검사해야 하는 이유는 무엇일까요?

사용자가 웹 사이트에서 계정을 만들 수 있도록 인터페이스를 빌드하고 있다고 가정해 보겠습니다. 프로필 데이터에는 사이트를 방문하는 모든 사람에게 표시할 이름, 메일 및 애칭이 포함됩니다. 신규 사용자가 프로필을 만들고 몇 가지 SQL 명령이 포함된 애칭을 입력하면 어떻게 될까요? 예를 들어 악의적인 사용자가 다음과 같은 발췌 내용을 입력하면 어떻게 될까요?

Eve'); DROP TABLE Users;--

아무 생각 없이 이 값을 데이터베이스에 삽입하면 절대 실행하면 안 되는 명령을 실행하도록 SQL 문이 변경될 수 있습니다. 이 예를 “SQL 삽입” 공격이라고 하며, 사용자 입력을 제대로 처리하지 않을 때 발생할 수 있는 여러 유형의 공격 중 하나입니다. 이 상황을 해결하려면 어떻게 해야 할까요? 이 단원에서는 입력의 유효성을 검사해야 하는 시기, 출력을 인코딩하는 방법, 매개 변수가 있는 큐를 만드는 방법(위의 공격을 해결하는 방법)을 알아보겠습니다. 이러한 세 가지 기술은 애플리케이션에 입력되는 악의적인 입력을 방어하는 주요 방어 기술입니다.

언제 입력의 유효성을 검사해야 할까요?

항상 검사해야 합니다. 애플리케이션에 대한 모든 입력의 유효성을 검사해야 합니다. 여기에는 URL의 매개 변수, 사용자의 입력, 데이터베이스의 데이터, API의 데이터, 전달되는 항목 중 사용자의 조작 가능성이 있는 모든 항목이 포함됩니다. 나쁜 입력을 구체적으로 찾아야 하는 차단 목록을 사용하지 말고, 항상 “알려진 좋은” 입력만 허용하는 허용 목록 방식을 사용하세요. 목록 전체를 위험한 입력이라고 생각하기는 불가능하기 때문입니다. 방어벽을 회피할 수 없도록 이 작업을 클라이언트 쪽이 아닌 서버에서 수행하세요(또는 서버에서도 하고 클라이언트 쪽에서도 하세요). 모든 데이터를 신뢰할 수 없다고 생각하고 대부분의 일반적인 웹앱 취약점으로부터 자신을 보호해야 합니다.

ASP.NET을 사용하는 경우 프레임워크에서 클라이언트와 서버 쪽 모두에 입력의 유효성을 검사하는 훌륭한 지원을 제공합니다.

다른 웹 프레임워크를 사용하는 경우 OWASP 입력 유효성 검사 치트시트에 입력의 유효성을 검사하는 유용한 기술이 제공됩니다.

항상 매개 변수가 있는 쿼리 사용

SQL 데이터베이스는 일반적으로 데이터를 저장하는 데 사용됩니다. 예를 들어 애플리케이션은 데이터베이스에 사용자 프로필 정보를 저장할 수 있습니다. 원시 사용자 입력을 사용하여 코드에서 인라인 SQL이나 다른 데이터베이스 쿼리를 만들어 데이터베이스에 직접 전송해서는 안 됩니다. 이전에 살펴본 대로 이러한 행동은 재앙을 부릅니다.

예를 들어 다음 인라인 SQL 예제와 같은 코드를 만들지 마세요.

string userName = Request.QueryString["username"]; // receive input from the user BEWARE!
...
string query = "SELECT *  FROM  [dbo].[users] WHERE userName = '" + userName + "'";

여기서는 텍스트 문자열을 서로 연결하여 쿼리를 만들고, 사용자의 입력을 가져와서 사용자를 조회하는 동적 SQL 쿼리를 생성하겠습니다. 기억해야 할 부분은 악의적인 사용자가 이 작업을 알아차리거나 취약성을 찾기 위해 여러 입력 스타일을 시도하는 경우 심각한 문제가 발생할 수 있다는 점입니다. 대신 다음과 같이 매개 변수가 있는 SQL 문이나 저장 프로시저를 사용합니다.

-- Lookup a user
CREATE PROCEDURE sp_findUser
(
@UserName varchar(50)
)

SELECT *  FROM  [dbo].[users] WHERE userName = @UserName

이 방법을 사용하면 코드에서 안전하게 프로시저를 호출하여 userName 문자열을 전달할 수 있으며 SQL 문의 일부로 처리될까 봐 걱정하지 않아도 됩니다.

항상 출력을 인코딩

시각적으로 또는 문서로 제공하는 모든 출력을 항상 인코딩하고 이스케이프해야 합니다. 그러면 삭제 패스에서 무언가가 누락되었거나 악의적으로 사용 가능한 무언가를 코드에서 실수로 생성한 경우에 데이터를 보호할 수 있습니다. 이 디자인 원리는 모든 사항이 출력으로 표시되고 실행되어야 하는 무언가로 실수로 해석되지 않도록 합니다. 이는 “XSS(교차 사이트 스크립팅)”이라고 하는 다른 일반적인 공격 기술입니다.

XSS 방지는 일반적인 애플리케이션 요구 사항이므로, 이 보안 기술은 ASP.NET이 수행하는 다른 영역입니다. 기본적으로 모든 출력이 이미 인코딩되어 있습니다. 다른 웹 프레임워크를 사용하는 경우 OWASP XSS 방지 치트시트를 사용하여 웹 사이트의 출력 인코딩에 대한 옵션을 확인할 수 있습니다.

요약

입력 삭제 및 유효성 검사는 입력의 유효성을 보장하고 안전하게 사용 및 저장하기 위한 필수 요구 사항입니다. 대부분의 최신 웹 프레임워크는 이 작업 중 일부를 자동화할 수 있는 기능을 기본 제공합니다. 원하는 프레임워크의 설명서를 확인하고 제공된 기능을 확인할 수 있습니다. 웹 애플리케이션에서는 이러한 문제가 가장 흔히 발생하지만, 다른 유형의 애플리케이션도 그 정도로 취약할 수 있습니다. 새 애플리케이션이 데스크톱 앱이기 때문에 안전하다고는 생각하지 마세요. 다른 사용자가 앱을 사용하여 데이터를 손상하거나 회사의 평판을 손상하는 일이 없도록 계속해서 사용자 입력을 적절하게 처리해야 합니다.

지식 점검

1.

다음 중 유효성을 검사해야 하는 데이터 원본은 무엇입니까?

2.

매개 변수화된 쿼리(SQL의 저장 프로시저)는 데이터베이스와 안전하게 통신하는 방법이며, 그 이유는 다음과 같습니다.

3.

다음 중 출력 인코딩되어야 하는 데이터는 무엇인가요?