div.b-mobile {display:none;}

Monday, July 31, 2006

Security via obscurity...

Security via obscurity. Someone emailed me last week with a cut and paste of an error page on asktom. The error included:

ORA-01400: cannot insert NULL into ("ASK_TOM"."WWC_ASK_QUESTION_ACCESS_LOG$"."DISPLAYID")

Their comment was “isn’t it a good practice to never give detailed error messages to end users”. I was curious – was this about ‘user interface’ issues (some people do not want to give out the error message for aesthetic reasons) or was this about ‘security via obscurity’.

Turns out it was ‘security via obscurity’. They said “I now have some basic information for SQL Injection attacks”. The thought was - that by having knowledge of a column name – an application would be more SQL Injection attackable.

To me – it is more of a binary thing, either your application is subject to SQL Injection attacks or it is not. It is sort of like data integrity – you either got it or you don’t (it isn’t like hull integrity on Star Trek, data integrity is either 100% or 0%).

Knowledge of the program should never be a cause for alarm. The names of the tables, their columns, the SQL used, the program flow, the algorithms and so on – if they are “protected from prying eyes because of security concerns – knowledge of them makes us subject to attack” then you have a problem. You are already subject to attack, it is merely a matter of time. There are valid reasons for protecting these things from prying eyes (intellectual property reasons mostly), but security isn’t one of them.

If by looking at my application code, logic, schemas, whatever – you can attack it, you could attack it already. It must be vulnerable in the first place. You cannot hide SQL Injection vulnerabilities (you should read this most excellent paper on the topic – it is obvious to me that the people that put together this video read it, they used the techniques outlined there. I picked up that video from Pete Finnigan’s blog).

Beware when someone says “no, you cannot show that for reasons of security”. That almost certainly means there is a bug lurking there just waiting to be exploited.

On asktom – I do not use string concatenation to build my SQL, I bind all strings, numbers and dates using either bind variables or application contexts. That means the end user cannot change the meaning/intent of my SQL.
POST A COMMENT

27 Comments:

Anonymous Anonymous said....

I'm sure there are no comments yet because everyone is over at asktom trying to inject some SQL.

Mon Jul 31, 01:15:00 PM EDT  

Blogger Joel Garry said....

It is sort of like data integrity – you either got it or you don’t (it isn’t like hull integrity on Star Trek, data integrity is either 100% or 0%).

So you are saying if I have a system that imports data and a few tables are allowed to not have integrity, that I have 0% data integrity over the whole system? How about if those tables merely exist to be able to resolve integrity issues? Perhaps you are thinking too specifically about deferred constraints making integrity on or off?

As far as security, there are levels of it, too. First you need to know what infrastructure you are dealing with. Then, as the paper you pointed at notes, you look for input ability. Then you look for particular types of pages. These layers all contribute to the integrity percentage of the "hull." Once the hull is breached, hopefully there is compartmentalization to limit the breach, or even honeypots for security via misdirection.

In a multi-tier environment you can't always know where the attack may come from, so some, perhaps ridiculous, paranoia is justifiable. All of them is smarter than any of us.

verification: dbhfzs

Mon Jul 31, 01:24:00 PM EDT  

Blogger Thomas Kyte said....

So you are saying if I have a system that imports data

No that is not what I'm saying at all.

Apparently, the tables you import into - they have no integrity constraints, anything goes. No one can make any assumptions about anything.

I'm saying

"you either
a) have a foreign key
b) do not have a foreign key"

You don't have "a mostly on foreign key". You know, the kind you get when an APPLICATION MAKES THE (FUTILE) ATTEMPT TO DO DO IT YOURSELF INTEGRITY"


Paranoia is ok - but believing that your system is not secure unless you "hide the schema/algorithms/etc" from view is not paranoia, it is a false sense of security.


I was reading in Wired over the weekend how car makers started the "theft proof car" concept. The idea: the car will not start unless you have the key (they are paired). Worked SO WELL in the beginning that insurance companies refused to pay people (accused them of trashing their own cars) once the system became understood.

