Выполнение отражения Java

Я использую три разных способа предотвращения уязвимости моего веб-приложения для SQL-инъекции.

  1. Использование mysql_real_escape_string(), которое является предопределенной функцией в PHP , и этот код добавляет обратную косую черту к следующим символам: \x00, \n, \r, \, ', " и \x1a. Передайте входные значения в качестве параметров, чтобы свести к минимуму вероятность внедрения SQL.
  2. Самый продвинутый способ - использовать PDO.

Надеюсь, это поможет вам.

Рассмотрим следующий запрос:

$iId = mysql_real_escape_string("1 OR 1=1"); $sSql = "SELECT * FROM table WHERE id = $iId";

mysql_real_escape_string () здесь не защитит. Если вы используете одиночные кавычки ('') вокруг ваших переменных внутри вашего запроса, это то, что защищает вас от этого. Ниже приведено ниже решение:

$iId = (int) mysql_real_escape_string("1 OR 1=1"); $sSql = "SELECT * FROM table WHERE id = $iId";

В этом вопросе есть хорошие ответы.

Я предлагаю , наилучшим вариантом является использование PDO.

Изменить:

mysql_real_escape_string() устарел с PHP 5.5.0. Используйте либо mysqli, либо PDO.

Альтернативой mysql_real_escape_string () является

string mysqli_real_escape_string ( mysqli $link , string $escapestr )

Пример:

$iId = $mysqli->real_escape_string("1 OR 1=1");
$mysqli->query("SELECT * FROM table WHERE id = $iId");

168
задан Peter Lawrey 16 April 2016 в 18:51
поделиться

9 ответов

Да - абсолютно. Поиск класса через отражение, магнитудой , более дорогой.

Заключение в кавычки документация Java относительно отражения :

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

Вот простой тест, который я изрубил за 5 минут на моей машине, рабочий Sun JRE 6u10:

public class Main {

    public static void main(String[] args) throws Exception
    {
        doRegular();
        doReflection();
    }

    public static void doRegular() throws Exception
    {
        long start = System.currentTimeMillis();
        for (int i=0; i<1000000; i++)
        {
            A a = new A();
            a.doSomeThing();
        }
        System.out.println(System.currentTimeMillis() - start);
    }

    public static void doReflection() throws Exception
    {
        long start = System.currentTimeMillis();
        for (int i=0; i<1000000; i++)
        {
            A a = (A) Class.forName("misc.A").newInstance();
            a.doSomeThing();
        }
        System.out.println(System.currentTimeMillis() - start);
    }
}

С этими результатами:

35 // no reflection
465 // using reflection

Принимают во внимание, что поиск и инстанцирование сделаны вместе, и в некоторых случаях поиск может быть пересмотрен далеко, но это - просто основной пример.

, Даже если Вы просто инстанцируете, Вы все еще поражали производительность:

30 // no reflection
47 // reflection using one lookup, only instantiating

Снова, YMMV.

168
ответ дан Arsen Davtyan 23 November 2019 в 20:53
поделиться

Часто можно использовать свободное городское население Apache BeanUtils или PropertyUtils, какой самоанализ (в основном они кэшируют метаданные о классах, таким образом, они должны не всегда использовать отражение).

1
ответ дан sproketboy 23 November 2019 в 20:53
поделиться

Да, всегда будет медленнее, создают объект отражением, потому что JVM не может оптимизировать код времени компиляции. Посмотрите Sun/Java Отражательные учебные руководства для получения дополнительной информации.

Посмотрите этот простой тест:

public class TestSpeed {
    public static void main(String[] args) {
        long startTime = System.nanoTime();
        Object instance = new TestSpeed();
        long endTime = System.nanoTime();
        System.out.println(endTime - startTime + "ns");

        startTime = System.nanoTime();
        try {
            Object reflectionInstance = Class.forName("TestSpeed").newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        endTime = System.nanoTime();
        System.out.println(endTime - startTime + "ns");
    }
}
1
ответ дан Michael Myers 23 November 2019 в 20:53
поделиться

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

6
ответ дан Elie 23 November 2019 в 20:53
поделиться

Существуют немного служебные с отражением, но это намного меньше на современном VMs, чем это раньше было.

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

24
ответ дан Marcus Downing 23 November 2019 в 20:53
поделиться

"Значительный" совершенно зависит от контекста.

, Если Вы используете отражение для создания единственного объекта-обработчика на основе некоторого конфигурационного файла, и затем тратите остальную часть времени рабочие запросы базы данных, тогда это незначительно. Если Вы создаете большие количества объектов через отражение в жестком цикле, то да, это значительно.

В целом, конструкторская гибкость (при необходимости!) должен управлять Вашим использованием отражения, не производительности. Однако, чтобы определить, является ли производительность проблемой, необходимо представить, а не получить произвольные ответы от дискуссионного форума.

26
ответ дан kdgregory 23 November 2019 в 20:53
поделиться

Если там действительно потребность в чем-то быстрее, чем отражение, и это не просто преждевременная оптимизация, то поколение байт-кода с ASM или высокоуровневая библиотека является опцией. При генерации байт-кода, первый раз медленнее, чем просто использование отражения, но после того как байт-код был сгенерирован, это с такой скоростью, как нормальный код Java и будет оптимизировано JIT-компилятором.

Некоторые примеры приложений, которые используют генерацию кода:

