Call: +44 (0)7759 277220 Call
Blog

Pete Finnigan's Oracle Security Weblog

This is the weblog for Pete Finnigan. Pete works in the area of Oracle security and he specialises in auditing Oracle databases for security issues. This weblog is aimed squarely at those interested in the security of their Oracle databases.

Can We Remove IF Statements from PL/SQL?

I like PL/SQL and I am always playing around with it or writing tools for use in security audits in PL/SQL or trying to do things that are not normal with PL/SQL such as writing an interpreter. One thing I found in some testing of PL/SQL recently is that the shorter the PL/SQL the faster it is parsed and compiled. This is common sense really; it should take 'x' seconds to compile a PL/SQL of 'y' length but if the length is 20% shorter it stands to reason it should parse and compile faster; because its shorter. Less code to read in and process, parse, less DIANA, less AST, less P-Code.

I was also thinking about the C language ternary operator where there is no IF statement but a short cut as follows:

(x==y)?"true":"false";

This is a single line IF/ELSE; without the IF/ELSE keywords. The condition is tested and if true the first part after the "?" is returned as the result of the statement or if the condition is false then the part after the ":"

Can we do similar in PL, no ternary operator in PL/SQL BUT we can as it happens use the condition in other places than an IF statement. So if I have a simple function to test if a character is ALPHA i.e. a-z or A-Z then it looks like this:

function IsAlpha(pv_c in varchar2) return boolean is
lv_ret boolean;
begin
if(((ascii(pv_c)>=65) and (ascii(pv_c)<=90))
or ((ascii(pv_c)>=97) and (ascii(pv_c)<=122))) then
lv_ret:=true;
else
lv_ret:=false;
end if;
return(lv_ret);
exception
when others then
dbms_output.put_line('Error');
end;

As you can see the simple function uses the ascii function to test the passed in character and then return TRUE or FALSE. I realised that we do not need the IF/ELSE/END IF as we can simply put the test condition in the return() directly and the function will then return TRUE or FALSE:

function IsAlpha2(pv_c in varchar2) return boolean is
begin
return(((ascii(pv_c)>=65) and (ascii(pv_c)<=90))
or ((ascii(pv_c)>=97) and (ascii(pv_c)<=122)));
exception
when others then
dbms_output.put_line('Error');
end;

This is now a much shorter version of the function producing the same result BUT without the IF/ELSE/END IF now. Great, we reduced the code, increased complexity slightly but made the code succinct.

Obviously we cannot do this change everywhere in all PL/SQL code. It works because the IF/ELSE/END IF returns just true or false. But it will also work not just in return but also in other places that take a condition.

The whole thing is here to prove it works:

set serveroutput on

declare
lv_ret boolean;
--
function IsAlpha(pv_c in varchar2) return boolean is
lv_ret boolean;
begin
if(((ascii(pv_c)>=65) and (ascii(pv_c)<=90))
or ((ascii(pv_c)>=97) and (ascii(pv_c)<=122))) then
lv_ret:=true;
else
lv_ret:=false;
end if;
return(lv_ret);
exception
when others then
dbms_output.put_line('Error');
end;
--
function IsAlpha2(pv_c in varchar2) return boolean is
begin
return(((ascii(pv_c)>=65) and (ascii(pv_c)<=90))
or ((ascii(pv_c)>=97) and (ascii(pv_c)<=122)));
exception
when others then
dbms_output.put_line('Error');
end;
--
begin
lv_ret:=IsAlpha('A');
dbms_output.put_line(sys.diutil.bool_to_int(lv_ret));
lv_ret:=IsAlpha('0');
dbms_output.put_line(sys.diutil.bool_to_int(lv_ret));
lv_ret:=IsAlpha2('A');
dbms_output.put_line(sys.diutil.bool_to_int(lv_ret));
lv_ret:=IsAlpha2('0');
dbms_output.put_line(sys.diutil.bool_to_int(lv_ret));
end;
/

And running gives:

SQL> @if
1
0
1
0

PL/SQL procedure successfully completed.

SQL>

The use of diutil.bool_to_int() is just to show the result. In the original use of this function it was embedded in another call so the IF/ELSE/END IF is truly removed

#oracleace #sym42 #plsql #securecode #oracle #security #extremeplsql #23ai #23c

Protect and Secure Your PL/SQL Code

Do you develop PL/SQL? Is your Oracle PL/SQL protected?