Sounds like a case for "hiding the facts" - problem is, facts leak out, many of the breaches were "social engineering" - poor design, horrible implementation.

But people believed so strongly that this feature made the cars secure....

I don't like people having some false sense of security.


You know what really scares me - since I'm on a security bend here - when you click on the "forgot your password" link and you get emailed - YOUR PASSWORD. Not a new temporary one, the old one.

first problem: they are STORING MY PASSWORD - ouch. That hurts

second problem: they sent it in email, plain text, just there. ouch ouch ouch again.

Mon Jul 31, 01:35:00 PM EDT  

Blogger Thomas Kyte said....

The wired article is Pinch my ride by the way. Interesting article.

Mon Jul 31, 01:36:00 PM EDT  

Blogger David Aldridge said....

Speaking in general, one way in which that information can be a security problem is in revealing what technology is being used on the website. Aside from the table name, the message says, "This site uses Oracle". A no-brainer in the case of AskTom, but for other sites it could be of interest in revealing possible "attack vectors". A generic message would be better in that regard.

If there are absolutely no vulnerabilities then the point is moot (or "mute" as one of my co-workers always says), but I'd regard revealing information to the viewer as a bad thing in general.

I'm reminded of advice I read to change the default message on your answering machine, as it can reveal to malicious callers the make and model, and they can infer the default access codes. Again, moot if you have changed all the codes and whatnot.

Mon Jul 31, 03:26:00 PM EDT  

Blogger Thomas Kyte said....

David Aldridge said...

so, what is your take on "open source" then :)

The issue I had is - my schema has been published, the application is out there, everything is there for looking.

If you have to hide table names, columns names and the like for "security reasons", it must be an insecure application from the get go.

Mon Jul 31, 03:59:00 PM EDT  

Anonymous Alex Gorbachev said....

Tom,
Your application might be well protected from SQL Injection. However, there could be other issues that you might not be able to take into account like security holes in Oracle database itself.
I guess you can't really get absolutely 100% secure application but rather be as close as possible. I can't say that showing internals of your application will make your site, say, 10% less secure but I am sure that you get a bit closer to absolute 100% if you can hide internals.
Just an example in addition to David's one - besides knowing that this site is using Oracle, a potential attacker knows that, say, materialized views are used and exploit one of security flaws specific to MVs.

Mon Jul 31, 04:45:00 PM EDT  

Blogger David Aldridge said....

I don't think that there's a valid comparison there -- open/closed source software is a different issue.

You have to distinguish between the form of openness that allows potential security problems to be identified in a set of code, and the sort of openness that says "This e-commerce site uses brand X RDBMS software, brand Y application server, and brand Z operating system". I believe that the first form of openness is a Good Thing, and the second form of openness is a Bad Thing. Unless everything about the e-commerce site is secure, in which case it makes no difference and the openness makes no difference at all.

I'm not advocating the "security through obscurity" paradigm that implies that problems have to be hidden so they don't have to be fixed. All identified security holes ought to be fixed. However security is improved by giving no clues as to the technical details of a website (for example). If you could not tell what technology is behind the HTML etc that an e-commerce site is delivering to your browser then it makes the attackers job more difficult.

To look at it another way, would you post on your curbside mailbox a list of household security details such as ...

i) model of alarm system and location of motion detectors and cameras
ii) make and model of door and window locks
iii) location and model of your safe

... so that potential burglars can peruse at their leisure before attempting suspicious activity? What would you think of a museum that took a similar appproach? It would be crazy to do so, I suggest. I would prefer that in order to get useful information about my system a potential attacker is required to do something detectable in order to get such information.

Mon Jul 31, 04:50:00 PM EDT  

Blogger Thomas Kyte said....

Alex,

I'll ask you what I asked David then:

What is your take on open source?


A potential attacker would have to get into my database with the ability to create a materialized view first...

Assuming I hadn't patched :)

