Wednesday, September 28, 2016

ORDS 3.0.7 more secure by default

Defaulting  PL/SQL Gateway Security


Oracle REST Data Services 3.0.7 went out yesterday.  There's an important change that went in to better secure installations by default.  It has always been the case that we recommend customers set the validations for the plsql gateway.  There has always been a validation configuration option to lock down what procedures are accessible which was outlined in this blog post http://krisrice.blogspot.com/2013/01/apex-listener-plsql-validations.html


The change is that starting in this patch when the plsql gateway is enabled AND the db username is APEX_PUBLIC_USER, ORDS setup will add in the configurations setting  security.requestValidationFunction  to be set to the apex security procedure  WWV_FLOW_EPG_INCLUDE_MODULES.AUTHORIZE



Customized PL/SQL Gateway Security

This is just a defaulted settings so if you have a custom procedure just edit the file as normal. Alsoin the blog post that describes how this works there are new features over this basic procedure approach such as binding values like flow_id ( app id ), flow_setup_id ( page id ).  The uses of this are you could have one install of ORDS that is external facing and expose only one set of applications based on the APEX application ID. Then an internal ORDS setup that doesn't limit at all to have intranet applications all hosted out of one production database.

There's also the ability to use javascript for securing the PL/SQL gateway which has been around since version 2.0.  The main benefit with this approach is there doesn't have to be a trip to the database to exec a plsql procedure.  That means ORDS can stop a request before the database is ever called in any capacity.  The variables available for this are outlined in this blog post: http://krisrice.blogspot.com/2012/12/apex-listener-20.html



Here's the note in the README


Important Changes to Note

APEX_PUBLIC_USER & wwv_flow_epg_include_modules.authorize

In line with security best practice and as recommended by the Oracle Application Express Documentation when a database pool is configured to use the APEX_PUBLIC_USER, Oracle REST Data Services will automatically set the value of thesecurity.requestValidationFunction setting to be:
    WWV_FLOW_EPG_INCLUDE_MODULES.AUTHORIZE
  
This activates the white list of callable procedures which ships with Oracle Application Express and prohibits calls to other procedures. Please consult the Oracle Application Express Documentation for more information about this procedure and how to customize it's behaviour.

Wednesday, June 22, 2016

Kill DB sessions the easy way with SQLcl

Seems I can not tweet these animated GIFs anymore. So this is another very short blog post to show real case for adding a new command into SQLcl which can be downloaded here.

It's hard annoying tedious to find SID and SESSION then alter to kill that when needed.  What if there was a simple kill command.

Here a sample one that takes in the 2 options:
  kill sid serial#
  Example :   kill 1 2
OR
  kill USERNAME
  Example: kill KLRICE








Thursday, June 16, 2016

SQLcl and Query Change Notification

The database has had Query Change Notification for a while but to use it required a custom program. Such as Tim outlines on his blog https://oracle-base.com/articles/10g/dbms_change_notification_10gR2


Since SQLcl has Nashorn, now it can be integrated with a few lines of javascript to get notified when changes happen.  The script is below and posted.  The catch is QCN only works on Varchars and Numbers.







Monday, March 14, 2016

ORDS and PL/SQL

Seems I've never posted about PL/SQL based REST endpoints other than using the OWA toolkit.  Doing the htp.p manually can give the control over every aspect of the results however there is an easier way.

With PL/SQL based source types, the ins and outs can be used directly without any additional programming.  Here's a simple example of an anonymous block doing about as little as possible but should get the point across of what's possible.

The interesting part is on the Parameters tab.  There is where to define the IN , OUT, or IN/OUT.  These are a INs can be from the URI or from the HTTP Header.  This means if you want USER_AGENT to be useful in the the plsql block just define it and assign it to a bind variable.  Here is the :ct and :myval being defined.  The :ct is bound to the HTTP HEADER Content-Type.  The :myval is bound to RESPONSE. More robust support for UDTs is in the works.



Hopefully, this is no surprise as to what the output looks like.






Friday, March 04, 2016

DIY SQCL Commands



As mentioned once or twice or 100 times, sqlcl exposes javascript scripting with nashorn to make things very scriptable.  To learn more on Nashorn itself there's a lot of great write ups such as http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html  So far, the scripting examples have been along the lines of conditional or looping of existing sqlcl commands.

Here's an example of creating a brand new command only from javascript.  This is a pretty simple one that for ALL command will snapshot the start time and print the elapsed time.  It also adds the new command "kris".

Just to show this is really nothing that new to sqlcl, here's a blog post from 2006 about how to make a Java based CommandListener in SQL Developer. This hasn't changed since then.

This all adds up to if we forget to add some feature, you want to override a command, perform something before or after commands, it's very simple to DIY your sqlcl.







// SQLCL's Command Registry
var CommandRegistry = Java.type("oracle.dbtools.raptor.newscriptrunner.CommandRegistry");

// CommandListener for creating any new command
var CommandListener =  Java.type("oracle.dbtools.raptor.newscriptrunner.CommandListener")

// Broke the .js out from the Java.extend to be easier to read
var cmd = {};

// Called to attempt to handle any command
cmd.handle = function (conn,ctx,cmd) {
   // Check that the command is what we want to handle
   if ( cmd.getSql().indexOf("kris") == 0 ){
       ctx.write("Hi Kris, what up?\n");

       // return TRUE to indicate the command was handled
       return true;
    }
   // return FALSE to indicate the command was not handled
   // and other commandListeners will be asked to handle it
   return false;
}

// fired before ANY command
cmd.begin = function (conn,ctx,cmd) {
   var start = new Date();

   // stash something for later like the start date
   ctx.putProperty("cmd.start",start);
}

// fired after ANY Command
cmd.end = function (conn,ctx,cmd) {
   var end = new Date().getTime();
   var start = ctx.getProperty("cmd.start");
   if ( start ) {
      start = start.getTime();
      // print out elapsed time of all commands
      ctx.write("Elapsed Time:" + (end - start) + "\n");
   }
}

// Actual Extend of the Java CommandListener

var MyCmd2 = Java.extend(CommandListener, {
        handleEvent: cmd.handle ,
        beginEvent:  cmd.begin  ,
        endEvent:    cmd.end
});

// Registering the new Command
CommandRegistry.addForAllStmtsListener(MyCmd2.class);

Disqus for Kris' Blog