'SAS'에 해당되는 글 2건

  1. 2013.08.21 Secret code

Secret code

View Comments




I blogged recently on ways to obfuscate data in SAS. Today I'll discuss some ways to secure SAS program code.

If you need to run SAS in a secure manner, here are a few starting points before we look at the code itself

Use the meta engine and metadata-bound libraries 

The meta engine is a reference in code to a library definition stored in metadata.
Where a traditional SAS libname statement looks like this:

libname demo1 "C:\temp";

a meta libname statement looks like this

libname demo2 meta library="My project library";

and points to a library defined in metadata, named "My project library" .

By going through metadata, users are subject to metadata security. 
They must to provide their SAS credentials to connect, but they no longer need to know anything about how the connection is made as metadata contains the "real" connection information, such as:
-the libname that will be used 'behind the scenes'
-the engine that will be used (which could be base, or Oracle, or any other SAS engine)
-any other connection arguments such as path or schema
-optionally, any credentials required

Users need only remember their SAS password as SAS can provide all other credentials for them transparently.
And if the data moves to a different location or even a different RDBMS, the administrator can redefine the metadata and nothing needs to be changed in the SAS code.

For more see http://support.sas.com/documentation/cdl/en/lrmeta/63180/PDF/defaul...

Metadata bound libraries are a feature introduced with SAS 9.3
Items in a metadata-bound library are assigned a password which is stored in metadata. When the user connects via metadata, the password is provided to the table transparently, and connections bypassing the metadata will fail.

To quote from the documentation:
Access from SAS to data within a metadata-bound library is provided only if all of the following conditions are met:
•The requesting user can connect to the metadata server in which the corresponding object is stored.
•The requesting user’s metadata identity has all required metadata-layer effective permissions for the requested action.
•The host identity with which the data is retrieved has all required host-layer access to the data

For more, see http://support.sas.com/documentation/cdl/en/seclibag/65159/PDF/defa...


Don't store credentials in your scripts

If a script has to be able to log on automatically (for example, if it needs to connect to your email system or to a secure FTP site when run as a scheduled job) then use macro variables, populated by a secured calling script. 
If your script is run in isolation, there is nothing there but unresolvable macro variable references.

To secure the script which creates the macro variables, consider one of the options below.

Options for securing SAS code

Option 1: SAS Program entries


"Traditional" SAS programmers are taught that SAS stores items in two places.

SAS data goes into SAS datasets, which live in SAS libraries
- So profit information could be stored in WORK.PROFIT
Everything else goes into SAS catalogs, which also live in SAS libraries.
- so a format to display money in pounds could be stored as WORK.CATALOG1.POUND.FORMAT

Actually there's a third item which isn't a data set, or a catalog or catalog entry.
It's called a SAS program entry and you create one like this

data x /pgm=work.prog1;
  set sashelp.class;
  newage=age+1;
run;

When the code is submitted the program doesn't execute. Instead the log has this message

NOTE: DATA STEP program saved on file WORK.PROG1.
NOTE: A stored DATA STEP program cannot run under a different operating system.
NOTE: DATA statement used (Total process time):
      real time           0.17 seconds
      cpu time            0.06 seconds


SAS has compiled the code and stored it "ready to run" on this operating system.

