Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add documentation regarding tainted strings in TH1. Mention the introduction of tainted strings in the 2.25 change log. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
90b63bc5d142d1eaa326e205bb8e1526 |
| User & Date: | drh 2025-04-24 15:04:20.894 |
Context
|
2025-04-24
| ||
| 15:19 | Fix the version numbers in the new documentation on tainted strings. ... (check-in: 807b73e6b5 user: drh tags: trunk) | |
| 15:04 | Add documentation regarding tainted strings in TH1. Mention the introduction of tainted strings in the 2.25 change log. ... (check-in: 90b63bc5d1 user: drh tags: trunk) | |
| 11:18 | Preserve taint across TH1 commands: foreach, lappend, lindex, string index, string range, and string trim. Add test cases for taint. ... (check-in: 5291edac07 user: drh tags: trunk) | |
Changes
Changes to www/changes.wiki.
| ︙ | ︙ | |||
136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
* Add a "user permissions changes" [/doc/trunk/www/alerts.md|subscription]
which alerts subscribers when an admin creates a new user or
when a user's permissions change.
* Show project description on repository list.
* Make [/help?cmd=/chat|/chat] better-behaved during server outages, reducing
the frequency of reconnection attempts over time and providing feedback
to the user when the connection is down.
* Diverse minor fixes and additions.
<h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
* The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
that have non-ASCII filenames
| > > > > > > > | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
* Add a "user permissions changes" [/doc/trunk/www/alerts.md|subscription]
which alerts subscribers when an admin creates a new user or
when a user's permissions change.
* Show project description on repository list.
* Make [/help?cmd=/chat|/chat] better-behaved during server outages, reducing
the frequency of reconnection attempts over time and providing feedback
to the user when the connection is down.
* The [/doc/trunk/www/th1.md|TH1 script language] now makes a distinction
between [/doc/trunk/www/th1.md#taint|tainted and untainted string values].
This is a security enhancement that makes it more difficult to write
custom TH1 scripts that contain XSS or SQL-injection bugs. As part of
this enhancement, the [/help?cmd=vuln-report|vuln-report] setting was
added to control what Fossil does when it encounters a potential TH1
security problem.
* Diverse minor fixes and additions.
<h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
* The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
that have non-ASCII filenames
|
| ︙ | ︙ |
Changes to www/th1.md.
| ︙ | ︙ | |||
66 67 68 69 70 71 72 |
of the command, is `if`.
The second token is `$current eq "dev"` - an expression. (The outer {...}
are removed from each token by the command parser.) The third token
is the `puts "hello"`, with its whitespace and newlines. The fourth token
is `else` and the fifth and last token is `puts "world"`.
The `if` command evaluates its first argument (the second token)
| | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
of the command, is `if`.
The second token is `$current eq "dev"` - an expression. (The outer {...}
are removed from each token by the command parser.) The third token
is the `puts "hello"`, with its whitespace and newlines. The fourth token
is `else` and the fifth and last token is `puts "world"`.
The `if` command evaluates its first argument (the second token)
as an expression, and if that expression is true, it evaluates its
second argument (the third token) as a TH1 script.
If the expression is false and the third argument is `else`, then
the fourth argument is evaluated as a TH1 expression.
So, you see, even though the example above spans five lines, it is really
just a single command.
|
| ︙ | ︙ | |||
104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
return [lindex [regexp -line -inline -nocase -- \
{^uuid:\s+([0-9A-F]{40}) } [eval [getFossilCommand \
$repository "" info trunk]]] end]
Those backslashes allow the command to wrap nicely within a standard
terminal width while telling the interpreter to consider those three
lines as a single command.
Summary of Core TH1 Commands
----------------------------
The original Tcl language (after which TH1 is modeled) has a very rich
repertoire of commands. TH1, as it is designed to be minimalist and
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
return [lindex [regexp -line -inline -nocase -- \
{^uuid:\s+([0-9A-F]{40}) } [eval [getFossilCommand \
$repository "" info trunk]]] end]
Those backslashes allow the command to wrap nicely within a standard
terminal width while telling the interpreter to consider those three
lines as a single command.
<a id="taint"></a>Tainted And Untainted Strings
-----------------------------------------------
Beginning with Fossil version 2.25 (circa 2025), TH1 distinguishes between
"tainted" and "untainted" strings. Tainted strings are strings that are
derived from user inputs that might contain text that is designed to subvert
the script. Untainted strings are known to come from secure sources and
are assumed to contain no malicious content.
Beginning with Fossil version 2.25, and depending on the value of the
[vuln-report setting](/help?cmd=vuln-report), TH1 will prevent tainted
strings from being used in ways that might lead to XSS or SQL-injection
attacks. This feature helps to ensure that XSS and SQL-injection
vulnerabilities are not *accidentally* added to Fossil when
custom TH1 scripts for headers or footers or tickets are added to a
repository. Note that the tainted/untainted distinction in strings does
make it impossible to introduce XSS and SQL-injections vulnerabilities
using poorly-written TH1 scripts; it just makes it more difficult and
less likely to happen by accident. Developers must still consider the
security implications TH1 customizations they add to Fossil, and take
appropriate precautions when writing custom TH1. Peer review of TH1
script changes is encouraged.
In Fossil version 2.25, if the vuln-report setting is set to "block"
or "fatal", the [html](#html) and [query](#query) TH1 commands will
fail with an error if their argument is a tainted string. This helps
to prevent XSS and SQL-injection attacks, respectively. Note that
the default value of the vuln-report setting is "log", which allows those
commands to continue working and only writes a warning message into the
error log. <b>Future versions of Fossil may change the default value
of the vuln-report setting to "block" or "fatal".</b> Fossil users
with customized TH1 scripts are encouraged to audit their customizations
and fix any potential vulnerabilities soon, so as to avoid breakage
caused by future upgrades. <b>Future versions of Fossil might also
place additional restrictions on the use of tainted strings.</b>
For example, it is likely that future versions of Fossil will disallow
using tainted strings as script, for example as the body of a "for"
loop or of a "proc".
Summary of Core TH1 Commands
----------------------------
The original Tcl language (after which TH1 is modeled) has a very rich
repertoire of commands. TH1, as it is designed to be minimalist and
|
| ︙ | ︙ | |||
145 146 147 148 149 150 151 152 153 154 155 156 157 158 | * string index STRING INDEX * string is CLASS STRING * string last NEEDLE HAYSTACK ?START-INDEX? * string match PATTERN STRING * string length STRING * string range STRING FIRST LAST * string repeat STRING COUNT * unset VARNAME * uplevel ?LEVEL? SCRIPT * upvar ?FRAME? OTHERVAR MYVAR ?OTHERVAR MYVAR? All of the above commands work as in the original Tcl. Refer to the <a href="https://www.tcl-lang.org/man/tcl/contents.htm">Tcl documentation</a> for details. | > > > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | * string index STRING INDEX * string is CLASS STRING * string last NEEDLE HAYSTACK ?START-INDEX? * string match PATTERN STRING * string length STRING * string range STRING FIRST LAST * string repeat STRING COUNT * string trim STRING * string trimleft STRING * string trimright STRING * unset VARNAME * uplevel ?LEVEL? SCRIPT * upvar ?FRAME? OTHERVAR MYVAR ?OTHERVAR MYVAR? All of the above commands work as in the original Tcl. Refer to the <a href="https://www.tcl-lang.org/man/tcl/contents.htm">Tcl documentation</a> for details. |
| ︙ | ︙ | |||
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | * [setParameter](#setParameter) * [setting](#setting) * [stime](#stime) * [styleHeader](#styleHeader) * [styleFooter](#styleFooter) * [styleScript](#styleScript) * [submenu](#submenu) * [tclEval](#tclEval) * [tclExpr](#tclExpr) * [tclInvoke](#tclInvoke) * [tclIsSafe](#tclIsSafe) * [tclMakeSafe](#tclMakeSafe) * [tclReady](#tclReady) * [trace](#trace) * [unversioned content](#unversioned_content) * [unversioned list](#unversioned_list) * [utime](#utime) * [verifyCsrf](#verifyCsrf) * [verifyLogin](#verifyLogin) * [wiki](#wiki) * [wiki_assoc](#wiki_assoc) | > > | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | * [setParameter](#setParameter) * [setting](#setting) * [stime](#stime) * [styleHeader](#styleHeader) * [styleFooter](#styleFooter) * [styleScript](#styleScript) * [submenu](#submenu) * [taint](#taintCmd) * [tclEval](#tclEval) * [tclExpr](#tclExpr) * [tclInvoke](#tclInvoke) * [tclIsSafe](#tclIsSafe) * [tclMakeSafe](#tclMakeSafe) * [tclReady](#tclReady) * [trace](#trace) * [untaint](#untaintCmd) * [unversioned content](#unversioned_content) * [unversioned list](#unversioned_list) * [utime](#utime) * [verifyCsrf](#verifyCsrf) * [verifyLogin](#verifyLogin) * [wiki](#wiki) * [wiki_assoc](#wiki_assoc) |
| ︙ | ︙ | |||
526 527 528 529 530 531 532 | <a id="html"></a>TH1 html Command ----------------------------------- * html STRING Outputs the STRING literally. It is assumed that STRING contains | | | | > > | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | <a id="html"></a>TH1 html Command ----------------------------------- * html STRING Outputs the STRING literally. It is assumed that STRING contains valid HTML, or that if STRING contains any characters that are significant to HTML (such as `<`, `>`, `'`, or `&`) have already been escaped, perhaps by the [htmlize](#htmlize) command. Use the [puts](#puts) command to output text that might contain unescaped HTML markup. **Beware of XSS attacks!** If the STRING value to the html command can be controlled by a hostile user, then he might be able to sneak in malicious HTML or Javascript which could result in a cross-site scripting (XSS) attack. Be careful that all text that in STRING that might come from user input has been sanitized by the [htmlize](#htmlize) command or similar. In recent versions of Fossil, the STRING value must be [untainted](#taint) or else the "html" command will fail. <a id="htmlize"></a>TH1 htmlize Command ----------------------------------------- * htmlize STRING Escape all characters of STRING which have special meaning in HTML. |
| ︙ | ︙ | |||
608 609 610 611 612 613 614 | ----------------------------------- * puts STRING Outputs STRING. Characters within STRING that have special meaning in HTML are escaped prior to being output. Thus is it safe for STRING to be derived from user inputs. See also the [html](#html) command | | > > | > > > | 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 |
-----------------------------------
* puts STRING
Outputs STRING. Characters within STRING that have special meaning
in HTML are escaped prior to being output. Thus is it safe for STRING
to be derived from user inputs. See also the [html](#html) command
which behaves similarly except does not escape HTML markup. This
command ("puts") is safe to use on [tainted strings](#taint), but the "html"
command is not.
<a id="query"></a>TH1 query Command
-------------------------------------
* query ?-nocomplain? SQL CODE
Runs the SQL query given by the SQL argument. For each row in the result
set, run CODE.
In SQL, parameters such as $var are filled in using the value of variable
"var". Result values are stored in variables with the column name prior
to each invocation of CODE. The names of the variables in which results
are stored can be controlled using "AS name" clauses in the SQL. As
the database will often contain content that originates from untrusted
users, all result values are marked as [tainted](#taint).
**Beware of SQL injections in the `query` command!**
The SQL argument to the query command should always be literal SQL
text enclosed in {...}. The SQL argument should never be a double-quoted
string or the value of a \$variable, as those constructs can lead to
an SQL Injection attack. If you need to include the values of one or
more TH1 variables as part of the SQL, then put \$variable inside the
|
| ︙ | ︙ | |||
647 648 649 650 651 652 653 654 655 656 657 658 659 660 |
~~~
query "SELECT res FROM tab1 WHERE key='$mykey'" {...} ;# <-- UNSAFE!
~~~
In this second example, TH1 does the expansion of `$mykey` prior to passing
the text down into SQLite. So if `$mykey` contains a single-quote character,
followed by additional hostile text, that will result in an SQL injection.
<a id="randhex"></a>TH1 randhex Command
-----------------------------------------
* randhex N
Returns a string of N*2 random hexadecimal digits with N<50. If N is
| > > > > | 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 |
~~~
query "SELECT res FROM tab1 WHERE key='$mykey'" {...} ;# <-- UNSAFE!
~~~
In this second example, TH1 does the expansion of `$mykey` prior to passing
the text down into SQLite. So if `$mykey` contains a single-quote character,
followed by additional hostile text, that will result in an SQL injection.
To help guard against SQL-injections, recent versions of Fossil require
that the SQL argument be [untainted](#taint) or else the "query" command
will fail.
<a id="randhex"></a>TH1 randhex Command
-----------------------------------------
* randhex N
Returns a string of N*2 random hexadecimal digits with N<50. If N is
|
| ︙ | ︙ | |||
781 782 783 784 785 786 787 788 789 790 791 792 793 794 | <a id="submenu"></a>TH1 submenu Command ----------------------------------------- * submenu link LABEL URL Add hyperlink to the submenu of the current page. <a id="tclEval"></a>TH1 tclEval Command ----------------------------------------- **This command requires the Tcl integration feature.** * tclEval arg ?arg ...? | > > > > > > > > > > > > > > | 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | <a id="submenu"></a>TH1 submenu Command ----------------------------------------- * submenu link LABEL URL Add hyperlink to the submenu of the current page. <a id="taintCmd"></a>TH1 taint Command ----------------------------------------- * taint STRING This command returns a copy of STRING that has been marked as [tainted](#taint). Tainted strings are strings which might be controlled by an attacker and might contain hostile inputs and are thus unsafe to use in certain contexts. For example, tainted strings should not be output as part of a webpage as they might contain rogue HTML or Javascript that could lead to an XSS vulnerability. Similarly, tainted strings should not be run as SQL since they might contain an SQL-injection vulerability. <a id="tclEval"></a>TH1 tclEval Command ----------------------------------------- **This command requires the Tcl integration feature.** * tclEval arg ?arg ...? |
| ︙ | ︙ | |||
852 853 854 855 856 857 858 859 860 861 862 863 864 865 | <a id="trace"></a>TH1 trace Command ------------------------------------- * trace STRING Generates a TH1 trace message if TH1 tracing is enabled. <a id="unversioned_content"></a>TH1 unversioned content Command ----------------------------------------------------------------- * unversioned content FILENAME Attempts to locate the specified unversioned file and return its contents. An error is generated if the repository is not open or the unversioned file | > > > > > > > > > > > > | 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 | <a id="trace"></a>TH1 trace Command ------------------------------------- * trace STRING Generates a TH1 trace message if TH1 tracing is enabled. <a id="untaintCmd"></a>TH1 taint Command ----------------------------------------- * untaint STRING This command returns a copy of STRING that has been marked as [untainted](#taint). Untainted strings are strings which are believed to be free of potentially hostile content. Use this command with caution, as it overwrites the tainted-string protection mechanisms that are built into TH1. If you do not understand all the implications of executing this command, then do not use it. <a id="unversioned_content"></a>TH1 unversioned content Command ----------------------------------------------------------------- * unversioned content FILENAME Attempts to locate the specified unversioned file and return its contents. An error is generated if the repository is not open or the unversioned file |
| ︙ | ︙ |