TypeStrings
Background
Injection attacks are the #1 security vulnerability on the web.
This vulnerability occurs when an attacker inputs a string that is later used inside of a command or query. The malicious string contains illegal characters that change how the command is executed.
The most common targets of attack are:
- Database queries (SQL injection)
- HTML output (XSS, or Cross-Site Scripting)
- System commands
To mitigate this risk, THT introduces TypeStrings, which are literal strings prefixed with a type identifier.
How TypeStrings Work
Unlike regular strings, TypeStrings can ONLY be combined with other strings through the use of placeholders.
Placeholders (aka parameterized queries) are an industry best practice for securing SQL queries. TypeStrings expand this tactic to cover all types of sensitive strings.
This approach is effective because:
- TypeStrings are literal constants defined at compile time. This means you can trust them to be 100% benign. (Assuming you trust yourself!)
- High risk modules only accept TypeStrings as input.
- TypeStrings automatically escape placeholders safely for their type.
This approach shifts the responsibility of escaping from the programmer to the language, leading to more reliable coverage and less work for you.
How to Use TypeStrings
Just prepend the type to any literal string to mark it as a TypeString.
Example:
$query = sql'select * from users';
Supported types:
-
sql
- SQL queries -
html
- HTML markup -
url
- URLs -
cmd
- System commands -
js
- JavaScript code -
css
- CSS code
TypeStrings can’t be modified like regular strings, so they can’t be accidentally mixed with insecure data.
Example:
// The safe kind of value that we normally // expect from a form field. $userId = '123'; // Instead, here is a malicious value that attempts // to delete an entire database table by using a // semicolon to split it into 2 commands. $userId = '123; drop table users;'; // ✖ ERROR // The TypeString can't be joined with a normal string $q = sql'select * from users where userId = ' ~ $userId;
Filling Placeholder Values
You can attach dynamic values to a TypeString via the fill
method.
These will be safely inserted into placeholders (e.g. {}
), which will be safely escaped by the TypeString class.
Example:
$query = sql'select * from users where userId = {}'; $query.fill($userId); // The Db modules only accepts TypeStrings $row = Db.selectRow($query);
Appending TypeStrings
You can join two TypeString together. Placeholder values will be merged into one list.
$name = html'Name: <b>{}</b>'; $job = html'Job: <b>{}</b>'; $profile = $name ~ $job; print($profile.fill('Theresa', 'Therapist & Teacher')); //= Name: <b>Theresa</b> //= Job: <b>Therapist & Teacher</b>
Aside: TypeStrings vs Immutable Strings
TypeStrings are not the same as “immutable” strings in other languages.
Immutable strings mostly exist for thread safety and performance. They provide no real security against injection: They can still be combined with unsafe user strings to create new (unsafe) Immutable strings.
Methods
See the TypeString class for a list of methods.