2012-04-12 7 views
41

나는 HTML 폼에서 post 매개 변수를 취하는 컨트롤러를 가지고 있으며, 그 데이터를 Cassandra 데이터베이스에 삽입 할 모델로 보낸다.내가 원하는 것을 제외한 모든 배열 요소를 제거 하시겠습니까?

NoSQL이기 때문에 SQLInjection 증명입니다. 그러나 사용자는 단지 100k 게시 매개 변수를 시뮬레이션하거나 필요하지 않은 항목을 추가하여 데이터베이스에 삽입 할 수 있습니다. 어떻게하면 필요한 값만 배열에 남아 있는지 확인할 수 있습니다.

예 :

$post = ['parent_id', 'type', 'title', 'body', 'tags']; // Good 
$post = ['parent_id', 'type', 'title', 'body', 'tags', 'one', 'two', 'three'] // Bad 

가 어떻게 내 배열 좋은 예에없는 모든 요소를 ​​설정 해제됩니다 있는지 확인합니까?

답변

40

당신은 array_intersect를 찾고 있습니다 :

$good = ['parent_id', 'type', 'title', 'body', 'tags']; 
$post = ['parent_id', 'type', 'title', 'body', 'tags', 'one', 'two', 'three']; 

print_r(array_intersect($good, $post)); 

See it in action합니다. 이 배열 에서 작동하기 때문에

은 물론이 구체적인 예는 훨씬 이해가되지 않지만, 키를 기준으로 동일하지 array_intersect_key도 있습니다.

+0

음,이 예제에서 내가 뭘 잘못하고 있습니까? http://codepad.viper-7.com/mhJ0WK – sed

+1

@Qmal :'$ good'은 * values ​​*처럼 좋은 이름을 가지고 있고,'$ post'는 * keys *처럼 있습니다. 가장 간단한 수정은'$ good' 대신에'array_flip ($ good)'을 전달하여 두 입력 모두가 좋은 이름을 갖도록하는 것입니다. – Jon

+0

이제 작동합니다. 감사. – sed

1

배열 교차를 사용하십시오. array intersect, 도움이 될 것입니다.

1

이렇게하면 $ post_allowed와 같은 결과가 출력됩니다. 그것이하는 일은 $ post_allow에도 존재하는 $ post_input의 값만 허용합니다.

$post_allowed = ['parent_id', 'type', 'title', 'body', 'tags']; 
$post_input = ['parent_id', 'type', 'title', 'body', 'tags', 'one', 'two', 'three']; 
$post = array_intersect($post_input, $post_allowed); 
66

항목을 허용 목록에해서 당신은 예상 할 .

<?php 
$post = array( 
    'parent_id' => 1, 
    'type' => 'foo', 
    'title' => 'bar', 
    'body' => 'foo bar', 
    'tags' => 'foo, bar', 
    'one' => 'foo', 
    'two' => 'bar', 
    'three' => 'qux' 
); 

$whitelist = array(
    'parent_id', 
    'type', 
    'title', 
    'body', 
    'tags' 
); 

$filtered = array_intersect_key($post, array_flip($whitelist)); 

var_dump($filtered); 

어쨌든, 데이터 스토어로 카산드라를 사용하면 수신하고있는 데이터 유효성 검사를 할 수 없습니다하지 않는 이유는 물론있다.

+0

매우 깨끗하고 깨끗함 –

+0

이것은 가장 좋은 대답입니다! 간단하고 정확하게 필요한 것은 다음과 같습니다 :) 감사합니다. –

1

이것은 백인 목록으로 표시되며 $_POST은 연관 배열이므로 사용자의 예는 오도 된 것입니다.

$post = [ 
    'parent_id' => 'val', 
    'type' => 'val', 
    'title' => 'val', 
    'body' => 'val', 
    'tags' => 'val', 
    'one' => 'val', 
    'two' => 'val', 
    'three'=>'val', 
]; 

$whitelist = ['parent_id', 'type', 'title', 'body', 'tags']; 

$sanitized_post = array_whitelist_assoc($post, $whitelist); 

이것은 연관 배열을 위해 생성 한 화이트리스트 기능입니다. 경우

