2013-03-12 3 views
0

나 인증 방법 다음에 asp.net 한 SQL 인젝션 방지 :

protected void Button1_Click(object sender, EventArgs e) 
     {    
      string s; 
      s = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; 
      SqlConnection con = new SqlConnection(s); 
      con.Open(); 
      string sqlCmd; 
      sqlCmd = "SELECT Username, UserPassword FROM Benutzer WHERE Username = @Username AND UserPassword [email protected]"; 
      SqlCommand cmd = new SqlCommand(sqlCmd, con); 
      String username = tbUsername.Text.Replace("'", "''"); 
      String password = tbPassword.Text.Replace("'", "''"); 
      cmd.Parameters.AddWithValue("Username", username); 
      cmd.Parameters.AddWithValue("Password", password); 
      string CurrentName; 
      CurrentName = (string)cmd.ExecuteScalar(); 
      if (CurrentName != null) 
      { 
       Session["UserAuthentication"] = cmd.Parameters[0].ToString(); 
       Session.Timeout = 1; 
       Response.Redirect("Default.aspx"); 
      } 
      else 
      { 
       lblStatus.ForeColor = System.Drawing.Color.Red; 
       lblStatus.Text = "Benuztername/Password ungültig!"; 
      } 
     } 

는 SQL 주입을 방지하기 위해이 충분? 나는이 같은 직접 명령에 단지 사용자 이름과 암호에 사용 :

sqlCmd = "SELECT Username, UserPassword FROM Benutzer WHERE Username ='" + username + "' AND UserPassword ='" + pwd + "'"; 
사용자 이름과 비밀번호가 그냥 문자열 변수가있는 사용자 이름과 암호 텍스트 상자의 내용이 저장된

...

편집 :

내가 내 코드를 편집 한 확인 지금처럼 보이는 :

protected void Button1_Click(object sender, EventArgs e) 
     { 
      SqlConnection objcon = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()); 
      SqlDataAdapter objda = new SqlDataAdapter("[MembershipPruefen]", objcon); 
      objda.SelectCommand.CommandType = CommandType.StoredProcedure; 
      objda.SelectCommand.Parameters.Add("@Username", SqlDbType.VarChar).Value = tbUsername.Text; 
      objda.SelectCommand.Parameters.Add("@UserPassword", SqlDbType.VarChar).Value = tbPassword.Text; 
      objcon.Open(); 
      string CurrentName; 
      CurrentName = (string)objda.SelectCommand.ExecuteScalar(); 
      if (CurrentName != null) 
      { 
       Session["UserAuthentication"] = tbUsername.Text; 
       Session.Timeout = 1; 
       Response.Redirect("Default.aspx"); 
      } 
      else 
      { 
       lblStatus.ForeColor = System.Drawing.Color.Red; 
       lblStatus.Text = "Benuztername/Password ungültig!"; 
      } 
      objcon.Close();    
     } 

이 내 저장 프로 시저는 다음과 같습니다

CREATE PROCEDURE MembershipPruefen (@Username VARCHAR(50), @UserPassword VARCHAR(50)) 
AS 

SELECT Username, UserPassword FROM Benutzer WHERE Username LIKE @Username AND UserPassword LIKE @UserPassword; 

충분합니까? 내 웹 응용 프로그램은 SQL Inections에 대해 안전 할 것인가 아니면 아직 할 일이 있습니까?

+2

나는 왜 당신이 단지 저장 프로 시저와 다중 계층 기술을 사용하지 않는지 알 수 있습니까 ?? 그것의 진짜로 도움이되는 – Marwan

+0

나는 이것에 상당히 새롭기 때문에 나는 그것에 시작하는 아무 단서도 없다 ... 또한 나의 시간은 조금 제한 되 그래서 나는 이것이 가능한 한 빨리 끝내야한다 ... 나는 많은 기사에 살균, 매개 변수화 및 저장 프로 시저는 SQL 주입에 대해 일반적으로 안전하므로 처음 2 개를 수행했지만 충분하지 않은지는 알 수 없습니다. – LeonidasFett

+0

문자열 연결을 건너 뛸 때 유용합니다! – Michel

답변

2

사용 SqlCommand.Prepare 저장 프로 시저 만이 (즉, 행 카운트) 데이터베이스에 존재하거나 말을 값을 반환을 당신은을 사용해야하는 경우 세션 데이터의 사용자 이름 등을 입력 한 다음 사용자 이름을 반환하면됩니다.

이 사용자 :)

