Я разрабатываю веб-приложение с использованием F #. Думая о защите пользовательских строк ввода от SQL, XSS и других уязвимостей.
В двух словах, мне нужны некоторые ограничения времени компиляции, которые позволили бы мне отличать простые строки от тех, которые представляют SQL, URL, XSS, XHTML и т. Д.
У многих языков есть, например. Встроенная в Ruby функция интерполяции строк #{...}
.
В F # кажется, что единицы измерения работают очень хорошо, но они доступны только для числовых типов.
Есть несколько решений, использующих время выполнения UoM (ссылка) , однако я думаю, что это накладные расходы для моей цели.
Я посмотрел на FSharpPowerPack, и вполне возможно придумать что-то похожее для строк:
[<MeasureAnnotatedAbbreviation>] type string<[<Measure>] 'u> = string
// Similarly to Core.LanguagePrimitives.IntrinsicFunctions.retype
[<NoDynamicInvocation>]
let inline retype (x:'T) : 'U = (# "" x : 'U #)
let StringWithMeasure (s: string) : string<'u> = retype s
[<Measure>] type plain
let fromPlain (s: string<plain>) : string =
// of course, this one should be implemented properly
// by invalidating special characters and then assigning a proper UoM
retype s
// Supposedly populated from user input
let userName:string<plain> = StringWithMeasure "John'); DROP TABLE Users; --"
// the following line does not compile
let sql1 = sprintf "SELECT * FROM Users WHERE name='%s';" userName
// the following line compiles fine
let sql2 = sprintf "SELECT * FROM Users WHERE name='%s';" (fromPlain userName)
Примечание : это просто образец; не предлагайте использовать SqlParameter
. : -)
Мои вопросы: есть ли приличная библиотека, которая делает это? Есть ли возможность добавить синтаксис сахара?
Спасибо.
Обновление 1 : мне нужны ограничения во время компиляции, спасибо Даниэль.
Обновление 2 : я пытаюсь избежать любых накладных расходов во время выполнения (кортежей, структур, различающихся объединений и т. Д.).