67

Исключительно простая теория AppSec .NET

Embed Size (px)

Citation preview

Page 1: Исключительно простая теория AppSec .NET
Page 2: Исключительно простая теория AppSec .NET

Исключительно простая теория AppSec .NET

Владимир Кочетков Application Inspector/Compiling Applications

Analysis/Team LeadPositive Technologies

Июньская встреча SPB.NET Community, 2015

Page 3: Исключительно простая теория AppSec .NET

:~$ whoami && whonotme― .NET-разработчик, руководитель группы

анализа компилируемых приложений в Positive Technologies

― AppSec-исследователь

― RSDN тимер

― Оторванный от реальности теоретик

― Упоротый параноик

Page 4: Исключительно простая теория AppSec .NET

Всего один вопрос…

Page 5: Исключительно простая теория AppSec .NET

…что такое уязвимость?

Page 6: Исключительно простая теория AppSec .NET

Какой из фрагментов кода уязвим?1)

var cmd = new SqlCommand("SELECT Value FROM Discounts WHERE CouponCode = '" + Request["CouponCode"] + "'");var connection = new SqlConnection(connectionString);connection.Open();cmd.Connection = connection;var couponValue = cmd.ExecuteScalar();...

2)

var cmd = new SqlCommand("SELECT Value FROM Discounts WHERE CouponCode = @CouponCode");cmd.Parameters.AddWithValue("@CouponCode ", Request["CouponCode"]);var connection = new SqlConnection(connectionString);connection.Open();cmd.Connection = connection;var couponValue = cmd.ExecuteScalar();...

Page 7: Исключительно простая теория AppSec .NET

Какой из фрагментов кода уязвим?1)

[Authorize(Roles = "All")]public ActionResult SomeAction(){ ... return View();}

2)

[Authorize(Roles = "Baz, Qux")]public ActionResult SomeAction(){ ... return View();}

Page 8: Исключительно простая теория AppSec .NET

Уязвимость к RCE?var code = wrapCode("Foo", "Bar", "Qux", Request["code"]);

var provider = new CSharpCodeProvider();

var compilerParams = new CompilerParameters { GenerateInMemory = true, GenerateExecutable = false};

var results = provider.CompileAssemblyFromSource( compilerParams, code);

if (!results.Errors.Any()){ var o = results.CompiledAssembly.CreateInstance("Foo.Bar"); var mi = o.GetType().GetMethod("Qux"); mi.Invoke(o, null);}

Page 9: Исключительно простая теория AppSec .NET

Критерии уязвимости определяются множествами правил предметных областей приложения

Page 10: Исключительно простая теория AppSec .NET

Примеры предметных областейНефункциональные:

― управление потоками данных;― управление потоками выполнения;― контроль доступа.

Функциональные:

― интернет-торговля;― онлайн-банкинг;― бухучет;― …

Page 11: Исключительно простая теория AppSec .NET

Театр начинается с вешалки, а уязвимость – с недостатка

Page 12: Исключительно простая теория AppSec .NET

Недостаток- неэффективный контроль выполнения правил предметных областей приложения

Примеры недостатков:

― неэффективная предварительная обработка данных;

― неэффективный контроль аутентичности источника запросов;

― неэффективный контроль доступа;

― неэффективный контроль жизненного цикла транзакции;

― неэффективный контроль распределения ролей.

Page 13: Исключительно простая теория AppSec .NET

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

Page 14: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 15: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 16: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 17: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 18: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 19: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 20: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 21: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 22: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 23: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 24: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 25: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 26: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 27: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 28: Исключительно простая теория AppSec .NET

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 29: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 30: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 31: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 32: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 33: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 34: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 35: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 36: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 37: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 38: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 39: Исключительно простая теория AppSec .NET

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

Page 40: Исключительно простая теория AppSec .NET

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

Page 41: Исключительно простая теория AppSec .NET

Множества значений всех потоков данных в конкретной точке потока выполнения определяют состояние приложения

Page 42: Исключительно простая теория AppSec .NET

Угроза- возможность обхода правил предметных областей приложения, приводящего к нарушению свойств защищенности хотя бы одного потока данных:

― конфиденциальности;― целостности;― доступности;― аутентичности;― авторизованности.

Page 43: Исключительно простая теория AppSec .NET

Уязвимость – состояние приложения, в котором возможна реализация угрозы

Page 44: Исключительно простая теория AppSec .NET

То, что может сделать с потоками данных атакующий, нарушив правила предметных областей, называется угрозой (threat)

То, где и благодаря чему он может это сделать, называется уязвимостью (vulnerability), обусловленной недостатком (weakness)

