보안 Golang 데이터베이스 상호 작용: SQL 삽입 방지
오늘날의 개발 환경에서는 보안 코딩 방식이 무엇보다 중요합니다. 이 기사에서는 데이터베이스와 상호 작용할 때 흔히 발생하는 위협인 SQL 삽입 취약점으로부터 Golang 애플리케이션을 보호하는 데 중점을 둡니다. 원시 SQL 및 ORM(객체 관계형 매핑) 프레임워크를 모두 사용하여 예방 기술을 살펴보겠습니다.
SQL 인젝션 이해
SQL 주입(SQLi)은 심각한 웹 보안 결함입니다. 공격자는 데이터베이스 쿼리에 악성 SQL 코드를 삽입하여 이를 악용하여 잠재적으로 데이터 무결성과 애플리케이션 보안을 손상시킵니다.
취약한 쿼리 예:
<code class="language-go">query := "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'" rows, err := db.Query(query)</code>
username
또는 password
에 악의적인 입력이 있으면 쿼리 논리가 변경될 수 있습니다.
SQL 인젝션에 대한 더 깊은 이해는 다른 포스팅을 참고하세요.
원시 SQL 쿼리 보안
SQL로 직접 작업할 때는 다음 보안 조치를 우선시하세요.
1. 준비된 명령문: Go의 database/sql
패키지는 SQLi에 대한 중요한 방어 수단인 준비된 명령문을 제공합니다.
취약한 예:
<code class="language-go">query := "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'" rows, err := db.Query(query) // Vulnerable to SQL injection</code>
보안 버전(준비된 설명):
<code class="language-go">query := "SELECT * FROM users WHERE username = ? AND password = ?" rows, err := db.Query(query, username, password) if err != nil { log.Fatal(err) }</code>
준비된 명령문은 사용자 입력을 자동으로 이스케이프하여 삽입을 방지합니다.
2. 매개변수화된 쿼리: 매개변수화된 쿼리에는 자리 표시자와 함께 db.Query
또는 db.Exec
를 사용합니다.
<code class="language-go">query := "INSERT INTO products (name, price) VALUES (?, ?)" _, err := db.Exec(query, productName, productPrice) if err != nil { log.Fatal(err) }</code>
동적 쿼리의 경우 문자열 연결이나 fmt.Sprintf
을 피하세요.
3. QueryRow
단일 레코드의 경우: 단일 행 검색의 경우 QueryRow
위험을 최소화합니다.
<code class="language-go">query := "SELECT id, name FROM users WHERE email = ?" var id int var name string err := db.QueryRow(query, email).Scan(&id, &name) if err != nil { log.Fatal(err) }</code>
4. 입력 검증 및 삭제: 준비된 문이 있어도 입력 검증 및 삭제:
Go 입력 확인 예:
<code class="language-go">func isValidUsername(username string) bool { re := regexp.MustCompile(`^[a-zA-Z0-9_]+$`) return re.MatchString(username) } if len(username) > 50 || !isValidUsername(username) { log.Fatal("Invalid input") }</code>
5. 저장 프로시저: 데이터베이스 저장 프로시저 내에 쿼리 논리 캡슐화:
<code class="language-sql">CREATE PROCEDURE AuthenticateUser(IN username VARCHAR(50), IN password VARCHAR(50)) BEGIN SELECT * FROM users WHERE username = username AND password = password; END;</code>
Go에서 전화:
<code class="language-go">_, err := db.Exec("CALL AuthenticateUser(?, ?)", username, password) if err != nil { log.Fatal(err) }</code>
ORM을 통한 SQL 주입 방지
GORM 및 XORM과 같은 ORM은 데이터베이스 상호 작용을 단순화하지만 안전한 관행은 여전히 중요합니다.
1. 고름:
취약한 예(동적 쿼리):
<code class="language-go">db.Raw("SELECT * FROM users WHERE name = '" + userName + "'").Scan(&user)</code>
보안 예(매개변수화된 쿼리):
<code class="language-go">db.Raw("SELECT * FROM users WHERE name = ? AND email = ?", userName, email).Scan(&user)</code>
GORM의 Raw
메소드는 자리 표시자를 지원합니다. Where
:
<code class="language-go">query := "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'" rows, err := db.Query(query)</code>
2. 복잡한 쿼리에는 원시 SQL을 피하세요. 복잡한 원시 쿼리에도 자리 표시자를 사용하세요.
3. 안전한 매핑을 위한 구조체 태그: 안전한 ORM 매핑을 위한 구조체 태그 사용:
<code class="language-go">query := "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'" rows, err := db.Query(query) // Vulnerable to SQL injection</code>
피해야 할 일반적인 실수:
결론
Golang은 안전한 데이터베이스 상호작용을 위한 강력한 도구를 제공합니다. 준비된 명령문, 매개변수화된 쿼리, ORM을 올바르게 사용하고 사용자 입력을 부지런히 검증 및 삭제하면 SQL 삽입 취약점의 위험을 크게 줄일 수 있습니다.
저와 소통하세요:
위 내용은 Golang에서 원시 SQL 및 ORM을 사용한 SQL 주입 방지의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!