>  기사  >  데이터 베이스  >  mysql 고급(24) SQL 주입을 방어하는 방법 요약

mysql 고급(24) SQL 주입을 방어하는 방법 요약

黄舟
黄舟원래의
2017-02-11 10:53:471506검색

SQL 인젝션 방어방법 요약

본 글에서는 주로 SQL 인젝션 방어방법을 설명하고, 인젝션이 무엇인지, 인젝션을 하는 이유는 무엇인지, 인젝션을 하는 이유는 무엇인지, 어떻게 대처하는지 소개한다. 그것을 방어하세요. 친구들이 그것을 참조할 수 있습니다.

SQL 주입은 매우 해로운 공격 형태입니다. 피해는 크지만 방어는 XSS보다 훨씬 덜 어렵습니다.

SQL 주입은 http://www.php.cn/

에서 확인할 수 있습니다. SQL 주입 취약점이 존재하는 이유는 SQL 매개변수를 연결합니다. 즉, 입력에 사용된 쿼리 매개변수를 SQL문에 직접 엮어 SQL 인젝션 취약점을 발생시키는 것이다.

1. 클래식 SQL 주입 시연


다음을 참조하세요. user where id=2;

SQL 문자열을 연결하여 명령문을 얻은 경우 예: String sql = "select id,no from user where id=" + id;

id 는 사용자가 입력한 매개변수입니다. 그리고 사용자가 2를 입력하면 위에서 발견한 데이터를 볼 수 있습니다. 2 또는 1=1을 입력하면 SQL 주입 공격이 수행됩니다.

그러면 위의 명령문(id=2 또는 1=1;인 user에서 id,no 선택)을 통해 사용자 테이블의 모든 레코드를 찾았음을 확인할 수 있습니다.

전형적인 SQL 인젝션입니다.

다른 열을 보세요:

sqlinject 테이블은 sql을 통해 직접 삭제할 수 있습니다. 주사! 위험을 볼 수 있습니다!

2. sql 인젝션을 하는 이유

sql 인젝션을 하는 이유는 표면적으로는 문자열을 엮어서 sql 문을 형성하기 때문이다. 고정 변수로 인해 사전 컴파일 및 바인딩되지 않습니다.

하지만 더 깊은 이유는 사용자가 입력한 문자열이 "sql 문"으로 실행되기 때문입니다.

예를 들어 위의 String sql = "select id,no from user where id=" + id;

사용자가 입력한 id 값이 다음과 같이 전달되기를 바랍니다. 문자열 리터럴 값을 입력하여 실행하지만 2 또는 1=1을 입력하거나 1=1이 where id=의 리터럴 값으로 사용되지 않고 sql 문으로 실행됩니다. 따라서 그 본질은 사용자의 입력 데이터를 명령으로 실행하는 것입니다.

3. SQL 인젝션 방어

1> 기본적으로 SQL 문을 사용하여 변수를 미리 컴파일하고 바인딩하는 것이 SQL 인젝션을 방어하는 가장 좋은 방법이라는 것은 누구나 알고 있습니다. 그러나 근본적인 이유가 모두 이해되는 것은 아닙니다.

String sql = "id=?인 사용자에서 id, no 선택";

PreparedStatement ps = conn.prepareStatement(sql);

ps.setInt(1, id);

ps.executeQuery();

위와 같이 SQL 문 사전 컴파일 및 바인드 변수의 일반적인 사용 방법입니다. 이것이 SQL 주입을 방지할 수 있는 이유는 무엇입니까?

이유는 다음과 같습니다.PreparedStatement를 사용하면 SQL 문: "select id, no from user where id=?"가 사전 컴파일됩니다. 즉, SQL 엔진이 미리 구문 분석을 수행하고 구문 트리를 생성합니다. 즉, 나중에 입력하는 매개변수는 무엇을 입력하든 sql 문의 문법 구조에 영향을 미치지 않습니다. 왜냐하면 문법 분석이 완료되었으며 문법 분석은 주로 sql을 분석하기 때문입니다. select,from,where,and,or,order by 등과 같은 명령. 따라서 나중에 이러한 sql 명령을 입력하더라도 sql 명령으로 실행되지 않습니다. 왜냐하면 이러한 sql 명령의 실행은 먼저 구문 분석을 통과하고 실행 계획을 생성해야 하기 때문입니다. 이제 구문 분석이 완료되었으므로 사전 컴파일되었습니다. . 이면 나중에 입력하는 매개변수는 sql 명령으로 실행하는 것이 절대 불가능하며 문자열 리터럴 매개변수로만 처리됩니다. 따라서 SQL 문을 미리 컴파일하면 SQL 주입을 방지할 수 있습니다.

2> 그러나 모든 시나리오에서 sql 문 사전 컴파일을 사용할 수 있는 것은 아닙니다. 이때 일부 시나리오에서는 매개 변수의 데이터 유형을 엄격하게 확인하고 sql 주입에 일부 안전 기능을 사용할 수도 있습니다.

예를 들어 String sql = "select id,no from user where id=" + id;

사용자가 입력한 매개변수를 받으면 엄격하게 id를 확인합니다. int 유형 . 복잡한 상황은 정규식을 사용하여 확인할 수 있습니다. 이는 SQL 주입을 방지할 수도 있습니다.

다음과 같은 안전한 기능 사용:

MySQLCodec codec = new MySQLCodec(Mode.STANDARD);

name = ESAPI.encoder().encodeForSQL(codec, name ) ;

String sql = "select id,no from user where name=" + name;

ESAPI.encoder().encodeForSQL(codec, name)

이 function 이름에 포함된 일부 특수 문자가 인코딩되므로 SQL 엔진은 이름의 문자열을 구문 분석을 위한 SQL 명령으로 처리하지 않습니다.

참고

실제 프로젝트에서는 일반적으로 ibatis, mybatis, hibernate 등 다양한 프레임워크를 사용합니다. 일반적으로 기본적으로 미리 컴파일된 SQL이 사용됩니다. ibatis/mybatis의 경우 #{name} 형식을 사용하면 sql이 미리 컴파일된 것입니다. ${name}을 사용하면 sql이 미리 컴파일되지 않습니다.

위 내용은 SQL 주입 방어 방법을 요약한 내용이므로 향후 연구에 도움이 되기를 바랍니다.

아름다운 글과 그림

그게 바로 it MySQL Advanced (24) SQL 인젝션 방어방법 요약. 자세한 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.