parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

offtop: про таинтизмы понятным языком (имхо)

Watcher 24.10.2019 01:59

0. Схема:

У запущенного скрипта есть входные, внутренние и выходные данные.
Т.е.условно поток выглядит так, и с точки зрения обработки потока всех данных
есть 3 основные фазы:

IN - накопление/получение входных данных за все время работы скрипта
RUNTIME - какая-то работа с данными в процессе работы скрипта
OUT - вывод/отдача данных в самом конце(!) после отработки скрипта
 
read-files     --+        (RUNTIME)         +-- write-files 
http-forms/get --+-> (IN)  script.p (OUT) >-+-- http-response
sql-result     --+                          +-- sql-query 
...                                            ...
Схема построена так, что все строковые(!) данные полученные извне (т.е. незахардкоденные руками в коде, в виде значений переменных или html-текста прям в скрипте руками программиста) по-умолчанию нуждаются в "карантине" чтобы потом если какие-то входные данные или их кусочки попадут в OUT, то они не просачивались как-есть (as-is), а автоматически или кастомно подвергались преобразованию (экранировнию) дабы превентивно избегать xss-уязвимостей.

Механизм реализован так, что во время всей работы скрипта, он накапливает входные данные из внешних источников, и все эти входные данные "невидимо"(для кода) помечаются (маркируются), и только перед непосредственной отдачей во вне, эти данные мгновенно преобразуются (экранирование/замена опасных символов).

Если ничего кастомно не трогать, то по-умолчанию данные(строки/стринги) из всех внешних источников автоматически красятся в "dirty" - неопределенно грязные или т.н. "общий автоматический случай".

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

Но(!) если кодер хочет немного подстроить маркировку входных данных(строк), чтобы получить на выход более желаемое преобразование, он может принудительно перекрасить "dirty" в какой-то ручной тип маркировки типа file-spec или url, чтобы экранировалось и заменялось всё не по правилу общего случая, а по конкретному. А может вообще очистить от какой бы то ни было маркировки (as-is)

И еще главное! Весь этот механизм работает только(!) со строками и подстроками. Т.е. весь этот винегрет маркировок живет только внутри стрингов, причем по-символьно, т.е. над каждым символом стринга (невидимо висит маркер определенного типа или его отсутствие).

А теперь собсна, сами операторы для работы со всем этим механизмом:

1. Все входные извне стринги автоматически красятся в маркер общего случая (dirty) *документация Парсера его называет tainted чтоб вы запутались с самого начала.



2. Оператор ^taint[тип][string] красит строку в заданный тип, если тип не указать то по-умолчанию покрасит в dirty. По сути надо, чтобы или перекрасить обратно в dirty то, что где-то по коду красили в другое. Или по какой-то причине покрасить часть ваших захардкоденных стрингов в грязные по общему случаю (ну мало ли). Если надо просто почистить от каких бы то ни было маркировок строку, то в качестве типа указываем тип "as-is", т.е. оставить данные как-есть, и снять маркировку.



3. Оператор ^untaint[тип]{string} - делает практически то же самое, но красит не всю указанную строку, а только те символы из строки, которые уже выкрашены в именно цвет dirty (грязный по общему случаю). Ну и чтобы вы окончательно и бесповоротно запутались, то ли историческая сырость первых версий, то ли какие-то нереализованные задумки раннего авторства (PAF'a) -- предлагают вам синтаксис с фигурными скобками и словом (код) в качестве аргумента.

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

Поэтому, в уме просто представьте несуществующий, но более логический синтаксис ^untaint[тип][string], а еще лучше ^taint[тип][string][but-only-for-dirty-parts]

Т.е. ^untaint не обратная операция по отношению к ^taint, это просто такой же taint но применяемый не ко всей строке принудительно, а выборочно только для dirty-цвета.



4. Dirty-цвет в документации называют tainted - чтоб уж добить молодого бойца с гарантией :) Видите цвет tainted (в уме говорите dirty, чтобы не путать с оператором)


5. Оператор ^apply-taint[тип][строка] - применяет преобразование со строкой сразу по коду, в то время как обычный taint делает реальное преобразование стрингов(строк) только неподсрественно при отдаче во вне.

6. Каждый символ каждой строки в процессе скрипта несет свой индивидуальный маркер или его отсутствие.

Таким образом, получив кучу строк из нескольких источников, часть из которых, будут автоматически покрашены в dirty, часть, например, вы подкрасите в нужный цвет, и часть будут чистыми изначально, и потом где-то в коде все это многократно смешается, например в одну строку, той же банальной конкатенацией, то в итоге вы получите "стринг-винегрет" где каждый кусок строки, а точнее символ будет выкрашен в свой цвет. В этом собственно и суть удержания контроля над грязностью данных.
  $a[$form:a] <- это автоматически в dirty-цвете
  $b[^taint[url][http://site]]  <- это вручную в url-цвете
  $c[hello] <- это в as-is цвете, т.е. значение забито кодером
  $d[$a$b$c]  <- эта "колбаса" сохранит все цвета составных строк посимвольно
                 т.е. будет состоять из dirty,url и as-is цвета.
  
  ^untaint{$d}  <- перекрасит в as-is только те куски строки (символы), которые были dirty-цвета.
                   в итоге строковая "колбаса" будет состоять из символов as-is и url-цветов (маркеров).
P.S.: Надеюсь не запутал еще сильнее ))