  • методы Вызова на прокси, сгенерированных , CGLIB немного быстрее, чем Java динамические прокси , потому что CGLIB генерирует байт-код для своих прокси, но динамические прокси используют только отражение (, я имел размеры CGLIB, чтобы быть о 10x быстрее в вызовах метода, но создание прокси было медленнее).

  • JSerial генерирует байт-код для чтения/записи полей сериализованных объектов, вместо того, чтобы использовать отражение. Существуют некоторые сравнительные тесты на сайте JSERIAL.

  • я не на 100% уверен (и я не испытываю желание читать источник теперь), но я думаю , Guice генерирует байт-код, чтобы сделать внедрение зависимости. Исправьте меня, если я неправ.

26
ответ дан Esko Luontola 23 November 2019 в 20:53
поделиться

Можно найти, что = новый () оптимизируется JVM. Если Вы помещаете объекты в массив, они не работают так хорошо.;) Следующая печать...

new A(), 141 ns
A.class.newInstance(), 266 ns
new A(), 103 ns
A.class.newInstance(), 261 ns

public class Run {
    private static final int RUNS = 3000000;

    public static class A {
    }

    public static void main(String[] args) throws Exception {
        doRegular();
        doReflection();
        doRegular();
        doReflection();
    }

    public static void doRegular() throws Exception {
        A[] as = new A[RUNS];
        long start = System.nanoTime();
        for (int i = 0; i < RUNS; i++) {
            as[i] = new A();
        }
        System.out.printf("new A(), %,d ns%n", (System.nanoTime() - start)/RUNS);
    }

    public static void doReflection() throws Exception {
        A[] as = new A[RUNS];
        long start = System.nanoTime();
        for (int i = 0; i < RUNS; i++) {
            as[i] = A.class.newInstance();
        }
        System.out.printf("A.class.newInstance(), %,d ns%n", (System.nanoTime() - start)/RUNS);
    }
}

Это предполагает, что различие составляет приблизительно 150 нс на моей машине.

36
ответ дан Peter Lawrey 23 November 2019 в 20:53
поделиться

Да, это медленнее.

, Но помнят проклятое правило № 1 - ПРЕЖДЕВРЕМЕННАЯ ОПТИМИЗАЦИЯ ЯВЛЯЕТСЯ КОРНЕМ ВСЕГО ЗЛА

(Ну, может быть связан № 1 для DRY)

, я клянусь, если бы кто-то подошел ко мне на работе и спросил меня это, то я был бы очень осторожен по их коду в течение следующих нескольких месяцев.

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

, О, и я не имею в виду, пишут глупый код также. Просто думайте о самом чистом способе, которым можно возможно сделать это - никакая копия и вставка, и т.д. (Все еще опасаться материала как внутренние циклы и использовать набор, что лучшие соответствия, которые потребность - Игнорирующий их не "не оптимизирована", программируя, она "плохо" программирует)

, Это волнует меня, когда я слышу вопросы как это, но затем я забываю, что все должны пройти изучение всех правил самих, прежде чем они действительно получат его. Вы получите его после пребывания в течение месяца человека, отлаживая что-то кто-то "Оптимизированный".

РЕДАКТИРОВАНИЕ:

интересная вещь произошла в этом потоке. Проверьте ответ № 1, это - пример того, насколько мощный компилятор при оптимизации вещей. Тест абсолютно недопустим, потому что неотражающее инстанцирование может быть полностью факторизовано.

Урок? Никогда не оптимизируйте, пока Вы не записали чистое, аккуратно кодированное решение и доказали его, чтобы быть слишком медленными.

85
ответ дан Bill K 23 November 2019 в 20:53
поделиться
Другие вопросы по тегам:

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