저장 프로 시저에 대한 정보를 들어

로 DB 데이터의 더 적은 보여준다 : http://support.microsoft.com/kb/306574

2

를 사용하여 매개 변수화 된 쿼리 (SqlCommand를 SqlParameter에 포함) 및 매개 변수로 사용자 입력을 넣어. 확인되지 않은 사용자 입력에서 SQL 문자열을 작성하지 마십시오. 모든 종류의 잘못된 형식에 대해 사용자 입력을 확인할 수있는 위생 루틴을 작성할 수 있다고 가정하지 마십시오. 엣지 케이스는 쉽게 잊어 버릴 수 있습니다. 숫자 입력을 검사하는 것은 안전면에서 당신을 쉽게 얻을 수 있지만 문자열 입력을 위해서는 매개 변수를 사용하십시오. 두 번째 수준의 취약점 검사 -이 값이 사용자 입력으로 구성되는 경우 SQL 테이블 값에서 SQL 쿼리 문자열을 작성하지 마십시오. 저장 프로 시저를 사용하여 데이터베이스 작업을 캡슐화합니다.

또는 Prepare 문을 사용하십시오. SQL 문이나 Hibernate에 대한 Linq와 같은 ORM을 사용하여 Prepared 문을 만들면 Prepared 문을 내부적으로 사용합니다.

+0

글쎄, 나는 큰 따옴표로 대체하기 위해 작은 따옴표를 확인하고있다 ... 그리고 나는 그것이 작동하는 것처럼 보이는 매개 변수화 된 쿼리를 가지고 있다고 생각한다. 이제는 저장 프로 시저와 메신저를 구현해야한다. – LeonidasFett

+2

이렇게하지 마십시오. '큰 따옴표로 바꾸려면 작은 따옴표를 사용합니다.' 매개 변수가이를 수정해야합니다. – Michel

2

전 데이터베이스에 연결하기 위해 전용 SQL 서버 사용자를 만들 것입니다. (지금 당신이 ths 'sa'와 연결하고 있다고 생각하십니까?).

이것은 데이터베이스에 전혀 권한이없는 새로운 사용자를 추가한다는 것을 의미하며, 앱을 처음 실행하면 예상대로 읽기 권한이 없다는 SQL 예외가 발생합니다. 새로 생성 된 사용자에 대한 'Benutzer'테이블에 대한 권한 부여 권한이 있습니다.

이렇게하면 연결이 손상된 경우에도 공격자는 시스템 저장 프로 시저 등을 실행할 수 없습니다.

한 가지 추가 사항 : 비밀번호를 해시하는 것이 좋습니다. 따라서 비밀번호를 실제 텍스트로 읽을 수 없습니다. 큰 글이며 시간이별로 없다는 것을 알았지 만 해쉬 된 암호를 구현하는 것이 좋습니다. http://crackstation.net/hashing-security.htm

편집 : 내가 =을 진술 할, 당신의 저장 프로 시저에 LIKE를 참조, 사용자가 정확한 암호를 입력해야합니다!

그리고 SQL 문에서 저장 프로 시저로 변경되는 것을 보았습니다. 이전 텍스트에서 테이블의 SELECT 권한을 저장 프로 시저에 대한 EXECUTE 권한으로 변경합니다.

+0

LIKE 키워드에 대한 힌트를 주셔서 감사합니다. 암호를 암호화 할 때, 좋은 생각이 될 것이라고 생각하지만이 프로젝트를 지나치게 확대하고 싶지는 않습니다. 난 계획, 실현 및 제어를위한 70 시간을 가지고 ... 권리 관리에 관한, 나는이 코드에서 할 것이라고 생각 ... 내 DB에 필드 "usertype"처럼,이 필드에 대한 값은 관리자가 될 수 있습니다, 사용자, 손님 ... 로그인 한 사용자의이 열을 확인하고 그가 무엇을 할 수 있는지, 무엇을 할 수 없는지를 결정합니다. 나는 이렇게 할 수 있습니까? – LeonidasFett

+0

간단한 프로젝트의 경우 암호화없이 할 수 있지만, 적어도 암호화를 실험관에게 보내는 강력한 조언으로 언급합니다. 실제 생활에서는 실제 생활에서 구현하기 위해 몇 시간을 더 보낼 것입니다. 더 이상 일반 텍스트 암호는 허용되지 않습니다. 역할은 올바른 사용자 테이블에있을 수 있습니다. 이런 종류의 프로젝트에 대해 간단하게 유지하십시오. – Michel