То, как он может это сделать, называется атакой (attack)

То, с какой вероятностью у него это удастся и какие последствия может повлечь, называется риском (risk)

Иными словами…

Page 45: Исключительно простая теория AppSec .NET

То, что не позволяет атакующему провести атаку, обеспечивает защищенность (security)

То, что минимизирует риск, обеспечивает безопасность (safety)

Разработчикам следует обеспечивать защищенность, не

допуская появления недостатков в коде

Иными словами…

Page 46: Исключительно простая теория AppSec .NET

Причинно-следственные связи

Недостаток Угроза

Уязвимость Атака

Риск

Незащищенность

Небезопасность

Бороться необходимо с причинами, а не со следствиями!

Page 47: Исключительно простая теория AppSec .NET

* на основе результатов опроса http://www.rsdn.ru/?poll/3488

Осведомленность разработчиков*

Abus

e of

Fun

ction

ality

Brut

e Fo

rce

Buffe

r/Fo

rmat

Str

ing

Ove

rflow

Cont

ent S

poofi

ng

Cred

entia

l/Ses

sion

Pred

iction

Cros

s-Si

te R

eque

st F

orge

ry

Cros

s-Si

te S

crip

ting

Deni

al o

f Ser

vice

Fing

erpr

intin

g

HPP/

HPC

HRS

Inte

ger O

verfl

ows

LDAP

Inje

ction

Mai

l Com

man

d In

jecti

on

Null

Byte

Inje

ction

OS

Com

man

ding

Path

Tra

vers

al

Pred

ictab

le R

esou

rce

Loca

tion

Rem

ote/

Loca

l File

Inclu

sion

Routi

ng D

etou

r

Sess

ion

Fixa

tion

SOAP

Arr

ay A

buse

SQL I

njec

tion

SSI I

njec

tion

URL R

edire

ctor

Abu

se

XML A

ttrib

ute

Blow

up

XML E

ntity

Exp

ansio

n

XML E

xter

nal E

ntitie

s

XML I

njec

tion

XPat

h/XQ

uery

Inje

ction

0.00%

10.00%

20.00%

30.00%

40.00%

50.00%

60.00%

70.00%

80.00%

90.00%

Attacks based on WASC classification Attacks included at OWASP Top 10 risks

Page 48: Исключительно простая теория AppSec .NET

КлассификацияКлассификация уязвимостей возможна по:

― предметной области; // управление потоками данных

― недостатку; // неэффективная предварительная обработка данных

― потоку данных; // первообразная потока управления

― угрозе; // нарушение целостности

== уязвимость к атакам инъекций (в зависимости от интерпретатора потока данных: XSS, SQLi, XMLi, XPATHi, Path Traversal, LINQi, XXE и т.п.)

Page 49: Исключительно простая теория AppSec .NET

Предварительная обработка данных

Page 50: Исключительно простая теория AppSec .NET

― Типизация — создание объектного представления входных данных из строкового типа (парсинг и десериализация).

― Санитизация — приведение данных в соответствие с грамматикой, допускаемой политикой защищенности.

― Валидация — проверка данных на соответствие установленным критериям:• грамматическая;• семантическая.

Подходы к предварительной обработке

Page 51: Исключительно простая теория AppSec .NET

Типизация и валидация на входе, санитизация — на выходе!

Смотри, не перепутай…

Page 52: Исключительно простая теория AppSec .NET

Протоколы потоков данных— формальные языки.

Некоторые языки распознаются сложнее, чем остальные.

Для некоторых языков распознавание неразрешимо.

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

Обобщенный подход

Page 53: Исключительно простая теория AppSec .NET

Тестирование эквивалентности конечных автоматов или детерминированных стековых автоматов* разрешимо.

Для недетерминированных стековых автоматов и более мощных моделей вычислений такое тестирование является неразрешимым.

В первом случае возможно полное покрытие тестами элементов парсера языка обрабатываемых данных или их статический анализ.

Во втором случае — НЕТ!

Обобщенный подход

Page 54: Исключительно простая теория AppSec .NET

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

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

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

Обобщенный подход

Page 55: Исключительно простая теория AppSec .NET

Островными – называются языки, грамматики которых описывают правила распознавания отдельных выражений («островов»), окруженных выражениями, принадлежащими другому языку («морем»).

string.Format("SELECT * FROM Table WHERE Id= {0}", Request["Id"]);