To run the program, submit this (note there's no slash before "pgm" this time)

data pgm=work.prog1;
run;

NOTE: DATA STEP program loaded from file WORK.PROG1.
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The data set WORK.X has 19 observations and 6 variables.
NOTE: DATA statement used (Total process time):
      real time           0.30 seconds
      cpu time            0.04 seconds


The data set is created, but the log doesn't show the code which ran. 
The code can be displayed by adding the describe statement like this

data pgm=work.prog1;
  describe;
run;

Now SAS will display the code instead of executing it. 
To describe and execute the code, add the execute option too.

data pgm=work.prog1;
  describe;
  execute;
run;

The Redirect option can be used to change the data used, like this.

data pgm=work.prog1;
  describe;
  execute;
  redirect output x=y;
run;

The log shows that the table "x" was routed to "y" instead.

data x /pgm=work.prog1 (pw=XXXX);
   set sashelp.class;
   newage=age+1;
run;


NOTE: DATA STEP program loaded from file WORK.PROG1.
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The data set WORK.Y has 19 observations and 6 variables.
NOTE: DATA statement used (Total process time):
      real time           2.87 seconds
      cpu time            0.09 seconds


So this can be used to store, recall and run the program. But what about preventing unauthorised execution?

And what if I didn't want people to know what the statements were? Again, there are options for this.

Password protecting code execution

data x /pgm=work.prog1 (pw=fred);
  set sashelp.class;
  newage=age+1;
run;

Now when I try to run the code, I must supply the password. 
If I know the password I can still see the statements though. 
To prevent program display I need to add the correct src= option

data x /pgm=work.prog1 (pw=fred src=nosave);
  set sashelp.class;
  newage=age+1;
run;

The log shows this

NOTE: DATA STEP program saved on file WORK.PROG1.
NOTE: The original source statements will not be saved with this stored DATA STEP program.  Also,
      a stored DATA STEP program will not run under a different operating system.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds

Even if I know the password for the program, when I try to display the code the log shows this:

data pgm=work.prog1 ;
  describe;
  execute;
  redirect output x=y;
run;

NOTE: No source statements were found in WORK.PROG1.PROGRAM.
NOTE: DATA STEP program loaded from file WORK.PROG1.
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The data set WORK.Y has 19 observations and 6 variables.
NOTE: DATA statement used (Total process time):
      real time           3.53 seconds
      cpu time            0.10 seconds


Limitations:
A stored program can contain only a single data step. 
Global statements like LIBNAME and OPTIONS aren't stored in the program entry.

So what if you want to store more than a single data step in each item? Then consider option 2

Option 2: Secured SAS macro programs

A SAS macro can contain global statements, procedures and multiple data steps.
On the downside, it can't be assigned a password on it in the same way as a SAS program entry. 
(Of course a SAS programmer would know how to code a macro to simulate a password requirement).  

Here's a simple example of storing code in a macro.

%macro storedcode;
data x;
  set sashelp.class;
  newage=age+1;
run;

proc print data=x;
run;
%mend storedcode;


To execute the code, invoke the macro like this

%storedcode

(Note there's no semicolon - it's a macro invocation, not a SAS statement).

However, the code in the macro can still be displayed by using the mprint option

188  options mprint;

189  %storedcode
MPRINT(STOREDCODE):   data x;
MPRINT(STOREDCODE):   set sashelp.class;
MPRINT(STOREDCODE):   newage=age+1;
MPRINT(STOREDCODE):   run;

NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The data set WORK.X has 19 observations and 6 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


MPRINT(STOREDCODE):   proc print data=x;
MPRINT(STOREDCODE):   run;

NOTE: There were 19 observations read from the data set WORK.X.
NOTE: PROCEDURE PRINT used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

There is a way to prevent this, although it takes a little work.
First, set up an area for storing compiled macros 

OPTIONS MSTORED SASMSTORE=name;
libname name 'C:\temp';

Then store the macro with the secure option

%macro storedcode /store secure;
data x;
  set sashelp.class;
  newage=age+1;
run;

proc print data=x;
run;
%mend storedcode;


Now start a new SAS session and assign the storage location. Invoke the macro as before


libname name 'C:\temp';
OPTIONS MSTORED SASMSTORE=name;
%storedcode

Calling the macro will retrieve it from the catalog and execute it, but the original statements can't be retrieved

Here's the SAS log 

1    libname name 'C:\temp';
NOTE: Libref NAME was successfully assigned as follows:
      Engine:        V9
      Physical Name: C:\temp
2    options mprint;
3    OPTIONS MSTORED SASMSTORE=name;
4    %storedcode

NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The data set WORK.X has 19 observations and 6 variables.
NOTE: DATA statement used (Total process time):
      real time           0.02 seconds
      cpu time            0.03 seconds



NOTE: There were 19 observations read from the data set WORK.X.
NOTE: PROCEDURE PRINT used (Total process time):
      real time           0.08 seconds
      cpu time            0.07 seconds


Warning!
There is no way to retrieve the original code. 
Keep a copy of the source code safe in case you ever need to 

- document
- audit
- edit
- inspect
- recompile the code to run on a different operating system

Considerations for Enterprise Guide users

Enterprise guide can reference catalogs using code just like a base SAS session. However, there are a couple of things to bear in mind.

1. The SAS session might not be on your local PC and the locations you can use for storage might be limited by your administrator. If you can, get your administrator to set up a shared location for these secure scripts.

2. Enterprise guide doesn't allow you to browse SAS catalogs "out of the box", but you can add a custom task to do this. It can be downloaded by following this link

http://blogs.sas.com/content/sasdummy/2013/03/18/sastalks-custom-ta...


Alternatively, why not save the code as items in an Enterprise Guide project and password - protect the Enterprise Guide project?

Option 3: Password protected Enterprise guide projects

To add a password to an Enterprise Guide project, go to File > Project properties > Security

The password is now required to open the project.

Limitation: the code cannot be called by other SAS scripts when embedded in this way. 
However, projects can be scheduled from within Enterprise Guide if you need a simple way to run them overnight. 
(Note, this doesn't use the LSF scheduler so has some limitations).

Comments (+add yours?)

Tracbacks (+view to the desc.)

Newer Entries Older Entries