My name is Pete Finnigan and in the next few minutes I will show you how you can protect you PL/SQL investment from theft. We can:

  • Stop people stealing your ideas

  • Make sure you control your PL/SQL

  • Secure your PL/SQL code

  • Simple to use


Ask to Purchase a License or see a live demo first

Here is the Perfect Solution to Stop Theft of your PL/SQL



Did you know that if you do not protect your PL/SQL then anyone with access to the database where your code is deployed can steal it.

If you don't protect your PL/SQL before it is deployed then someone can read your code in clear text and understand it and rewrite it as their own. You think your application is fantastic and customers will buy it but if you don't protect it someone will take it for free and use it or access your source code and copy the ideas within it.

Which means that your code could be stolen and deployed to further databases and used without you receiving a penny in license fees that you should be due.

Luckily for you we have an easy to use solution that helps prevent anyone from learning how your PL/SQL application code works and understanding your ideas and prevents the theft of your code from a database where it is deployed. Our solution can also easily add protection to your application to prevent its use even if its copied to another database.

  • Obfuscate and compact your PL/SQL code which means your customers cannot understand and steal your intellectual property

  • Detailed configuration and customization which means that you can set up and re-use the same rules on a different project

  • Control the obfuscation process which means you decide what is protected and what is not

  • Add simple date and time based licensing which means you control when your application runs in the customers system

  • Add run time controls automatically to your application which means you can activate and control which database it works in

  • Command line operation which means you can integrate PFCLObfuscate into your existing build cycle


Using PFCLObfuscate to protect your PL/SQL code


Using PFCLObfuscate is easy. After installing the product you can see that the software is highly configurable at the product level and also down to the individual source code level and anywhere in between.
PFCLObfuscate Settings

The above picture shows the main configuration settings for the tool. For each piece of PL/SQL at a schema level or even down to individual pieces of PL/SQL we can easily provide settings. All of the settings are stored at the schema level in files BUT we can also save the configuration per schema and open/close saves configs easily if we need separate settings at a file level or group of files within a schema. The image below shows some of the PFCLObfuscate settings that can be changed
PFCLObfuscate Configuration for Strings

Once we have all the settings configured as we need we can connect to a database and choose a schema to download PL/SQL source code from:
PFCLObfuscate Connection

The next step is easy; simply click "refresh" from the file menu to get all the source code for the chosen schema. This is shown next:
PFCLObfuscate Refresh

When we have a list of PL/SQL packages, headers, procedures and functions then we can simply check the box next to each piece of PL/SQL that we want to obfuscate. This is shown next:
PFCLObfuscate Choose what to Obfuscate

We can display the original clear text as well as the obfuscated text:
PFCLObfuscate Show the source code

The product is much more though. We can easily inject code at any point we choose in the clear text PL/SQL. This means that it is easy to add license type protection to your PL/SQL. This means you can ship PL/SQL to customers for instance where it has a time limit - e.g. it works for 30 days and stops or we can inject locks into your PL/SQL so that you can for instance limit which database the protected code will work in. We can also use the same functionality to add better string obfuscation or indeed anything that you need. The main configuration screen is here:
PFCLObfuscate Function File

As you can see we use Lua files to inject code into your PL/SQL. These scripts write PL/SQL that is then automatically added to the obfuscate stream and is obfuscated with the rest of your code.

Not everything in your PL/SQL can be obfuscated. Imagine that you have calls to a specific package procedure such as schema.package.procedure(a,b). If we obfuscate the call then it cannot find it as the original package is not obfuscated. We have two options here; we can either omit this call from the obfuscation by adding it to the omit files OR we can also obfuscate everything else. We have some customers who also obfuscate all table definitions and triggers and more with PFCLObfuscate.

Don't forget we can also use the product completely from the command line and the whole process to protect all of your PL/SQL can be automated and be added into your build processes.

Detailed documentation is available and can be used as a reference when working with the product and we also have email based support where we will answer any questions.

Pete Finnigan is the designer of this software and he has more than 21 years real world experience helping customers secure data in Oracle databases. Pete is an Oracle ACE, a member of the OakTable and also a member of Symposium 42 and is a published author multiple times on the subject of securing data in Oracle databases.

License PFCLObfuscate to easily protect your own PL/SQL source code. A download of the software is built for you and is available as soon as payment is received. The Pro license is £1,095 GBP (+ Taxes if applicable) to install and use to protect all of your PL/SQL. To arrange a purchase Email Sales Now

