Вопрос по php, arrays – Удалить все элементы массива, кроме того, что я хочу?

45

У меня есть контроллер, который принимает параметры записи из HTML-формы, а затем отправляет их модели, которая вставит массив в базу данных Cassandra.

Это доказательство SQLInjection, потому что это NoSQL, однако я боюсь, что пользователь может просто смоделировать 100 000 параметров записи или просто добавить те, которые мне не нужны, и они будут вставлены в базу данных. Как я могу убедиться, что в моем массиве останутся только те значения, которые мне нужны?

Пример:

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

Как мне убедиться, что мой массив будет сбрасывать все элементы, которые не находятся вgood пример?

Ваш Ответ

8   ответов
1

нигде не нашел оптимального решения. Итак, я написал это сам

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

        fo,reach ($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;
    }

использование: пример

$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 ) ) ) ,) 

Таким образом, вы получаете только необходимые ключи из многомерного массива. он не ограничен только для «многомерного», его можно использовать, передавая массив, например

['key1', 'loaa']

выход вы получите:

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

ура!

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)); 
    }
}
45

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));

Увидеть это в действии.

Конечно, этот конкретный пример не имеет особого смысла, потому что он работает с массивомvalues, но есть иarray_intersect_key что делает то же самое на основе ключей.

Ссылки на кодовую панель в ответе и комментариях возвращаются к стандартному стандарту & quot; hello world & quot; скрипт. :-(
@Qmal:$good имеет хорошие имена какvalues, в то время как$post имеет их какkeys, Простейшим решением было бы передатьarray_flip($good) вместо$good так что оба входа имеют хорошие имена в качестве ключей.
Хм, что я делаю не так в этом примере?codepad.viper-7.com/mhJ0WK stan
1

как $ post_allowed. Он разрешает только значения в $ post_input, которые также присутствуют в $ post_allow.

$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);
0

array_intersect а такжеarray_intersect_key хороши, они вполне могут быть излишними. В моей ситуации я хотел, чтобы оставался только 1 элемент, поэтому самым простым вариантом было просто перестроить массив, который я хотел, основываясь на ключе / значениях, которые мне нужны. Интересно, в какой момент, следовательно, array_intersect не стоит, и вам просто лучше$new = array('whatI'=>'want');, Я верю в ОП, это того стоит, но в небольших случаях это может быть излишним.

В качестве альтернативы в ответ на оригинальный вопрос просто с помощьюunset возможно, был бы более дешевый вариант -unset($post['one'],$post['two'],$post['three']), Опять же, это относится к точке, в которой это становится слишком неэффективным, и функции array_intersect лучше.

1

ьarray_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']
);
77

do ожидать.

<?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 );

В любом случае, использование Cassandra в качестве хранилища данных, конечно же, не является причиной для того, чтобы не проверять данные, которые вы получаете.

0

массив пересекаются, это поможет вам.

Этот ответ, содержащий только ссылки, лучше позиционировать как комментарий, поскольку он значительно менее информативен по сравнению с другими полными ответами.

Похожие вопросы