examples: Parametrized queries with Guile v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Thu, 07 Feb 2019 14:30:42 +0100
branchv_0
changeset 247 087b8621fb3e
parent 246 fde0cd94fde6
child 248 e76ca9f7d6cb
examples: Parametrized queries with Guile
relpipe-data/examples-guile-parametrized-queries.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relpipe-data/examples-guile-parametrized-queries.xml	Thu Feb 07 14:30:42 2019 +0100
@@ -0,0 +1,79 @@
+<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 Guile</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-guile \
+			--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 Guile 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 you remember <a href="https://xkcd.com/327/">XKCD: Exploits of a Mom</a>?
+			Don't do it again!
+		</p>
+		
+		<p>
+			The <code>relpipe-tr-guile</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-guile \
+			--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>