My problem with hiding stuff is - if you BELIEVE you are secure (but aren't), you might really BELIEVE it. If you BELIEVE that holding back say column names makes you more secure, you might really BELIEVE it.

Just like the insurance companies believe in theft proof cars (the wired article - which the more I think about it - the more it relates to this very discussion)

Mon Jul 31, 04:52:00 PM EDT  

Blogger Thomas Kyte said....

I don't think that there's a valid comparison there -- open/closed source software is a different issue

I disagree entirely - open source, open kimono, every thing out there.

Brand Y of application server is always pretty much well known - it is advertised right in the headers. The database might be hidden, but in general (via press releases) it should be fairly easy to figure out.

The OS - also openly advertised - I have little "bookmarklets" that tie into netcraft and tell me that stuff.


and we do announce our security systems - I have the sign in the front yard (have to if I want the insurance reduction) that declares the very service I'm using (which leads to a very short list of what could be there).

Mon Jul 31, 04:59:00 PM EDT  

Anonymous Anonymous said....

I do believe tom has a good point about security (although I'd worry about taking it too far). The best encryption techniques are those where you know exactly how the algorithm works and do not buckle under attack from the cryptography community analysing said algorithms. The fear is that if your algorithm is secret it may have some massive hole just waitnig to be tripped over giving folks that false security blanket. It just means that another revenue of attack it effectively (leaking of the algorithm) is reduced to an ineffective attack strategy.

This is a long way from saying that open source is instantly more secure though.

Mon Jul 31, 05:16:00 PM EDT  

Blogger David Aldridge said....

I quite agree that the information is easy to come by -- I disagree that that has any relevance as to whether it is a good security measure or not.

The I.T.industry and its stock analysts are obsessed by usage statistics. What percent of websites run Apache? What percentage of hits came from Safari? How prevalant is IIS in large e-commerce sites? ... blah blah blah. These statistics are made possible by the willingness of vendors (and their customers) to drop their pants to the most casual onlooker in a quite shameless manner. If you redesigned the entire industry based on "security is paramount" then this information would be a lot harder to come by. The ease of getting the information is therefore driven by the prioritising of marketing over security.

Furthermore, if an operating system or application is completely secure then it doesn't matter whether it is open-source or closed-source, in the same way that if AskTom is SQL injection-proof then it doesn't matter whether schema details are public knowledge or not.

Now, here's a key question: suppose you had a choice between the following options ...

i) A sign in your front-yard that said "ADT Security" (or whatever)

ii) A sign or notice from some independent authority that certified that "This building protected by a security system linked to a 24-hour montoring system" without saying what manufacturer's equipment was installed.

... which would be more secure? (Assuming that ADT isn't a million times better than the possible other options).

Mon Jul 31, 05:22:00 PM EDT  

Blogger Thomas Kyte said....

I like incremental refinement - Davids last comment is a good example of that I think.

Yes, perhaps it would be technically harder if the information were locked down - but as you noted, it is just out there, everywhere. In fact - we promote the technologies we use all of the time with press releases, marketing, "powered by" icons and the lot.

It just leaks out. That is why I'm not into "hiding stuff for security reasons" - because it invariably just gets out there. Always.


And since I cannot go 5 minutes without saying "bind variables", and I know every application SHOULD be sql injection proof for 100% of its DML, I just jump on it :)

JUST BIND and SQL Injection won't happen - can't happen. You have to concatenate user input into your sql and compile (parse) it. If you never concatenate user input - then no SQL Injection.

The fact that you get performance, scalability and better shared pool utilization - all the better.

And as I like to say in my seminar "All about binds" - when you don't bind, when you do have code that is SQL Injection capable - you must submit that code for review to at least five people smarter than you that don't really like you. They'll find your bugs...

See, it all comes back to binds, binds, binds :)

Mon Jul 31, 05:39:00 PM EDT  

Blogger David Aldridge said....

>> at least five people smarter than you that don't really like you

See that's just crazy talk. People who don't like me are idiots.

Mon Jul 31, 05:48:00 PM EDT  

Blogger jimk said....

