Skip to content

Commit d12eaff

Browse files
committed
Update docs for barriers and barrier guards
1 parent 7fab0b6 commit d12eaff

7 files changed

+507
-0
lines changed

docs/codeql/codeql-language-guides/customizing-library-models-for-cpp.rst

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,88 @@ The remaining values are used to define the input and output specifications, the
178178
- The ninth value ``"taint"`` is the kind of the flow. ``taint`` means that taint is propagated through the call.
179179
- The tenth value ``"manual"`` is the provenance of the summary, which is used to identify the origin of the summary model.
180180

181+
Example: Taint barrier using the ``mysql_real_escape_string`` function
182+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183+
184+
This example shows how the CPP query pack models the ``mysql_real_escape_string`` function as a barrier for SQL injection.
185+
This function escapes special characters in a string for use in an SQL statement, which prevents SQL injection attacks.
186+
187+
.. code-block:: cpp
188+
189+
char *query = "SELECT * FROM users WHERE name = '%s'";
190+
char *name = get_untrusted_input();
191+
char *escaped_name = new char[2 * strlen(name) + 1];
192+
mysql_real_escape_string(mysql, escaped_name, name, strlen(name)); // The escaped_name is safe for SQL injection.
193+
sprintf(query_buffer, query, escaped_name);
194+
195+
We need to add a tuple to the ``barrierModel``\(namespace, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate by updating a data extension file.
196+
197+
.. code-block:: yaml
198+
199+
extensions:
200+
- addsTo:
201+
pack: codeql/cpp-all
202+
extensible: barrierModel
203+
data:
204+
- ["", "", False, "mysql_real_escape_string", "", "", "Argument[*1]", "sql-injection", "manual"]
205+
206+
Since we are adding a barrier, we need to add a tuple to the ``barrierModel`` extensible predicate.
207+
The first five values identify the callable (in this case a free function) to be modeled as a barrier.
208+
209+
- The first value ``""`` is the namespace name.
210+
- The second value ``""`` is the name of the type (class) that contains the method. Because we're modelling a free function, the type is left blank.
211+
- The third value ``False`` is a flag that indicates whether or not the barrier also applies to all overrides of the method. For a free function, this should be ``False``.
212+
- The fourth value ``"mysql_real_escape_string"`` is the function name.
213+
- The fifth value is the function input type signature, which can be used to narrow down between functions that have the same name.
214+
215+
The sixth value should be left empty and is out of scope for this documentation.
216+
The remaining values are used to define the output specification, the ``kind``, and the ``provenance`` (origin) of the barrier.
217+
218+
- The seventh value ``"Argument[*1]"`` is the output specification, which means in this case that the barrier is the first indirection (or pointed-to value, ``*``) of the second argument (``Argument[1]``) passed to the function.
219+
- The eighth value ``"sql-injection"`` is the kind of the barrier. The barrier kind is used to define the queries where the barrier is in scope.
220+
- The ninth value ``"manual"`` is the provenance of the barrier, which is used to identify the origin of the barrier model.
221+
222+
Example: Add a barrier guard
223+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
224+
225+
This example shows how to model a barrier guard that stops the flow of taint when a conditional check is performed on data.
226+
A barrier guard model is used when a function returns a boolean that indicates whether the data is safe to use.
227+
Consider a function called ``is_safe`` which returns ``true`` when the data is considered safe.
228+
229+
.. code-block:: cpp
230+
231+
if (is_safe(user_input)) { // The check guards the use, so the input is safe.
232+
mysql_query(user_input); // This is safe.
233+
}
234+
235+
We need to add a tuple to the ``barrierGuardModel``\(namespace, type, subtypes, name, signature, ext, input, acceptingvalue, kind, provenance) extensible predicate by updating a data extension file.
236+
237+
.. code-block:: yaml
238+
239+
extensions:
240+
- addsTo:
241+
pack: codeql/cpp-all
242+
extensible: barrierGuardModel
243+
data:
244+
- ["", "", False, "is_safe", "", "", "Argument[*0]", "true", "sql-injection", "manual"]
245+
246+
Since we are adding a barrier guard, we need to add a tuple to the ``barrierGuardModel`` extensible predicate.
247+
The first five values identify the callable (in this case a free function) to be modeled as a barrier guard.
248+
249+
- The first value ``""`` is the namespace name.
250+
- The second value ``""`` is the name of the type (class) that contains the method. Because we're modelling a free function, the type is left blank.
251+
- The third value ``False`` is a flag that indicates whether or not the barrier guard also applies to all overrides of the method. For a free function, this should be ``False``.
252+
- The fourth value ``"is_safe"`` is the function name.
253+
- The fifth value is the function input type signature, which can be used to narrow down between functions that have the same name.
254+
255+
The sixth value should be left empty and is out of scope for this documentation.
256+
The remaining values are used to define the input specification, the ``accepting value``, the ``kind``, and the ``provenance`` (origin) of the barrier guard.
257+
258+
- The seventh value ``Argument[*0]`` is the input specification (the value being validated). In this case, the first indirection (or pointed-to value, ``*``) of the first argument (``Argument[0]``) passed to the function.
259+
- The eighth value ``true`` is the accepting value of the barrier guard. This is the value that the conditional check must return for the barrier to apply.
260+
- The ninth value ``sql-injection`` is the kind of the barrier guard. The barrier guard kind is used to define the queries where the barrier guard is in scope.
261+
- The tenth value ``manual`` is the provenance of the barrier guard, which is used to identify the origin of the barrier guard.
262+
181263
.. _threat-models-cpp:
182264

183265
Threat models

docs/codeql/codeql-language-guides/customizing-library-models-for-csharp.rst

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,90 @@ For the remaining values for both rows:
309309

310310
That is, the first row specifies that values can flow from the elements of the qualifier enumerable into the first argument of the function provided to ``Select``. The second row specifies that values can flow from the return value of the function to the elements of the enumerable returned from ``Select``.
311311

312+
Example: Add a barrier for the ``RawUrl`` property
313+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
314+
This example shows how we can model a property as a barrier for a specific kind of query.
315+
A barrier model is used to define that the flow of taint stops at the modeled element for the specified kind of query.
316+
Here we model the getter of the ``RawUrl`` property of the ``HttpRequest`` class as a barrier for URL redirection queries.
317+
The ``RawUrl`` property returns the raw URL of the current request, which is considered safe for URL redirects because it is the URL of the current request and cannot be manipulated by an attacker.
318+
319+
.. code-block:: csharp
320+
321+
public static void TaintBarrier(HttpRequest request) {
322+
string url = request.RawUrl; // The return value of this property is considered safe for URL redirects.
323+
Response.Redirect(url); // This is not a URL redirection vulnerability.
324+
}
325+
326+
We need to add a tuple to the ``barrierModel``\(namespace, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate by updating a data extension file.
327+
328+
.. code-block:: yaml
329+
330+
extensions:
331+
- addsTo:
332+
pack: codeql/csharp-all
333+
extensible: barrierModel
334+
data:
335+
- ["System.Web", "HttpRequest", False, "get_RawUrl", "()", "", "ReturnValue", "url-redirection", "manual"]
336+
337+
Since we are adding a barrier, we need to add a tuple to the ``barrierModel`` extensible predicate.
338+
The first five values identify the callable (in this case the getter of a property) to be modeled as a barrier.
339+
340+
- The first value ``System.Web`` is the namespace name.
341+
- The second value ``HttpRequest`` is the class (type) name.
342+
- The third value ``False`` is a flag that indicates whether or not the barrier also applies to all overrides of the method.
343+
- The fourth value ``get_RawUrl`` is the method name. Getter and setter methods are named ``get_<name>`` and ``set_<name>`` respectively.
344+
- The fifth value ``()`` is the method input type signature.
345+
346+
The sixth value should be left empty and is out of scope for this documentation.
347+
The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the barrier.
348+
349+
- The seventh value ``ReturnValue`` is the access path to the return value of the property getter, which means that the return value is considered safe.
350+
- The eighth value ``url-redirection`` is the kind of the barrier. The barrier kind is used to define the queries where the barrier is in scope. In this case - the URL redirection queries.
351+
- The ninth value ``manual`` is the provenance of the barrier, which is used to identify the origin of the barrier.
352+
353+
Example: Add a barrier guard for the ``IsAbsoluteUri`` property
354+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
355+
This example shows how we can model a property as a barrier guard for a specific kind of query.
356+
A barrier guard model is used to stop the flow of taint when a conditional check is performed on data.
357+
Here we model the getter of the ``IsAbsoluteUri`` property of the ``Uri`` class as a barrier guard for URL redirection queries.
358+
When the ``IsAbsoluteUri`` property returns ``false``, the URL is relative and therefore safe for URL redirects because it cannot redirect to an external site controlled by an attacker.
359+
360+
.. code-block:: csharp
361+
362+
public static void TaintBarrierGuard(Uri uri) {
363+
if (!uri.IsAbsoluteUri) { // The check guards the redirect, so the URL is safe.
364+
Response.Redirect(uri.ToString()); // This is not a URL redirection vulnerability.
365+
}
366+
}
367+
368+
We need to add a tuple to the ``barrierGuardModel``\(namespace, type, subtypes, name, signature, ext, input, acceptingvalue, kind, provenance) extensible predicate by updating a data extension file.
369+
370+
.. code-block:: yaml
371+
372+
extensions:
373+
- addsTo:
374+
pack: codeql/csharp-all
375+
extensible: barrierGuardModel
376+
data:
377+
- ["System", "Uri", False, "get_IsAbsoluteUri", "()", "", "Argument[this]", "false", "url-redirection", "manual"]
378+
379+
Since we are adding a barrier guard, we need to add a tuple to the ``barrierGuardModel`` extensible predicate.
380+
The first five values identify the callable (in this case the getter of a property) to be modeled as a barrier guard.
381+
382+
- The first value ``System`` is the namespace name.
383+
- The second value ``Uri`` is the class (type) name.
384+
- The third value ``False`` is a flag that indicates whether or not the barrier guard also applies to all overrides of the method.
385+
- The fourth value ``get_IsAbsoluteUri`` is the method name. Getter and setter methods are named ``get_<name>`` and ``set_<name>`` respectively.
386+
- The fifth value ``()`` is the method input type signature.
387+
388+
The sixth value should be left empty and is out of scope for this documentation.
389+
The remaining values are used to define the ``access path``, the ``accepting value``, the ``kind``, and the ``provenance`` (origin) of the barrier guard.
390+
391+
- The seventh value ``Argument[this]`` is the access path to the input whose flow is blocked. In this case, the qualifier of the property access (``uri`` in the example).
392+
- The eighth value ``false`` is the accepting value of the barrier guard. This is the value that the conditional check must return for the barrier to apply. In this case, when ``IsAbsoluteUri`` is ``false``, the URL is relative and considered safe.
393+
- The ninth value ``url-redirection`` is the kind of the barrier guard. The barrier guard kind is used to define the queries where the barrier guard is in scope. In this case - the URL redirection queries.
394+
- The tenth value ``manual`` is the provenance of the barrier guard, which is used to identify the origin of the barrier guard.
395+
312396
Example: Add a ``neutral`` method
313397
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
314398
This example shows how we can model a method as being neutral with respect to flow. We will also cover how to model a property by modeling the getter of the ``Now`` property of the ``DateTime`` class as neutral.

docs/codeql/codeql-language-guides/customizing-library-models-for-go.rst

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,88 @@ The remaining values are used to define the ``access path``, the ``kind``, and t
341341
- The ninth value ``taint`` is the kind of the flow. ``taint`` means that taint is propagated through the call.
342342
- The tenth value ``manual`` is the provenance of the summary, which is used to identify the origin of the summary.
343343

344+
Example: Add a barrier using the ``Htmlquote`` function
345+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
346+
This example shows how the Go query pack models a barrier that stops the flow of taint.
347+
The ``Htmlquote`` function from the beego framework HTML-escapes a string, which prevents HTML injection attacks.
348+
349+
.. code-block:: go
350+
351+
func Render(w http.ResponseWriter, r *http.Request) {
352+
name := r.FormValue("name")
353+
safe := beego.Htmlquote(name) // The return value of this function is safe to use in HTML.
354+
...
355+
}
356+
357+
We need to add a tuple to the ``barrierModel``\(package, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate by updating a data extension file.
358+
359+
.. code-block:: yaml
360+
361+
extensions:
362+
- addsTo:
363+
pack: codeql/go-all
364+
extensible: barrierModel
365+
data:
366+
- ["group:beego", "", True, "Htmlquote", "", "", "ReturnValue", "html-injection", "manual"]
367+
368+
Since we are adding a barrier, we need to add a tuple to the ``barrierModel`` extensible predicate.
369+
The first five values identify the function to be modeled as a barrier.
370+
371+
- The first value ``group:beego`` is the package group name. The ``group:`` prefix indicates that this is a package group, which is used to match multiple package paths that refer to the same package.
372+
- The second value ``""`` is left blank since the function is not a method of a type.
373+
- The third value ``True`` is a flag that indicates whether or not the barrier also applies to subtypes. This has no effect for non-method functions.
374+
- The fourth value ``Htmlquote`` is the function name.
375+
- The fifth value ``""`` is the input type signature. For Go it should always be an empty string.
376+
377+
The sixth value should be left empty and is out of scope for this documentation.
378+
The remaining values are used to define the ``access path``, the ``kind``, and the ``provenance`` (origin) of the barrier.
379+
380+
- The seventh value ``ReturnValue`` is the access path to the output of the barrier, which means that the return value is considered sanitized.
381+
- The eighth value ``html-injection`` is the kind of the barrier. The barrier kind must match the kind used in the query where the barrier should take effect. In this case, it matches the ``html-injection`` sink kind used by XSS queries.
382+
- The ninth value ``manual`` is the provenance of the barrier, which is used to identify the origin of the barrier.
383+
384+
Example: Add a barrier guard
385+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
386+
This example shows how to model a barrier guard that stops the flow of taint when a conditional check is performed on data.
387+
A barrier guard model is used when a function returns a boolean that indicates whether the data is safe to use.
388+
Consider a function called ``IsSafe`` which returns ``true`` when the data is considered safe for SQL injection.
389+
390+
.. code-block:: go
391+
392+
func Query(db *sql.DB, input string) {
393+
if example.IsSafe(input) { // The check guards the query, so the input is safe.
394+
db.Query(input) // This is not a SQL injection vulnerability.
395+
}
396+
}
397+
398+
We need to add a tuple to the ``barrierGuardModel``\(package, type, subtypes, name, signature, ext, input, acceptingvalue, kind, provenance) extensible predicate by updating a data extension file.
399+
400+
.. code-block:: yaml
401+
402+
extensions:
403+
- addsTo:
404+
pack: codeql/go-all
405+
extensible: barrierGuardModel
406+
data:
407+
- ["example.com/example", "", False, "IsSafe", "", "", "Argument[0]", "true", "sql-injection", "manual"]
408+
409+
Since we are adding a barrier guard, we need to add a tuple to the ``barrierGuardModel`` extensible predicate.
410+
The first five values identify the function to be modeled as a barrier guard.
411+
412+
- The first value ``example.com/example`` is the package name.
413+
- The second value ``""`` is left blank since the function is not a method of a type.
414+
- The third value ``False`` is a flag that indicates whether or not the barrier guard also applies to subtypes. This has no effect for non-method functions.
415+
- The fourth value ``IsSafe`` is the function name.
416+
- The fifth value ``""`` is the input type signature. For Go it should always be an empty string.
417+
418+
The sixth value should be left empty and is out of scope for this documentation.
419+
The remaining values are used to define the ``access path``, the ``accepting value``, the ``kind``, and the ``provenance`` (origin) of the barrier guard.
420+
421+
- The seventh value ``Argument[0]`` is the access path to the input whose flow is blocked. In this case, the first argument to the function (``input`` in the example).
422+
- The eighth value ``true`` is the accepting value of the barrier guard. This is the value that the conditional check must return for the barrier to apply. In this case, when ``IsSafe`` returns ``true``, the input is considered safe.
423+
- The ninth value ``sql-injection`` is the kind of the barrier guard. The barrier guard kind is used to define the queries where the barrier guard is in scope. In this case - the SQL injection queries.
424+
- The tenth value ``manual`` is the provenance of the barrier guard, which is used to identify the origin of the barrier guard.
425+
344426
Example: Accessing the ``Body`` field of an HTTP request
345427
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
346428
This example shows how we can model a field read as a source of tainted data.

0 commit comments

Comments
 (0)