<stránka
xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro">
<nadpis>Parametrized queries with Scheme</nadpis>
<perex>passing input parameters and avoiding code-injections</perex>
<m:pořadí-příkladu>01600</m:pořadí-příkladu>
<text xmlns="http://www.w3.org/1999/xhtml">
<p>
<m:name/> are not only for ad-hoc commands but – they could (and probably often should) be used for creating reusable programs.
Such programs are once written, stored in a shell script or shell function or alias and then called many times.
</p>
<p>
For example, we need a script which prints records from our <code>fstab</code> that have given filesystem type.
We could do it this way:
</p>
<m:pre jazyk="bash"><![CDATA[fstab-where-type() {
relpipe-in-fstab \
| relpipe-tr-scheme \
--relation fstab \
--where '(string= $type "'$1'")' \
| relpipe-out-tabular;
}]]></m:pre>
<p>It seems working – e.g. if we call <code>fstab-where-type btrfs</code>, we get:</p>
<m:pre jazyk="text"><![CDATA[fstab:
╭─────────────────┬──────────────────────────────────────┬──────────────────────┬───────────────┬──────────────────┬────────────────┬────────────────╮
│ scheme (string) │ device (string) │ mount_point (string) │ type (string) │ options (string) │ dump (integer) │ pass (integer) │
├─────────────────┼──────────────────────────────────────┼──────────────────────┼───────────────┼──────────────────┼────────────────┼────────────────┤
│ UUID │ a2b5f230-a795-4f6f-a39b-9b57686c86d5 │ /home │ btrfs │ relatime │ 0 │ 2 │
╰─────────────────┴──────────────────────────────────────┴──────────────────────┴───────────────┴──────────────────┴────────────────┴────────────────╯
Record count: 1]]></m:pre>
<p>
But it is fundamentally wrong. The input parameter is blindly pasted in middle of the Scheme code.
So if we call e.g. <code>fstab-where-type 'ext4"'</code>, it crashes terribly.
Do you remember SQL injections in your first PHP scripts when you were 14?
Do not do it again!
</p>
<p>
The <code>relpipe-tr-scheme</code> tool has a safe way for passing parameters from the outside. And such parameters are even strongly typed.
So this is, how our program should be written:
</p>
<m:pre jazyk="bash"><![CDATA[fstab-where-type() {
relpipe-in-fstab \
| relpipe-tr-scheme \
--relation fstab \
--define 'myRequestedType' string "$1" \
--where '(string= $type myRequestedType)' \
| relpipe-out-tabular;
}]]></m:pre>
<p>
So when we call <code>fstab-where-type 'ext4"'</code> again, there is no crash, no code-injection.
Just empty relation is returned because there is no record <code>WHERE type = 'ext4"'</code> (said in SQL words).
</p>
<p>
Now it is like we do a parametrized query in SQL:
</p>
<m:pre jazyk="sql"><![CDATA[SELECT * FROM fstab WHERE type = :myRequestedType;]]></m:pre>
<p>
And bind the <code>myRequestedType</code> parameter.
</p>
</text>
</stránka>