While not knowing the specific technology helps to raise the bar on security it isn't something one should rely on. Why? I suspect that the largest thefts of information are similar to the most prevelant thefts in retail. Insiders. In retail people who already work there are more likely to steal than outsiders. They know they system, they understand its limitations. So it isn't an effective method. Security has to be strong enough to protect from an inside job.

Mon Jul 31, 06:12:00 PM EDT  

Blogger Noons said....

One thing I must say in favour of open source: it's relatively easy to give the would-be hacker a bum-steer.

Very easy to go into the source code of Apache and slightly modify the info it gives out so it looks like a different version, or a different piece of software.

That way, one can have a degree of confidence a possible invader will be knocking at the wrong doors.

A common technique used in many security conscious sites or where absolute security is demanded, it is a simple variation of the ages old bait-and-switch.

Sometimes it pays to deceive... :-)

Mon Jul 31, 10:59:00 PM EDT  

Anonymous RobH said....

Wow, this got Tom really fired up! This has to be the most comments by him in a single post....

(hacking the blogger.com database to query: select count(*), comments.COMMENT_ID from BLOGGER.COMMENTS$.USER_ID comments inner join BLOGGER.OWNER$.USER_NAME owner on owner.USER_ID = comments.USER_ID where owner.USER_NAME ='tkyte';)

Tue Aug 01, 09:07:00 AM EDT  

Anonymous Alex Gorbachev said....

What is your take on open source?

Well... depending on how immature the open source product is, I could feel uncomfortable knowing that sources are available.
If product is mature and well supported/developed (say Linux) than "open-sourceness" stimulates better quality (I must have read it somewhere obviously, but it makes sence).
If product is not that common (take some kind of open-source CRM, for example) than publicly available sources would rather harm security side of the software.

In the end you are right, maybe it's just me BELIEVING that obscurity should increase security. I also BELIEVE obscurity wouldn't make things less secure.

Anyway, the first answer should have been as usual "it depends" and the first "it depends" is on skills of developers.

Tue Aug 01, 07:45:00 PM EDT  

Anonymous Roy J. said....

>> at least five people smarter than you that don't really like you.

I will not claim to be smarter than Tom and I will certainly not claim to "really don't like" Tom :-)

Submit it for review to someone with a "testing state of mind" and that have experience with testing and/or reviewing:-).

(see Selective System Grants and SQL Injection Rejection)

>> To me – it is more of a binary thing, either your application is subject to SQL Injection attacks or it is not.

I agree. However, your application could have "openings" for SQL injection but you think you have thought of, and prevented, every possible way that this can be exploited. If you are just 98% sure you have handled every unwanted situation, it would be a good idea to hide your code/schema.

Whether your application is subject to SQL Injection attacks is binary. Whether your think your application is subject to SQL Injection attacks are not necessarily binary if you are using dynamic sql in some form...

Wed Aug 02, 05:00:00 AM EDT  

Anonymous Pete Finnigan said....

Hi Tom,

A bit late to comment but I have been at Blackhat last week. I have a couple of observations:

I agree with your sentiments wholeheartedly that if you are secure no amount of table, view or whatevre name exposure will make the system any more insecure.

My issue would be that there could be other insecurities that you have not thought about that by making tables or procedure names available could make them easier to exploit. This is simply defence in depth. Whilst on the face of it it is security through obscurity it can also be part of a defence in depth approach.

I have no idea of your schema or code but for instance it may be possible to inject directly via a URL, it may be possible to inject via a built in procedure that you have used. If it is possible to inject via other means than your own API then knowledge of your schema could help a defacement or other damage. It could also be possible to use a different exploit to gain access to your database either externally through the web interface or internally and knowledge of your schema and API could be useful to a hacker.

So whilst I agree with your view and also agree the worth of security through obscurity its still worth (IMHO) emplying defence in depth methods.

Also, if you use objects in dynamic statements then binds are not possible (i guess from your post that you dont). Alex has shown recently that DBMS_ASSERT can be bypassed for instance

cheers

Pete

Mon Aug 07, 01:12:00 PM EDT  

Blogger Thomas Kyte said....