Buy a Pro license in the next 30 days from this post date and get 25% off our one day live on-line "secure Coding in PL/SQL" class taught by Pete Finnigan. You can choose a date from our on-line course agenda. To arrange a purchase Email Sales Now

#oracleace #sym_42 #oracle #plsql #protection #obfuscation #license #protect #sourcecode #database

Extreme PL/SQL - An Interpreter for a Simple Language

I talked at a high level a few weeks ago about Extreme PL/SQL and gave a brief look at an interpreter I have been creating for a simple language based on BASIC.

I have been keeping notes in a Word document currently running over 100 pages and over 35 sections/chapters/articles. I plan to release each of those chapters as separate blogs in a blog series. I have been writing all of these notes as I develop the language and the interpreter and of course the design and tests and content changes. So, i am unsure at this stage whether to release all the articles "as-is" or update them to reflect the changes that have occurred as we progressed.

I will decide soon!

The language is fairly simple and have these features:

  • Define any number of numeric variables such as "var" or "x" or...

  • Expressions include "+, -, /, *", variables brackets

  • KEYWORDS such as IF, THEN, FI, LET, PRINT, GOTO, REM and END


The language is simple and does not include loops or ELSE in the IF statement or procedures - YET!

We can implement all of the above with LET, GOTO and IF anyway. Writing loops, ELSE or procedures with GOTO, IF and LET makes the code more complex and hard to write and understand but can be done.

I wanted to get a simple version of a language working first and then we can extend it and add more language constructs and features.

The original plan was to write a VM for a CPU in PL/SQL and indeed I have written that already in anticipation but I have not written an assembler yet to convert assembly language to binary instructions. This binary stream would then be executed in the VM of the CPU. Finally the interpreter would be converted to a compiler and would emit assembly language instructions for the VM. The tool chain would be BASIC => compiler => assembly language => assemble => binary => execute the binary in the VM CPU.

Currently the simple BASIC language is interpreted and having looked at the speed, I suspect the binary would not run massively faster than the interpreter. The VM is a CPU written in PL/SQL and the interpreter executes the simple BASIC. We compare at run time executing BASIC or binary in a PL/SQL program. There is additional complexity of course in compiling the BASIC to assembler and then assembling the assembly language and running it. If the goal is to run a program then probably there is not a massive difference in speed. I will explain a lot more in the detailed write up. One option is to make the BASIC execute faster by reducing its size so it parses and executes faster. We will explore that also in the detailed write up.

The language is not BASIC and is a simple implementation of some of the original BASIC from the 1960s. It will change as I add features to it so I am going to call it PFCLScript.

A traditional starter program is "hello World". Here it is in PFCLScript:

declare
lv_prog varchar2(32767):=q'[
PRINT "Hello, World!!"
]';
begin
pfcl_int.init(true,1);
pfcl_int.run(lv_prog);
end;
/

And here it is running:

SQL> @compiler
Hello, World!!

Start Time : 17-JUL-24 08.14.09.484629 AM
End Time : 17-JUL-24 08.14.09.562677 AM
Elapsed Seconds : +000000 00:00:00.078048000
SQL>

OK, lets try another favourite for testing new languages or learning to program in a language; the Fibonacci sequence where the Fibonacci number is less than 20:

declare
lv_prog varchar2(32767):=q'[
LET m=20
LET x=1
LET y=1
:30 IF x>m THEN GOTO :20 FI
PRINT x
LET x=x+y
IF y>m THEN GOTO :20 FI
PRINT y
LET y=x+y
GOTO :30
:20 END
]';
begin
--
pfcl_int.init(true,1);
--
pfcl_int.run(lv_prog);
--
end;
/

And running shows:

SQL> @compiler
1
1
2
3
5
8
13

Start Time : 17-JUL-24 10.55.13.109739 AM
End Time : 17-JUL-24 10.55.16.933322 AM
Elapsed Seconds : +000000 00:00:03.823583000
SQL>

That is the correct answer.

I will decide whether to update the notes I have already created for many articles to reflect the later versions of the interpreter or release them as they were written. I am also going to continue to add some features to the language and the interpreter and also decide whether to convert to a compiler or not.

Watch out for more and commend via social media and also please consider following me on my social media accounts.


#oracleace #sym_42 #oracle #database #23c #23ai #securecode #plsql #extreme #interpreter #compiler #assembler #vm #cpu #pfclscript