The History of the Oracle PLSQL Gateway Flaw

Risk: Medium
Local: Yes
Remote: Yes

CVSS Base Score: 7.5/10
Impact Subscore: 6.4/10
Exploitability Subscore: 10/10
Exploit range: Remote
Attack complexity: Low
Authentication: No required
Confidentiality impact: Partial
Integrity impact: Partial
Availability impact: Partial

In the past few days Oracle has criticized me for publishing a workaround for a critical flaw in their PLSQL Gateway. This email will show that after 4 years of waiting for Oracle to try to get it right, I eventually decided to take matters into my own hands and provide Oracle customers with more help than Oracle is currently doing. Oracle - shame on you: The Oracle PLSQL Gateway sits on a web server and allows web users to execute PLSQL applications in an Oracle database server. When first introduced, as long as a web user had the permission to execute the PLSQL procedure and knew its name then they could execute it through the PLSQL gateway. This clearly opens up a massive security risk and Oracle introduced what is known as the PLSQLExclusionList to help limit exposure. Essentially, if a web user attempts to access any plsql package listed in the exclusion list then the Gateway rejects the user's request with a "forbidden" message. So access to anything that started with "SYS.", for example, would be blocked. Or that's what's supposed to happen, anyway. There are two distinct problems with this solution. Firstly, it's never worked and the exclusion list can be totally bypassed and secondly, it's a half baked idea to begin with. Let's delve deeper and examine both of these When Oracle first introduced the exclusion list in 2001 it could be trivially bypassed by preceding the plsql package name with a newline character I advised Oracle about this bypass problem in 2001 and, once Oracle "patched" this, I published details in "Hackproofing Oracle Application Server" ( It didn't take long to discover that this patch could be bypassed using the following techinque: due to internationalization, an Oracle database server will convert the ? character (value 0xFF) to a capital Y. The PLSQL Gateway will not. Thus, if we request the gateway will happily pass it over to the database server where the ? is conveted to a Y and we can gain access again. Oracle issued a patch for this but this patch was broken, too. What's interesting is the story behind how I found the next bypass technique. I had just reported some flaws in a few PLSQL applications in the database server but there was only a risk if an attacker could bypass the exclusion list. As Oracle had just released a "fix" for the bypass problem they stated they were not going to fix the backend flaws. This is from the email they sent me informing me that they weren't going to fix these issues "We feel that our latest fix to security alert #68 will now correctly block any request that matches the patterns defined in the exclusion list. The OWA_OPT_LOCK package falls under the OWA_* pattern. Therefore, this request will be blocked by the exclusion list feature. Since the exclusion list cannot be bypassed anymore, we are not allowing anyone to call this package from the browser, and thereby, blocking this PL/SQL injection from happening." This angered me as it was clear laziness on Oracle's part and they were deliberately leaving their customers at risk. I then set out to find a new bypass technique and eleven minutes after reading this mail I found what I was looking for. This new bypass technique simplly involved enquoting - putting SYS in double quotes:"SYS".PACKAGE.PROCEDURE Whilst this bypass worked on Oracle Application Server 9 - it didn't on 10g. The technical reason for this is as follows. 10g App Server converts the upper case SYS to the lower case sys - and if something is enquoted - it needs to match the right case. However, a bypass trick that did work with 10g was to use angle brackets - these form a label in PLSQL.<<LABEL>>SYS.PACKAGE.PROCEDURE So come July 2005 Oracle had really made a mess of all this and introduced their next patch. This can be bypassed too - this is the one I posted a workaround for and we're all currently waiting on Oracle fixing. Going back to the second problem - that is - the PLSQL Exclusion List is a half baked idea to begin with. The exclusion list, by default, attempts to block access to the following SYS.* DBMS_* UTL_* OWA_* OWA.* HTP.* HTF.* Thus, by default, access to packages owned by accounts such as CTXSYS or MDSYS is not blocked. These two accounts are both DBAs and, what's more, many of the PLSQL applications owned by these accounts have suffered from security flaws. As the exclusion list doesn't block access to these accounts, these flaws can be exploited via the web server to gain complete control of the database server. The point is the exlusion list is a "black list" solution and the problem with black lists is that you need to know in advance everything that is bad and should be black listed. It's a much easier proposition to know what is not bad though and only allow access to this. This is a "white list" solution and I've been asking Oracle to give us a white list solution to this problem for four years now - but they still haven't done it. Explaining this further - let's say my web plsql application consists of one package called "banking" and this package has a number of procedures that implement typical banking tasks such as "transfer", "pay", "show_balance", etc, etc. If I had a white list solution then I could say allow access if and only if the web users request starts with "banking" and reject everything else. This is an entirely much more secure and robust solution than the "black list" approach. Will we ever be given this as a solution? Who knows. As it seems providing a decent security solution is beyond Oracle at the moment - I'm not holding my breath. Come on Oracle - get your stuff together! Cheers, David Litchfield

Vote for this issue:


Thanks for you vote!


Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.

(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024,


Back to Top