Also, if you use objects in dynamic statements then binds are not possible

that is absolutely not true!!!!!

It needs API support, but the popular API's support it (and trying to do objects with concatenation would be a horrible thing to attempt - oh my, just building that string :)


ops$tkyte%ORA10GR2> create or replace type myType as object
2 ( x number,
3 y date,
4 z varchar2(30)
5 )
6 /

Type created.

ops$tkyte%ORA10GR2> create table t ( a myType );

Table created.

ops$tkyte%ORA10GR2> declare
2 l_data myType := myType( 1, sysdate, 'hello world' );
3 begin
4 execute immediate 'insert into t values ( :Z )' using l_data;
5 end;
6 /

PL/SQL procedure successfully completed.




Alex has shown recently that DBMS_ASSERT can be bypassed for instance

what he demonstrated was that IF you use dbms_assert incorrectly, not as intended, it can be dimished. It does what it does - nothing more, nothing less. It was not an example of bypassing, it was an example of improper use of dbms_assert.

Mon Aug 07, 08:54:00 PM EDT  

Blogger Alexander Kornbrust said....

Hi Tom


Even if you believe that SQL Injection is not possible on your webpage, showing error messages from the underlying database is at least bad style (from the security perspective) and allows at least information disclosure. It is more
difficult to exploit blind SQL injection vulnerabilities than non-blind sql injection types.


Quite often error messages are the easiest way to retrieve information from the database via SQL injection. Here is a quick example:

append the following string to a (vulnerable) number field (e.g.an URL contains orderid=11)
"orderid=11||utl_inaddr.get_host_name((select 'Users='||count(*) from all_users))".

The resulting error message shows the username ("ORA-29257 host Users=17 unkown").



As mentioned from previous posters a developer should always implement security in depth. NEVER believe that the underlying application/database you are using is 100%secure (no binary in Security!). Only sales people believe that everything is 100% secure.

Here some examples:
* database logon trigger can be bypassed in all versions of Oracle, status: unfixed
* SQL Injection vulnerability in the core APEX/HTMLDB, status: unfixed
* ...


It's not my task to do a security audit of asktom.oracle.com but here are some (potential) security problems with asktom (and all APEX/HTMLDB related apps). More
information about hacking and hardening APEX/HTMLDB will be presented at the UKOUG:


1. Cross Site Scripting (XSS/CSS)

Due to the architecture of the application HTMLDB/APEX (missing input validation in htp.p in many places) is full of XSS. I reported many XSS in HTMLDB/APEX. This means that your application is also vulnerable against Cross Site Scripting.

If you are interested I can send you an asktom link containg my custom Javascript.

But be careful if you click on the link ;-) I can even run OS commands on your client formatting your harddisk (using an 0day for IE or firefox).
Most people don't understand / underestimate XSS vulnerabilities.


2. Information disclosure

By changing the debug flag in the URL to YES it is possible to see valueable information for an attack. By adding "::YES" to an APEX/HTMLDB URL you can get a lot of useful information (usernames "user=PUBLIC_USER", SQL/PLSQL commands, ...).

I would highly recommend to disable this functionality in production systems. Why is Oracle not blocking this by default? How can I disable this debug information?


3. SQL Injection bugs in mod_plsql
David Litchfield reported a PL/SQL injection vulnerability in mod_plsql last year which was fixed with the April 2006 CPU. Every site using mod_plsql (without April/July 2006 patches) is still vulnerable. Exploits for this vulnerabilities are available in the hacker scene.


4. SQL Injection bug(s) in APEX/HTMLDB
The core APEX/HTMLDB contains a least one SQL Injection bug (reported to Oracle secalert 20-oct-2005). Even if your (custom) code is OK I could exploit your
application using this vulnerability (if you use a special feature). There are no (security) patches for APEX/HTMLDB which means that this bug will never fixed in current versions.



Concerning dbms_assert:
I could bypass dbms_assert in 36+ Oracle system packages. At least it is not an uncommon problem.

You could also say that SQL Injection does not exist it's just an example of improper use of dbms_sql/execute immediate.



