Home > Security > Security is not Obscurity. Even in U2 [Part 1]

Security is not Obscurity. Even in U2 [Part 1]

Sure, we may benefit from whatever shelter is derived from running a less widely used/understood system, but relying solely on security through obscurity with your U2 system is, to put it nicely, extremely naive in this day and age. It just doesn’t add up when you pay thousands of dollars for firewalls and other network security paraphernalia and wouldn’t dream of allowing raw user input through in your SQL-based applications.

U2 may have different syntactical spices and a different method of representing data than its mainstream counterparts but the core principles behind secure coding practices still apply:

The list goes on.

So, what specific vulnerabilities should we look out for?

Let us start with the humble EXECUTE/PERFORM statements in UniData and UniVerse. SQL Injection is a widely know subject, but how many U2 developers have considered UniQuery/RetrieVe Injection? Did you know that in some cases, malformed UniQuery in a EXECUTE can drop you to ECL?

As developers in the U2 world, the same lessons learnt in SQL Injection can and should be applied when using *EXECUTE/*PERFORM, etc. Sanitise your input!

Do you have any statements that work like this?

...
EXECUTE 'SELECT MYFILE WITH FIRST.NAME = "':TAINTED.INPUT:'"'
...

In this case, TAINTED.INPUT is either supplied by a user or is comes from an external source. The results from the SELECT statement are now compromised and can contain any data. Take for instance the following input for this contrived example:

" OR WITH CC.NUMBER = "4657000000000000

Essentially, this converts the innocent SELECT statement which, for example, was used to search for customer’s first names to get contact numbers, into one which can be used to find Credit Card numbers (hopefully though, your CC numbers are encrypted in some manner). Even worse, if your program displays error messages that reveal record names when they cannot be read, then an attacker with patience can reveal almost any data they want from your system.

Remember, in UniData you can use the ‘USING’ keyword to specify any FILE to source the dictionaries (UniVerse does not have this, I believe). Aside the all the usual manipulation of results, the USING means that if someone can control the first few lines of a record (temp data dumping file anyone?) then using the SUBR() call, they can even cause programs and subroutines to be called!

Before you EVER use input from a user or an external source, make sure it is validated and sanitised. Expecting a number? Use MATCH and 1N0N. Expecting a name? Make sure it is doesn’t contain double quotes. Don’t want to allow ‘searching’ with your SELECT? For example, I use the following check to ensure the user input doesn’t escape the SELECT string with double quotes or attempt a wildcard search with [ or ].

IF TAINTED.INPUT MATCH "~'['0X~']'" AND NOT(INDEX(PCNAME, '"', 1)) THEN
   ...

Further to this UniQuery/RetrieVe Injection vulnerability, earlier I mentioned that in certain situations you could cause it to crash to ECL.

Are you running UniData in PICK mode? If you are, I suggest you type ‘UDT.OPTIONS’  at ECL right now and continue down until you see whether ’41  U_UDT_SERVER’ is set to ON or OFF. Now, did it say OFF? If so, then read on because you may be vulnerable.

While that option is turned off, certain malformed UniQuery statements can cause you to crash straight to ECL, even if you are in a program called by a program.

Lets see an example. First, compile the following program in Pick Mode.

CRT "Enter the program to select"
INPUT PROG.NAME
CRT "Executing query..."
EXECUTE 'SELECT BP WITH @ID="':PROG.NAME:'"' CAPTURING INFO RETURNING RESULT
CRT "Checking results..."
IF SYSTEM(11) > 0 THEN
   CRT "Program FOUND!"
END ELSE
   CRT "Program doesn't exist"
END
CLEARSELECT
STOP

Now, when you run the program (I called it CRASHTEST), put a record ID that exists in BP. Try again with a record ID that doesn’t exist. Your results should be something like this:

Normal Program Operation

Normal Program Operation

Looks good. Program works as expected. Underneath this simple program though, lies a bug feature in the Pick Parser. To show this, I will use a specifically formed input that will make the programs SELECT malformed in a manner to gain ECL access. This time when you run the program (with UDT.OPTIONS 41 off) type in this input, including quotes:
" @ID="
In this case, the program will crash out before ever returning.

Crashed from EXECUTE

Crashed from EXECUTE

There are 2 ways to deal with this. The first way is to set UDT.OPTIONS 41 to ON. This will result in the EXECUTE returning so we can handle it whatever way we wish.

The other way is to set ON.ABORT. I created a VOC paragraph for this, called EXCEPTION as follows:

PA
DISPLAY This program aborted

Running the same test above now results in:

Aborted program

Aborted program

Personally, I believe the method that returns control to the program (UDT.OPTIONS 41) and handles it accordingly (always check what was set by RETURNING) is the safest since it doesn’t give away that the program has a compromised EXECUTE statement. However, this may not always be a viable option, so make sure you at least have ON.ABORT set.

Advertisements
  1. December 7, 2010 at 6:26 am

    Great post, Dan.

    A SQL injection attack could insert:

    Bobby’; DROP TABLE Students;–

    To work against this SQL string:

    SELECT * FROM Students WHERE sFullName = ‘” + @UserInput + “‘

    Similarly, you could insert:

    Bobby” @AM DELETE-FILE STUDENTS @AM ;*

    To work against this UniQuery string:

    SELECT STUDENTS WITH FULLNAME=”‘:USER.INPUT:'”‘ CAPTURING INFO RETURNING RESULT

    The attribute mark character terminates UniQuery statements just as semi-colon terminates a SQL statement. A best-practice would be to always accept user-input through a generic input routine which scrubs and strips bad characters, such as attribute marks (no user should ever be typing attribute marks).

    -Rob

    • December 7, 2010 at 10:14 pm

      Thanks for the comment.

      The attribute mark is quite dangerous. Thankfully, it is extremely simple to have a generic input routine as you suggest to clear out all the delimiter characters (most U2 shops I know of do this).

      Who would of guessed someone at Fog Creek would know UniQuery? :)

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: