# How to avoid SQL injection risks

**URL:** <https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967>\
**Category:** questions\
**Tags:** sql\
**Created:** [February 20, 2026, 12:45am UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967 "2026-02-20T00:45:59Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![PurpleEdge2214](https://clarionhub.com/user_avatar/clarionhub.com/purpleedge2214/32/5109_2.png) [@PurpleEdge2214](https://clarionhub.com/u/PurpleEdge2214)\
**Post date:** [February 19, 2026, 10:47pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/1 "2026-02-19T22:47:26Z")

</div>

How does one avoid SQL injection risks, in Clarion, apart from using a SQL function and passing parameters to the function?

---

<div class="post-metadata">

**Author:** ![Bruce](https://clarionhub.com/letter_avatar_proxy/v4/letter/b/ccd318/32.png) [@Bruce](https://clarionhub.com/u/Bruce)\
**Post date:** [February 20, 2026, 12:45am UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/2 "2026-02-20T00:45:59Z")

</div>

The new SQL() function is by far the easiest approach. It’s the same form as the prop:sql, and uses the same NEXT loop to to read. Converting prop:sql to SQL() is trivial to do and requires the minimum of change.

Assuming you don’t have the SQL() function (yet?) our best option is two fold;

a) Avoid prop:Sql wherever possible. Make use of appropriate Clarion driver commands instead. There’s actually a lot more in there than you propbably expect - most people are using prop:Sql in places where it’s not necessary. It’s an easy pattern and so something quickly reached for, even if the driver offers a safe alternative.

b) you can sanitise your input. ie before adding anything to prop:sql. Unfortunately this is somewhat of a wack-a-mole approach, but it is a LOT better than nothing, and will get stronger as you improve your sanitize function.

Both options are less than ideal because we’re all lazy, and when there’s no immediate tangible benefit to customers it’s easy to just reach for prop:sql. It’s a lot less work to just ignore security (which is why most programmers, in most languages to be fair, simply ignore it.)

Hence the SQL() command - designed to be as easy as prop:Sql, but at the same time offer better security for no extra effort.

---

<div class="post-metadata">

