2013-11-27 5 views
1

일부 저장 프로 시저 프로 시저 입력 매개 변수가 제공된 경우 WHERE 조건을 보간해야합니다. 잠재적 주입 지점을 피하기 위해 보간 된 조건의 일부가 될 값에 대한 매개 변수 바인딩을 사용하고 싶습니다.바인딩 할 매개 변수 개수가 가변적 인 준비된 문 실행

준비된 명령문에 추가 된 조건과 바인드 할 매개 변수의 수는 사용자 입력에 따라 다를 수 있으므로 EXECUTE 문으로 전달할 변수를 결정하기 위해 아래 방법을 고안했습니다. 이것은 효과가 있지만 그것은 우아하지 않습니다.

CREATE PROCEDURE foo (IN mandatory INT, IN optional INT, IN optional2 VARCHAR(20)) 
    BEGIN 

    SELECT 
     0, '', '', mandatory, optional, optional2 
    INTO 
     @params, @sql, @where, @m, @o1, @o2; 

    IF (@o1 > '' AND @o1 IS NOT NULL) THEN 
     SET @where = CONCAT(@where, ' AND field = ?'); 
     SET @params = @params + 1; 
    END IF; 
    IF (@o2 > '' AND @o2 IS NOT NULL) THEN 
     SET @where = CONCAT(@where, ' AND field2 = ?'); 
     SET @params = @params + 3; 
    END IF; 

    SET @sql = CONCAT(' 
     SELECT id, bar FROM table 
     WHERE 
     baz = ? 
     ', @where 
    ); 
    PREPARE STMT FROM @sql; 
    CASE @params 
     WHEN 0 THEN EXECUTE STMT USING @m; 
     WHEN 1 THEN EXECUTE STMT USING @m, @o1; 
     WHEN 3 THEN EXECUTE STMT USING @m, @o2; 
     WHEN 4 THEN EXECUTE STMT USING @m, @o1, @o2; 
    END CASE; 
    DEALLOCATE PREPARE STMT; 

    END$$ 

나는 대안을 알고 있어요 :

  • 이 스토어드 프로 시저를 호출 할 바이너리는 정규 표현식을 통해 사용자가 제공 한 문자열을 전달하여 잠재적 인 SQL 주입을 식별하기 위해 시도하는 기능을 가지고있다.
  • 사용자 정의 함수를 사용하면 동적 입력 수가 주어진 경우 EXECUTE 문을 동적으로 생성 할 수 있습니다. 다른 사람이 욕망에 달려있다 사람이 SQL로 순전히 EXECUTE 문의 동적 구조를 처리하는 경우

그러나, 나는 궁금했다.

답변

0
However, I was wondering if anyone else has ran into this desire to 
handle dynamic construction of an EXECUTE statement purely with SQL. 

예, 나도 그렇습니다.

여기에 알 수없는 길이의 배열에 따라 준비된 문 물음표의 목록을 생성하는 PHP 솔루션입니다 :

/* My target query is this: 
    SELECT fun FROM fun_stuff WHERE fun_key IN (...unknown number of values...) 
*/ 

/* For this example let's set our array to this: */ 
$val_arr = array(1,2,3,4,5,6,7,8,9); 
$val_arr_cnt = count($val_arr); /* and count it */ 

/* Now make prepared statement q-mark string from values array */ 
$sql_prep = str_pad('?', ($val_arr_cnt * 2) - 1, ',?', STR_PAD_RIGHT); 

/* add it to query */ 
$sql = "SELECT fun FROM fun_stuff WHERE fun_key IN ($sql_prep)"; 

/* And the result: 
    SELECT fun FROM fun_stuff WHERE fun_key IN (?,?,?,?,?,?,?,?,?) 
*/ 

나는이 얼마나 효율적으로 아무 생각도 없어. 그러나 나는 지금도 MySQL의 prepared statements의 보안과 효율성을 구현하려고하지만 가변 길이 입력 배열을 가지고 싶다.

0

동적으로 매개 변수 목록을 만들 수 있는지는 잘 모르겠다. ...). 그러나 where 절을 동적으로 빌드 할 수 있으므로 매우 간단한 해결 방법 중 하나가 이와 같습니다. 유효성 검사를 허용한다고 가정 할 때 else 절은 필터링 할 수도 있고 그렇지 않을 수도있는 매개 변수를 무시하는 것과 기본적으로 동일한 효과를 갖습니다.

if p_cust_id is not null && p_cust_id > 0 then 
    set v_where_clause = concat(v_where_clause, ' c.cust_id = ? '); 
    set @v_cust_id := p_cust_id; 
else 
    set v_where_clause = concat(v_where_clause, ' c.cust_id > ? '); 
    set @v_cust_id := 0; 
end if; 

그런 다음 실행 문에 위의 모든 사용자 변수를 연결

execute str1 using @v_cust_id, @v_etc....;*