Cheers

Alexander Kornbrust

Tue Aug 08, 07:40:00 AM EDT  

Blogger Thomas Kyte said....

You could also say that SQL Injection does not exist it's just an example of improper use of dbms_sql/execute immediate.

WELL SAID, like I said, sql injection is a binary thing - either:

a) you are subject to it
b) you are not.


My point with the error message is that if you believe "by not showing the column names, we are more secure" - you are as deluded as the insurance companies with the electronic theft system and the belief that the car is un-stealable.


I hate it when people become deluded. They are lulled into a false sense of security.


send me the link, I'm interested.

Tue Aug 08, 07:48:00 AM EDT  

Blogger Thomas Kyte said....

Alexander - one more thing

so, what is your take on open source, whereby everything is just sitting there, everything is readable, anyone can see the code, the column names, all of it?

See, my stuff has been published more than once, installed all over the place.

The names are not a surprise, not a secret, they are well known.

As they would be for most all 3rd party applications as well.


as for:

...
append the following string to a (vulnerable) number field (e.g.an URL contains orderid=11)
"orderid=11||utl_inaddr.get_host_name((select 'Users='||count(*) from all_users))".
....


or, just append:

orderid=11 union all
select ... from dual --

I don't really need to know the column name (i might have to run it a couple of times if I didn't know how many columns they selected to get the union all working, but that just takes seconds)

I don't really need to know your column names.

SQL Injection is an example of dynamic sql being used improperly - you said that very nicely, I agree entirely.

It is a bug in the developed code and you either have it or you don't.

And the column names are known to many people regardless - I'm worried that people think "because we hide the error messages, no one will be able to figure out how to sql inject us so we are safe"

When you know (you know) they are not safe at all.

Tue Aug 08, 08:13:00 AM EDT  

Anonymous Pete Finnigan said....

Hi Tom,

Sorry Tom, my brain was still on US time and my body in the UK. I misled you, I didnt meant "objects" as in PL/SQL objects I meant to say that you cannot substitute object names (tables, views, columns) only literals with bind variables. What I was leading onto was the use of DBMS_ASSERT to validate the object names and hence mention that Alex had found "mis-use" of the package.

cheers

Pete

Tue Aug 08, 08:14:00 AM EDT  

Blogger Michael Friedman said....

I think you are wrong here.

1. There may be bugs in your underlying tool set (ie. APEX). Exposing information may enable attacks through those routes.

2. Unless your system is truly interesting enough to have been reviewed by large numbers of people at the source code level you have probably made at least one mistake coding it that has not yet been found. Why give a potential attacker more information he can use in an attack?

Sat Aug 12, 03:32:00 AM EDT  

Blogger Thomas Kyte said....

Michael,

I'll ask what I've asked before - so, what is YOUR take on open source then?

What about 3rd party products - is SAP, Peoplesoft, whatever unsafe because I can see their schema?

Here is the thrust of what I'm trying to say here:

Pointy haired managers are deluded into thinking 'we are secure because we've hidden things' (and oh, the scads of people I've seen saying just that - after showing me the entire thing) - they have deluded themselves.

Just like the insurance companies have (see referenced wired article above, it is perfect).

It is deluded thinking that says "if we keep schema's hidden, we are more secure"

Just 'view source' someday - guess what you see in there? I'll betcha you see scads of - well, column names, table names and their ilk.

Why? Because no one uses:

X2143123Afdafa23

as the "input type=text" name - when they are dealing with the ENAME column...

So, we'll have to continue to agree to disagree.

The APEX schema - well known.
SAP - well known
All open source - well known

Every piece of code you've ever written for production - well known enough by a community of people well versed in ways to attack it once you've fired them.

and so on.


I just don't want anyone deluded into a false sense of security - got a problem, got to fix it, you cannot hide it.

In closing:

USE BINDS

when you cannot use binds - that code just became INTERESTING ENOUGH.

Sat Aug 12, 02:11:00 PM EDT  

POST A COMMENT

<< Home