if(!function_exists('array_whitelist_assoc')){ 

    /** 
    * Returns an associative array containing all the entries of array1 which have keys that are present in all the arguments when using their values as keys. 
    * 
    * @param array $array The array with master keys to check. 
    * @param array $array2 An array to compare keys against its values. 
    * @return array $array2,... A variable list of arrays to compare. 
    * 
    */ 

    function array_whitelist_assoc(Array $array1, Array $array2) { 

     if(func_num_args() > 2){ 
      $args = func_get_args(); 
      array_shift($args); 
      $array2 = call_user_func_array('array_merge', $args); 
     } 
     return array_intersect_key($array1, array_flip($array2)); 
    } 
} 
1

당신은 연관 배열을 상대하고있는 당신은 수동으로 이전에서 원하는 값을 사용하여 새 배열을 구축 당신은 또한 간단한 접근을 할 수있는, 어떤 이유로 array_intersect_key()을 사용하지 않으 하나. array_intersectarray_intersect_key이 좋은 상태가 아니라 과잉 될 수 있음을 기억 그것의 가치가

$post = array(
    'parent_id' => 1, 
    'type' => "post", 
    'title' => "Post title", 
    'body' => "Post body", 
    'tags' => "Post tags", 
    'malicious' => "Robert'); DROP TABLE students;--" 
); 
$good = array(
    'parent_id' => $post['parent_id'], 
    'type' => $post['type'], 
    'title' => $post['title'], 
    'body' => $post['body'], 
    'tags' => $post['tags'] 
); 
0

. 필자의 상황에서는 1 요소 만 남기고 싶었 기 때문에 가장 간단한 옵션은 필요한 키/값을 기반으로 원하는 배열을 다시 작성하는 것이 었습니다. 그러므로 어떤 점에서 array_intersect의 가치가 없어지고 $new = array('whatI'=>'want');을 사용하는 것이 좋습니다. 나는 이것이 가치있는 일을 믿는다. 그러나 더 작은 경우에는 그것은 과잉일지도 모른다.

또는 원래 질문에 대한 응답으로 단순히 unset을 사용하는 것이 더 저렴한 옵션 인 unset($post['one'],$post['two'],$post['three']) 일 수 있습니다. 다시 말하지만, 이것은 너무 비효율적이되어 array_intersect 함수가 더 좋은 점과 관련이 있습니다.

1

다차원 배열은 어떻게됩니까? 이 솔루션에 대한 몇 시간 동안 연구를 해봤는데 아무데도 최적의 솔루션을 찾지 못했습니다. 예를

$array = [ 
     'key1' => 'kw', 
     'loaa'=> ['looo'], 
     'k' => [ 
      'prope' => [ 
       'prop' => ['proo', 'prot', 'loolooo', 'de'], 
       'prop2' => ['hun' => 'lu'], 
      ], 
      'prop1' => [ 

      ], 
     ], 
    ]; 

전화 : 예

allow_keys($array, ['key1', 'k' => ['prope' => ['prop' => [0, 1], 'prop2']]]) 

출력 :

Array ([key1] => kw [k] => Array ([prope] => Array ([prop] => Array ([0] => proo [1] => prot) [prop2] => Array ([hun] => lu)))) 

그래서 당신은 필요한 경우에만받을 키에서 그래서, 나는

function allow_keys($arr, $keys) 
    { 
     $saved = []; 

     foreach ($keys as $key => $value) { 
      if (is_int($key) || is_int($value)) { 
       $keysKey = $value; 
      } else { 
       $keysKey = $key; 
      } 
      if (isset($arr[$keysKey])) { 

       $saved[$keysKey] = $arr[$keysKey]; 
       if (is_array($value)) { 

        $saved[$keysKey] = allow_keys($saved[$keysKey], $keys[$keysKey]); 
       } 
      } 
     } 
     return $saved; 
    } 

사용 혼자 쓴 다차원 배열 그것은 단지 당신이 얻을 "다차원"당신이

['key1', 'loaa'] 

출력과 같은 배열을 전달하여 사용할 수에 대한 제한되지 않습니다

Array ([key1] => kw [loaa] => Array ([0] => looo)) 

환호!

관련 문제