Переопределение переменных экземпляра суперкласса

Каждый ответ здесь охватывает только часть проблемы. На самом деле существует четыре разных части запроса, которые мы можем добавить к ней динамически:

  • строка
  • номер
  • идентификатор
  • ключевое слово синтаксиса.

и подготовленные операторы охватывают только 2 из них

. Но иногда нам приходится делать наш запрос еще более динамичным, добавляя операторы или идентификаторы также. Таким образом, нам понадобятся разные методы защиты.

В целом такой подход защиты основан на whitelisting . В этом случае каждый динамический параметр должен быть жестко закодирован в вашем скрипте и выбран из этого набора. Например, для динамического упорядочения:

$orders  = array("name","price","qty"); //field names
$key     = array_search($_GET['sort'],$orders)); // see if we have such a name
$orderby = $orders[$key]; //if not, first one will be set automatically. smart enuf :)
$query   = "SELECT * FROM `table` ORDER BY $orderby"; //value is safe

Однако есть еще один способ защитить идентификаторы - экранирование. Пока вы указываете идентификатор, вы можете избежать обратных звонков внутри, удвоив их.

В качестве еще одного шага мы можем заимствовать поистине блестящую идею использования некоторого заполнителя (прокси для представления фактического значения в запросе) из подготовленных операторов и изобретать местозаполнитель другого типа - заполнителя идентификатора .

Итак, чтобы сделать длинный рассказ коротким: это заполнитель, не подготовленное заявление можно рассматривать как серебряную пулю.

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

Тем не менее, есть проблема с ключевыми словами синтаксиса SQL (например, AND, DESC и т. д.), но белый список - единственный подход в этом случае.

Обновить

Несмотря на то, что существует общее согласие в отношении наилучшей практики защиты SQL-инъекций, все еще существует множество плохих методов. И некоторые из них слишком глубоко укоренены в умах пользователей PHP. Например, на этой самой странице есть (хотя и невидимые для большинства посетителей) более 80 удаленных ответов - все они удалены сообществом из-за плохого качества или продвижения плохих и устаревших практик. Хуже того, некоторые из плохих ответов не удаляются, а скорее процветают.

Например, там (1) являются (2) еще (3) many (4) отвечает (5) , в том числе второй наиболее ответный ответ , предлагающий вам ручное стирание строки - устаревший подход, который оказался небезопасным.

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

Я думаю, что все это из-за одного очень старого суеверия, поддержанного такими авторитетами, как OWASP или PHP manual , который провозглашает равенство между тем, что «ускользает» "и защита от SQL-инъекций.

Независимо от того, что написано в руководстве по PHP, *_escape_string ни в коем случае не делает данные безопасными и никогда не предназначались. Помимо бесполезности для любой части SQL, отличной от строки, ручное экранирование неверно, поскольку оно является ручным, как автоматическое.

И OWASP делает это еще хуже, подчеркивая, что пользовательский вход пользователя является совершенно бессмысленным: таких слов в контексте защиты от инъекций не должно быть. Каждая переменная потенциально опасна - независимо от источника! Или, другими словами, каждая переменная должна быть должным образом отформатирована для включения в запрос - независимо от источника. Это вопрос назначения. В тот момент, когда разработчик начинает отделять овец от коз (думая, является ли какая-то конкретная переменная «безопасной» или нет), он делает свой первый шаг к катастрофе. Не говоря уже о том, что даже формулировка предполагает, что в точке входа происходит массовое ускорение, напоминающее очень волшебную функцию кавычек - уже презренный, устаревший и удаленный.

Итак, в отличие от любого «экранирования» подготовленные операторы мера, которая действительно защищает от SQL-инъекции (если применимо).

Если вы все еще не уверены, вот пошаговое объяснение, которое я написал, The Hitchhiker's Guide на SQL Injection Prevention , где я подробно объяснил все эти вопросы и даже составил раздел, полностью посвященный плохим практикам и их раскрытию.

27
задан Andreas -he-her- 17 March 2017 в 02:35
поделиться

8 ответов

Потому что, если бы вы изменили реализацию элемента данных, это вполне могло бы сломать суперкласс (представьте, что элемент данных суперкласса может быть изменен с плавающего на String).

21
ответ дан cletus 28 November 2019 в 04:16
поделиться

Поскольку можно только переопределить поведение и не структуру. Структура установлена в камне, как только объект был создан, и память была выделена для него. Конечно, это обычно верно на статически типизированных языках.

9
ответ дан Adrian Zanescu 28 November 2019 в 04:16
поделиться

К переменным не получают доступ полиморфно. Что Вы хотели бы сделать с этим, что Вы не можете сделать с защищенной переменной? (Не то, чтобы я поощряю использовать нечастные изменяемые переменные вообще, лично.)

5
ответ дан Jon Skeet 28 November 2019 в 04:16
поделиться
class Dad{
    public String name = "Dad";
}
class Son extends Dad{
    public String name = "Son";
    public String getName(){
        return this.name;
    }
}

Из метода main () при вызове

new Son().getName();

будет возвращено «Сын». Так вы можете переопределить переменную суперкласса.

2
ответ дан ssi-anik 28 November 2019 в 04:16
поделиться

Вы имеете в виду с переопределением, Вы хотите изменить тип данных, например?

, Что Вы делаете с этим выражением

public class A {
   protected int mIndex;

   public void counter(){
      mIndex++;
   }

}

public class B extends A {
   protected String mIndex; // Or what you mean with overloading
}

, Как Вы хотите изменить mIndex ++ выражение без перегрузки оператора или чего-то вроде этого.

0
ответ дан Markus Lausberg 28 November 2019 в 04:16
поделиться

мы не можем переопределить структуру переменных экземпляра, но мы переопределяем их поведение: -

class A
{
int x = 5;
}

class B extends A
{
int x = 7:
}

class Main
{
public static void main(String dh[])
{
A obj = new B();
System.out.println(obj.x);
}
}

в этом случае вывод равен 5.

0
ответ дан dheeraj 28 November 2019 в 04:16
поделиться

Если вам нужно переопределить переменную экземпляра, вы почти наверняка унаследуете от класса worng.

В некоторых языках вы можете скрыть переменную экземпляра, указав новую:

class A has variable V1 of type X;

class B inherits from A, but reintroduces V1 of type Y.

Методы класса A по-прежнему могут обращаться к исходному V1. Методы класса B могут получить доступ к новому V1. И если они хотят получить доступ к оригиналу, они могут привести себя к классу А (как вы видите, грязное программирование провоцирует более грязное программирование).

Лучшее решение - найти другое имя для переменной.

0
ответ дан Toon Krijthe 28 November 2019 в 04:16
поделиться

С помощью TMemoryStream и компонента Indy. но что вы подразумеваете под переопределением переменной? если вы хотите использовать переменную в любом другом месте, а не в суперклассе Вы можете использовать супер. как в super (имена переменных); почему вы хотите переопределить переменную? я имею в виду, есть ли необходимость?

0
ответ дан 28 November 2019 в 04:16
поделиться
Другие вопросы по тегам:

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