море (C#) остров (SQL) море (C#)

Работа с любыми выходными данными сводится к формированию текста на островном языке, а также приводит к образованию новых островных языков, т.к.:

острова с параметрами являются верхнеуровневыми островными языками

Островные языки

Page 56: Исключительно простая теория AppSec .NET

Формальные признаки инъекции― Потенциально уязвимая операция PVO(text):

операция прямой или косвенной интерпретации текста text на формальном островном языке

― text = transform(argument), где argument – элемент множества аргументов точки входа EP, а transform – функция промежуточных преобразований

― Не существует или недостижимо ни одно множество таких значений элементов EP, при которых происходит изменение структуры синтаксического дерева значения text, достигающего PVO, не предусмотренное правилами прочих предметных областей

Page 57: Исключительно простая теория AppSec .NET

1' AND 1=(SELECT COUNT(*) FROM tablenames); --

'><script>alert/XSS/</script><!--

../../../../../../../etc/passwd%00

admin*)((|userPassword=*)

Что общего между ними?

Анатомия атак инъекций

Page 58: Исключительно простая теория AppSec .NET

1' AND 1=(SELECT COUNT(*) FROM tablenames); --

'><script>alert/XSS/</script><!--

../../../../../../../etc/passwd%00

admin*)((|userPassword=*)

Атакующие используют синтаксические элементы основной грамматики, чтобы

выбраться за пределы острова и нарушить целостность потока выполнения принимающей

стороны

Анатомия инъекций

Page 59: Исключительно простая теория AppSec .NET

Какой грамматике соответствует запрос:

SELECT * FROM Table WHERE Id={:int}

?

Островные языки

Page 60: Исключительно простая теория AppSec .NET

select stmt ::= SELECT select list from clause | SELECT select list from clause where clauseselect list ::= id list | *id list ::= id | id , id listfrom clause ::= FROM tbl listtbl list ::= id listwhere clause ::= WHERE bool condbcond ::= bcond OR bterm | btermbterm ::= bterm AND bfactor | bfactorbfactor ::= NOT cond | condcond ::= value comp valuevalue ::= id | str lit | numstr lit ::= ' lit 'comp ::= = | < | > | <= | >= | !=

… (+ еще ~1000 страниц отборной EBNF)

Контекстно-свободная SQL?

Page 61: Исключительно простая теория AppSec .NET

SELECT \* FROM Table WHERE Id=[0-9]+ Море Остров

Явное выделение всех островных грамматик облегчает реализацию контроля выходных

данных

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

Регулярная, островная!

Page 62: Исключительно простая теория AppSec .NET

Пример: LINQ Injection

public AjaxStoreResult GetCustomers(int limit, int start, string dir, string sort){    var query = (from c in this.DBContext.Customers                select new                {                    c.CustomerID,                    c.CompanyName,                    c.ContactName,                    c.Phone,                    c.Fax,                    c.Region                }).OrderBy(string.Concat(sort, " ", dir));

    int total = query.ToList().Count;

    query = query.Skip(start).Take(limit);    return new AjaxStoreResult(query, total);}

Page 63: Исключительно простая теория AppSec .NET

Пример: LINQ Injection

public AjaxStoreResult GetCustomers(int limit, int start, string dir, string sort){    var query = (from c in this.DBContext.Customers                select new                {                    c.CustomerID,                    c.CompanyName,                    c.ContactName,                    c.Phone,                    c.Fax,                    c.Region                }).OrderBy(string.Concat(sort, " ", dir));

    int total = query.ToList().Count;

    query = query.Skip(start).Take(limit);    return new AjaxStoreResult(query, total);}

Page 64: Исключительно простая теория AppSec .NET

Пример: LINQ Injection

public AjaxStoreResult GetCustomers(int limit, int start, string dir, string sort){ if (!Regex.IsMatch(dir, "(?-m:)(?i:)^asc|desc$")) { dir = "ASC"; } if (!Regex.IsMatch(sort, "(?-m:)(?i:)^customerid|companyname|contactname|phone|fax|region$")) { sort = "CustomerID"; }    var query = (from c in this.DBContext.Customers                select new                {                    c.CustomerID,                    c.CompanyName,                    c.ContactName,                    c.Phone,                    c.Fax,                    c.Region                }).OrderBy(string.Concat(sort, " ", dir));

    var total = query.ToList().Count;    query = query.Skip(start).Take(limit);    return new AjaxStoreResult(query, total);}

Page 65: Исключительно простая теория AppSec .NET

{DEMO}

Page 66: Исключительно простая теория AppSec .NET

Вопросы?

Владимир Кочетков

[email protected]@kochetkov_v

Application Inspector/Compiling Applications Analysis/Team LeadPositive Technologies

Page 67: Исключительно простая теория AppSec .NET