**Author:** ![PurpleEdge2214](https://clarionhub.com/user_avatar/clarionhub.com/purpleedge2214/32/5109_2.png) [@PurpleEdge2214](https://clarionhub.com/u/PurpleEdge2214)\
**Post date:** [February 20, 2026, 11:41pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/3 "2026-02-20T23:41:35Z")

</div>

Thanks Bruce.

Where is this new SQL() command available and what is different in terms of what is sent to the database?

---

<div class="post-metadata">

**Author:** ![Jane](https://clarionhub.com/letter_avatar_proxy/v4/letter/j/ecb155/32.png) [@Jane](https://clarionhub.com/u/Jane)\
**Post date:** [February 21, 2026, 1:09am UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/4 "2026-02-21T01:09:30Z")

</div>

> [@PurpleEdge2214](#):
>
> Where is this new SQL() command available and what is different in terms of what is sent to the database?

Search for prop:sql in this docs page. Discussed in many sections (138 hits in chrome search).

[https://www.capesoft.com/docs/Driverkit/ClarionObjectBasedDrivers.htm#sqlexecute](https://www.capesoft.com/docs/Driverkit/ClarionObjectBasedDrivers.htm#sqlexecute)

---

<div class="post-metadata">

**Author:** ![JonW](https://clarionhub.com/user_avatar/clarionhub.com/jonw/32/1344_2.png) [@JonW](https://clarionhub.com/u/JonW)\
**Post date:** [February 24, 2026, 5:48pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/5 "2026-02-24T17:48:47Z")

</div>

In addition to what Bruce said, there are some other things you can do. Firstly, the really risky situation is when the user is able to type in text that gets put into a prop:sql, like "SELECT whatever from sometable where city = ’ & ‘ **Sucker; delete \* from important\_table;** ’ where the stuff in bold is the user input. Much less risky if the user input is being collected in numeric or date fields.  
Chance of nasty damage is also much lower if the user’s credentials on the database are not that great. You put your data in app\_schema, your user logs on with their own username, and their username is granted rights on the stuff in app\_schema via grants to a role; they can only do a select on data in some tables, can only update or insert in others, not allowed to delete. Certainly no DML.  
One thing I often do, particularly for putting stuff in where clauses, is to use a temporary table. Say you want stuff between two dates. You set up a temporary table (date\_limits) that has start\_date and end\_date. You set up a view that is something like:

```auto
create or replace sometable_view as
select <columns>
from some_table t
join date_limits l on t.dt between l.start_date and l.end_date

```

Your user-entered date\_limits go into the temporary table, and then your browse is run off the view. Avoids PROP:SQL, and the dates are guaranteed to be dates.  
Also, of course, no real risk of SQL injection if the user is not entering any of the information. For example, I might have a clarion form that updates something the normal clarion way, and have a prop:SQL when the form is accepted that sends:  
`update table_status set status = 'Modified', dt = sysdate where id = ' & tab:id`

---

<div class="post-metadata">

**Author:** ![CarlBarnes](https://clarionhub.com/user_avatar/clarionhub.com/carlbarnes/32/1859_2.png) [@CarlBarnes](https://clarionhub.com/u/CarlBarnes)\
**Post date:** [February 26, 2026, 6:00pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/6 "2026-02-26T18:00:02Z")

</div>

Much more info on SQL Injection in Clarion in the new File Driver Kit docs

[https://capesoft.com/docs/Driverkit/ClarionObjectBasedDrivers.htm#sqlinjection](https://capesoft.com/docs/Driverkit/ClarionObjectBasedDrivers.htm#sqlinjection)

* * *

Wikipedia on SQL injection

> **[SQL injection](https://en.wikipedia.org/wiki/SQL_injection)**
>
> In computing, SQL injection is a code injection technique used to attack data-driven applications, in which malicious SQL statements are inserted into an entry field for execution (e.g. to dump the database contents to the attacker). SQL injection must exploit a security vulnerability in an application's software, for example, when user input is either incorrectly filtered for string literal escape characters embedded in SQL statements or user input is not strongly typed and unexpectedly ex SQL...

---

<div class="post-metadata">

**Author:** ![ArnorBld](https://clarionhub.com/letter_avatar_proxy/v4/letter/a/dfb087/32.png) [@ArnorBld](https://clarionhub.com/u/ArnorBld)\
**Post date:** [February 26, 2026, 8:40pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/7 "2026-02-26T20:40:15Z")

</div>

Hi Bruce,

Do you mean the Clarion SQL() function? Not exactly new, I think it’s been around for 20 years or so - I think it was introduced in C5.5, it is in the C6.3 documentation from 2007. It only worked for VIEWS if I recall, you could not use it directly on files.

Best regards,

---

<div class="post-metadata">

**Author:** ![RchdR](https://clarionhub.com/letter_avatar_proxy/v4/letter/r/d78d45/32.png) [@RchdR](https://clarionhub.com/u/RchdR)\
**Post date:** [February 27, 2026, 2:44am UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/8 "2026-02-27T02:44:25Z")

</div>

> [@ArnorBld](#):
>
> Do you mean the Clarion SQL() function?

Not the SQL() function but the Prop:SQL.

> A new command, SQL, has been introduced as a safer approach to calling embedded SQL statements. This replaces the need for the prop:Sql command, which is inherantly vulnerable to SQL Injection attacks.

Capesofts SQL() functions seems alot like the SV SQL() function imo, with added text to highlight why its preferable to use instead of Prop:SQL, which if hooked up to a (c)string text control on a window in an app somewhere becomes a [Little Bobby Drop Tables](https://xkcd.com/327/).

---

<div class="post-metadata">

**Author:** ![Bruce](https://clarionhub.com/letter_avatar_proxy/v4/letter/b/ccd318/32.png) [@Bruce](https://clarionhub.com/u/Bruce)\
**Post date:** [February 27, 2026, 3:42am UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/9 "2026-02-27T03:42:52Z")

</div>

Hi Arnor. Same name, but different function.

The Clarion `SQL(string)` function is used to embed SQL Language directly into a `prop:filter` or `prop:order`. As you noted it is limited to Views. You also need to figure out, and use, the SQL Alias correctly. The new drivers continue to support this (although the Alias restriction has fallen way.) And the new drivers support this for FIles as well as Views.

But no, that’s not the SQL function I’m refering to. The new drivers provide a new command also called SQL, but it’s called with a FILE or VIEW parameter. As in  
`SQL(somefile, somesql, <parm1>,,,<parm20>)`  
This allows you to parameterise a sql command, thus making it safe.

So if you have a prop:Sql that read something like

`Customers{prop:sql} = 'SELECT name from Customers where Cus:Name > ''' & someLocator & '''')`

This becomes

` SQL(Customers,'SELECT name from Customers where Cus:Name > ?1',somelocator)`

The second form is simpler (no need to deal with quotes) and also safer, because the contents of `someLocator` as passed to the SQL engine as a parameter. So it’s never “compiled” by the SQL engine, and thus is immune to SQL Injection attacks.

For a better explanation, and more examples see;  
[https://www.capesoft.com/docs/Driverkit/ClarionObjectBasedDrivers.htm#sqlexecute](https://www.capesoft.com/docs/Driverkit/ClarionObjectBasedDrivers.htm#sqlexecute)

---

<div class="post-metadata">

**Author:** ![JonW](https://clarionhub.com/user_avatar/clarionhub.com/jonw/32/1344_2.png) [@JonW](https://clarionhub.com/u/JonW)\
**Post date:** [February 27, 2026, 2:58pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/10 "2026-02-27T14:58:43Z")

</div>

Hi Richard,

No, there really is a big difference because you are using bound parameters. In PROP:SQL you are saying to the server: here is a command or a bunch of commands I want you to carry out. Interpret the cstring I have sent you and work out what to do with it. If you send it:

`select * from whatever where somecol = 'myvalue'; delete from some_table;`

it will treat it as two commands, with the second one being the deletion of everything in the table.

If you send it:

`select * from whatever where somecol = ?1`

where ?1 is a bound string, then it will look for values where somecol is greater than whatever you send in the string; it isn’t trying to parse the whole resulting string to see if there might be another command or commands in there.

In terms of how this works in the database, what you are doing is something like this (this is Oracle PL/SQL, but same concepts apply to TSQL etc.: )

```auto
declare
starting_activity varchar2(40);

cursor x is 
select activity_id
from activity
where activity_name > starting_activity;

begin
  starting_activity := 'LLL; delete from a;';
  for y in x loop
    dbms_output.put_line('ID is ' || y.activity_id);
  end loop;  
end;

```

Starting\_activity is your user input. If you use prop:SQL you can potentially send to the server, if your malicious user manages to handle the quotes correctly:

```auto
select activity_id
from activity
where activity_name > 'LLL'; delete from a;

```

and you lose your A table.

If starting\_activity is a bound cstring, then the select statement can only be:

```auto
select activity_id
from activity
where activity_name > 'LLL; delete from a;'

```

which is harmless.

---

<div class="post-metadata">

**Author:** ![Bruce](https://clarionhub.com/letter_avatar_proxy/v4/letter/b/ccd318/32.png) [@Bruce](https://clarionhub.com/u/Bruce)\
**Post date:** [February 27, 2026, 3:28pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/11 "2026-02-27T15:28:52Z")

</div>

> [@RchdR](#):
>
> Capesofts SQL() functions seems alot like the SV SQL() function imo

The SV SQL command is used inside a prop:filter or prop:order. It isn’t used for whole sql statements. It’s very different to the driver kit SQL(file) command.

---

<div class="post-metadata">

**Author:** ![ArnorBld](https://clarionhub.com/letter_avatar_proxy/v4/letter/a/dfb087/32.png) [@ArnorBld](https://clarionhub.com/u/ArnorBld)\
**Post date:** [February 27, 2026, 3:30pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/12 "2026-02-27T15:30:43Z")

</div>

Hi Bruce,

Ah, so it’s part of your new drivers. Cool.

---

<div class="post-metadata">

**Author:** ![ArnorBld](https://clarionhub.com/letter_avatar_proxy/v4/letter/a/dfb087/32.png) [@ArnorBld](https://clarionhub.com/u/ArnorBld)\
**Post date:** [February 27, 2026, 3:39pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/13 "2026-02-27T15:39:05Z")

</div>

Hi Bruce,

Or did I miss something - is this now in Clarion? I’m primarily still working in C9.1, so I’m ages behind 😉

Back in 2024 my main client and I went through a big effort to bring a large PHP/MySQL project up to full parameterized queries for penetration testing. PHP makes it fairly easy, but it was a bit of an effort to convert older code up to parameterized queries.

I have used /TURBOSQL quite a bit in the past, but as I recall there was no option for parameters for queries…

Best regards,

---

<div class="post-metadata">

**Author:** ![Bruce](https://clarionhub.com/letter_avatar_proxy/v4/letter/b/ccd318/32.png) [@Bruce](https://clarionhub.com/u/Bruce)\
**Post date:** [February 27, 2026, 7:14pm UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/14 "2026-02-27T19:14:54Z")

</div>

Its in the Driver Kit Arnor. Works in Clarion 9.1 and up.

---

<div class="post-metadata">

**Author:** ![Omar\_Squiabro](https://clarionhub.com/user_avatar/clarionhub.com/omar_squiabro/32/4474_2.png) [@Omar\_Squiabro](https://clarionhub.com/u/Omar_Squiabro)\
**Post date:** [March 2, 2026, 11:37am UTC](https://clarionhub.com/t/how-to-avoid-sql-injection-risks/8967/15 "2026-03-02T11:37:30Z")

</div>

this is a good articule but very complex to integrate to clarion

> **[Guarding Against SQL Injection at the Database Layer (SQL Server) –...](https://www.sqlservercentral.com/articles/guarding-against-sql-injection-at-the-database-layer-sql-server)**
>
> This article presents a way to check and validate input before using it in your dynamic SQL queries to prevent SQL Injection problems.
