Hacking using SAS

[last updated: 02 Aug 2008]

"All that is required for evil to prevail is for good men to do nothing."  --  Edmund Burke

Introduction

Before moving over to the field of clinical reporting in 1996 I had spent ten years as an MVS Capacilty Planner/Performance tuner, again using sas. In that job you sometimes come across hacking attempts or use of the computer that borders on hacking. As a "performance tuner" it was my job, if assigned to me, to thoroughly investigate any hacking attempts done by any user and to investigate their activities, possibly going back many months, using the archived system logs. My first experience was to see the JES3 print spool queue replaced by a sas output. This was most likely an inventive programmer's attempt to do a print in a novel way, except it knocked out everybody else's print jobs. The second was seeing a task with the seemingly obligatory name IAMGOD doing something it should definitely not be doing. In the second case, the person had their account cancelled with immediate effect, was dismissed and marched off the premises. In the first case, it was yet another entry on that person's file that stretched back for years. I bet he is still wondering why he never got a promotion. Since those times, hacking has become a worldwide pasttime.Nothing is sacred and nowhere is safe. Your sas jobs can be hacked too. What I intend to do on this page is increase the awareness of hacking for those in an IT position who look after sas production work. That is if anyone is in that position. Perhaps companies feel that no such post is needed. After reading this page, they might reconsider.

old-style macros

Most sas programmers have never heard of "old-style macros". If you have heard of these then it is likely you have worked with MXG software that is used for databasing performance and usage data from IBM mainframes (and now others). MXG uses old-style macros. What these old-style macros do is substitute a word (up to 8 characters) with what follows it until a "%" is encountered. MXG software uses an underscore as the start of a name where it is making a substitution, but it doesn't have to be an underscore for it to work. Firstly, I would like to wake you up to the existence of this macro style. Below I have created a deliberate syntax error in the old-style macro name and the sas compiler has warned me about it.
 
1    macro (bad) dummy dummy %
ERROR: Old-style macro name ( must contain only letters, digits, and underscores.

In this next example I have got the syntax correct and you can see what the old-style macro is doing.
 
2    macro naughty DUMMY DUMMY %
3    %put >>>>>> You are a naughty hacker >>>>>>>;
>>>>>> You are a  DUMMY DUMMY   hacker >>>>>>>

Can you see that it has found the word "naughty", which is the macro name, and has substituted that word with what follows "naughty" in the macro definition. It's substitution powers are limited. This is really important to know. See what happens when I put "naughty" in quotes. No substitution is made.
 
1    macro naughty DUMMY DUMMY %
2    %put >>>>>> You are a naughty "naughty" hacker >>>>>>>;
>>>>>> You are a   DUMMY DUMMY   "naughty" hacker >>>>>>>

We will use that bit of good news (i.e. the substitution is not made inside quotes) later.

Old-style macros are limited to 8 characters in length. You will see that the following attempt at a substitution does not work. Note that sas did not produce any diagnostics to say that the name was too long.
 
4    macro mendacious DUMMY DUMMY %
5    %put >>>>>> You are a mendacious hacker >>>>>>>;
>>>>>> You are a mendacious hacker >>>>>>>

Substitutions are made for words and not part of a string. Here is the "naughty" example again but with "naughty" inside "z"s. No substitution is made.
 
6    macro naughty DUMMY DUMMY %
7    %put >>>>>> You are znaughtyz hacker >>>>>>>;
>>>>>> You are znaughtyz hacker >>>>>>>

Now we come to the part where we substitute a name with another one with a different meaning. Firstly, here is the output with no old-style macro substitution being made. The result is as expected.
 
5    %put >>>>>> %sysfunc(trim(hacker)) >>>>>>>;
>>>>>> hacker >>>>>>>
6    %put >>>>>> %trim(hacker) >>>>>>>;
>>>>>> hacker >>>>>>>
7    run;

Now an old-style macro makes a substitution. Look at the output carefully. Do you see that the first "trim" has been substituted but the send "trim" not. Old-style macros will not substitute for macro names. This is important.
 
8    macro trim reverse %
9    %put >>>>>> %sysfunc(trim(hacker)) >>>>>>>;
>>>>>> rekcah >>>>>>>
10   %put >>>>>> %trim(hacker) >>>>>>>;
>>>>>> hacker >>>>>>>
11   run;

In the above case the %trim macro had already been complied. Now what I will do is save the code, quit the sas session, restart it and rerun it. This is what I got.
 
1    macro trim reverse %
2    %put >>>>>> %sysfunc(trim(hacker)) >>>>>>>;
>>>>>> rekcah >>>>>>>
3    %put >>>>>> %trim(hacker) >>>>>>>;
MACRO CALLED:   reverse   v1.0
NOTE: Autocall member, TRIM, has not been compiled by the macro processor. It may contain a macro
      syntax error or not define a macro with the same name as the member.  To autocall this
      member again, set OPTION MRECALL.
>>>>>> (hacker) >>>>>>>
4    run;

The difference in the above case is that as the %trim macro is being compiled, the old-style macro is acting on it before the compilation stage and has replaces the name of the macro "trim" with "reverse" and so the macro name is not the same as the autocall program name and so a compilation error occurs.

You are not encouraged to use old-style macros. You should never use them, in fact, for any new work you do but you may have to maintain some old code where they are used and you might be confused as to how they work. If you want to know more about these old-style macros and their syntax then follow this link on the sas support site.

Syntax for old style macros

Hopefully you now know that there exists a different style of macro than the ones you are used to, called "old-style macros" and you can see how they work and their limitations. Next you will see how they can be used for hacking.

Using old-style macros for hacking

Consider that your organisation has spent a great deal of money writing some reporting macros. They think these macros are very valuable and they don't want anybody to see the code that underlies them. So somewhere in their macro they try to hide the code from the outside user by resetting system options as follows.
 
options nomprint nosymbolgen nomlogic nomacrogen nospool nosource nosource2 nonotes;

Note that some of the option names above are 8 characters or less. They are ripe for being substituted by old-style macros. Suppose the hacker uses this code before calling this precious macro.
 
macro macrogen nomacrogen %
macro nomprint mprint %
macro nomlogic mlogic %
macro nospool spool %
macro nosource source %
macro nonotes notes %

Let's try this out and look at the MPRINT option setting. Do you see that MPRINT is in effect even though, within the macro, NOMPRINT was specified. I checked in sashelp.voption and indeed, MPRINT is in effect and not NOMPRINT. Macro hacked! Do you see how easy it is?

And look at the hacker turning macrogen into nomacrogen. Why are they doing that? The answer is that "macrogen" is for old-style macros and shows where these old-style macros are being used. The hacker does not want the user to see this. If they want some real macro code then they will want the MPRINT option setting.
 

1    macro nomprint mprint %
2    macro nomlogic mlogic %
3    macro nospool spool %
4    macro nosource source %
5    macro nonotes notes %
6
7    options nomprint nosymbolgen nomlogic nomacrogen nospool nosource nosource2 nonotes;
8
9    %put >>> %sysfunc(getoption(mprint)) >>>>>;
>>> MPRINT >>>>>

The possibilities for using old-style macros to substitute words like that are endless. You may think that a "compiled" macro is something that can not be looked at. Well, unless you are using sas v9.2 or later with the "secure" option for the macro compilation then all a person has to do is to open the compiled macro in a text editor. Most of the code can be seen. The hacker can decide exactly what substitutions will be of benefit to them and make those substitutions if they so wish, so long as the words are 8 characters or less. There is not much you can do about it. However, remember that these old-style macros will not substitute macro names. They will not make substitutions in other old-style macros either. So if you have this in your macro code at the top of the code then these hacking attempts are thwarted and will never give honest sas code a problem.
 
macro nomprint NOMPRINT %
macro nomlogic NOMLOGIC %
macro nospool NOSPOOL %
macro nosource NOSOURCE %
macro nonotes NONOTES %

An anti-hack that won't work

Old-style macros are applied right at the end of all other processing, including all normal macro and macro variable processing, so you see that assigning the word "nomprint" to two macro variables will fail and the old-style macro will take effect only after "nomprint" has been resolved -- which then gets hacked. Take a look.
 
26   options macrogen;
27
28   macro nomprint mprint %
29
30   %let var1=nom;
31   %let var2=print;
32
33   options &var1.&var2;
NOTE: The old-style macro NOMPRINT is beginning resolution.
34  + mprint
NOTE: The old-style macro NOMPRINT is ending resolution.
35
36   run;
37
38   %put >>>>> %sysfunc(getoption(mprint)) >>>> ;
>>>>> MPRINT >>>>

Using %listm (or %mlist)

If you have sas then you have both of the macros %listm amd %mlist. Isn't it strange that you can't find them in the online documentation? There is a reason for that, from what I have read, and that is the SI wished they could have gotten rid of old-style macros many years ago. As I said, they can't, as MXG uses them and they sell a lot of site licenses on the back of MXG. They just hope, maybe, that it would all be forgotten -- yet MXG users certainly know they are there -- and so will any hacker worth their salt, who is intent on hacking sas code. If you are an IT person looking after production sas jobs then you are at a disadvantage against hackers. Hackers know old-style macros exist and what they can do with them. As an IT person with no experience of MXG software -- you don't have a clue that old-style macros exist! Luckily, you can use %listm (or %mlist) to thwart attempts to hack your sas code by detecting the existence of old-style macros.

Up until now you have very likely never heard of %listm so I will start up a fresh sas session and see what I get when I call the macro.
 
1    %listm;
NOTE: Old-style macro directory is empty.

Now I will set up an old-style macro that I hope will do a bit of good hacking for me and call %listm again. I'll quit sas and start a new session.
 
1    macro nomprint mprint %
2    %listm;
Old-style macro directory:
   NOMPRINT

You can see that if the old-style macro directory is empty then we get a "NOTE" statement of the above form with the word "empty" in it and if it has members then it is not a "NOTE". The messages are written to the log and we can redirect the log if we want to. We want to in this case. Note that I have set up the macro variable "osmempty" (old-style macros empty) to determine or not whether the macro library is empty.
 
3    macro nomprint mprint %
4    proc printto log="C:\spectre\osmacros.txt" new;
5    run;

NOTE: PROCEDURE PRINTTO used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
 

9
10   %let osmempty=0;
11   data _null_;
12     infile "C:\spectre\osmacros.txt";
13     input;
14     if not index(_infile_,"Old-style") then delete;
15     put _infile_;
16     if index(_infile_,"NOTE: Old-style macro directory is empty.")=1 then call
16 ! symput("osmempty","1");
17   run;

NOTE: The infile "C:\spectre\osmacros.txt" is:
      File Name=C:\spectre\osmacros.txt,
      RECFM=V,LRECL=256

Old-style macro directory:
NOTE: 11 records were read from the infile "C:\spectre\osmacros.txt".
      The minimum record length was 0.
      The maximum record length was 50.
NOTE: DATA statement used (Total process time):
      real time           0.04 seconds
      cpu time            0.04 seconds
 

18
19   %put osmempty=&osmempty;
osmempty=0
 

The old-style macro library is not empty in the above case due to the presence of the "nomprint" macro. I will now delete this macro, using the %delete macro, and rerun. This time the library is empty and this is reflected in the value of the "osmempty" macro variable.
 
20   %delete nomprint;
21   proc printto log="C:\spectre\osmacros.txt" new;
22   run;

NOTE: PROCEDURE PRINTTO used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds
 

26
27   %let osmempty=0;
28   data _null_;
29     infile "C:\spectre\osmacros.txt";
30     input;
31     if not index(_infile_,"Old-style") then delete;
32     put _infile_;
33     if index(_infile_,"NOTE: Old-style macro directory is empty.")=1 then call
33 ! symput("osmempty","1");
34   run;

NOTE: The infile "C:\spectre\osmacros.txt" is:
      File Name=C:\spectre\osmacros.txt,
      RECFM=V,LRECL=256

NOTE: Old-style macro directory is empty.
NOTE: 10 records were read from the infile "C:\spectre\osmacros.txt".
      The minimum record length was 0.
      The maximum record length was 50.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
 

35
36   %put osmempty=&osmempty;
osmempty=1
 

So it looks as though we have a way of thwarting the hacker. But then, any hacker worth his salt will suspect you have such a check in place and will attempt to negate both the %listm and the %mlist macros. I'll start a fresh session, define the old-style macro, and attempt to cancel out the %listm and %mlist macro.
 
1    macro nomprint mprint %
2
3    %macro listm;
ERROR: Macro LISTM has been given a reserved name.
ERROR: A dummy macro will be compiled.
4    %put NOTE: Old-style macro directory is empty.;
5    %mend listm;
6    %macro mlist;
ERROR: Macro MLIST has been given a reserved name.
ERROR: A dummy macro will be compiled.
7    %put NOTE: Old-style macro directory is empty.;
8    %mend mlist;
9
10   proc printto log="C:\spectre\osmacros.txt" new;
11   run;

NOTE: PROCEDURE PRINTTO used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
 

15
16   %let osmempty=0;
17   data _null_;
18     infile "C:\spectre\osmacros.txt";
19     input;
20     if not index(_infile_,"Old-style") then delete;
21     put _infile_;
22     if index(_infile_,"NOTE: Old-style macro directory is empty.")=1 then call
22 ! symput("osmempty","1");
23   run;

NOTE: The infile "C:\spectre\osmacros.txt" is:
      File Name=C:\spectre\osmacros.txt,
      RECFM=V,LRECL=256

Old-style macro directory:
NOTE: 11 records were read from the infile "C:\spectre\osmacros.txt".
      The minimum record length was 0.
      The maximum record length was 50.
NOTE: DATA statement used (Total process time):
      real time           0.04 seconds
      cpu time            0.04 seconds
 

24
25   %put osmempty=&osmempty;
osmempty=0
 

The hacker has been foiled in the above case. They can not replace the macros %listm or %mlist with their own versions. It looks as though we have beaten the hacker so long as we test for old-style macros and abort the sas job if any are detected. If osmempty=1 we carry on, if osmempty=0 we abort, running %listm again to give us a list of the old-style macros used in attempting the hack.

This looks good! It looks like we have beaten the hacker. Have we won? Have we beaten the hacker? Have we, have we? The answer is "maybe". There is an attack point in your solution that the hacker can try to exploit. That is the macro variable name you use to do the check --  "osmempty" to be specific. Even if your macro is compiled, the hacker can find the name of the macro variable you are using by opening up your compiled macro in a text editor. And you have used the unique name "osmempty" that is a perfect target for attack, especially because your macro variable name is 8 characters or less and so is available to be substituted using an old-style macro. They can try to substitute that name with another macro variable name that they have set to "1" before calling your macro. The hacker stands a chance here but will the hacker succeed? Let's see. Here is the code followed by the log message.
 
macro osmempty haha %
macro nomprint mprint %

%let haha = 1;

options mprint;

%macro test;
  proc printto log="C:\spectre\osmacros.txt" new;
  run;
  %listm;
  proc printto log=log;
  run;

  %let osmempty = 0;
  data _null_;
    infile "C:\spectre\osmacros.txt";
    input;
    if not index(_infile_,"Old-style") then delete;
    put _infile_;
    if index(_infile_,"NOTE: Old-style macro directory is empty.") = 1 
      then call symput("osmempty","1");
  run;

  %put >>> osmempty = &osmempty >>>>;

  %if &osmempty = 1 %then %put It is safe to carry on;
  %else %put We have been hacked - we must abort;
%mend test;
%test
 

>>> osmempty = 0 >>>>
We have been hacked - we must abort
 

The hack against the counter-hack should have worked in the above case but it didn't. But to be on the safe side, if you are going to use a macro variable in this way to detect the presence of old-style macros then you should take precautions and make it more than 8 characters long so that there is no way it can be substituted. "osmempty" was a stupid macro variable name to use due to it being 8 characters long or less. When you counter-hack, you have got to put yourself in the position of the hacker who is going to attempt to hack your counter-hack. Leave no vulnerabilities. Thoroughly attempt to hack your solution yourself in any way you can. Better still, get another competent programmer to attempt to hack your solution as it is human nature to be unaware of our own weaknesses and failings.

Can we relax now?

You can use %listm to detect whether there have been any old-style macros set up. Using the above methods you should be able to keep that door closed. But if you did all those things, would you be safe?

The answer is "no". There are data sets.....................................  and then there are views.

Hacks inside Views

A data set is a fairly safe thing. A view is not. You can put extra processing in views. You could have a "call execute" in your view or a "call symput". In the "call execute" you could reset system options if you wanted to. In the "call symput" you could reset the contents of one or more very important macro variables. Using a "call execute", what you can achieve is limited only by your imagination.. Let's see an example of this at work used against the NOMPRINT option.
 
18   options nonotes;
19   data class / view = class;
20     if _n_ eq 1 then call execute('options mprint;');
21     set sashelp.class;
22   run;
23
24   options mprint;
25
26   %macro test(data=);
27     options nomprint;
28     %put >>>>>> Before data step: %sysfunc(getoption(mprint)) >>>>>>>>>>>;
29     data _null_;
30       set class;
31     run;
32     %put >>>>>> After data step: %sysfunc(getoption(mprint)) >>>>>>>>>;
33   %mend test;
34
35   %test(data=class);
MPRINT(TEST):   options nomprint;
>>>>>> Before data step: NOMPRINT >>>>>>>>>>>
1   + options mprint;
>>>>>> After data step: MPRINT >>>>>>>>>

To negate this hack attempt, then if we allow Views, we must reset system options to what they should be directly after the data step. I have added "options nomprint" after the data step and this is what we get.
 
36   options nonotes;
37   data class / view = class;
38     if _n_ eq 1 then call execute('options mprint;');
39     set sashelp.class;
40   run;
41
42   options mprint;
43
44   %macro test(data=);
45     options nomprint;
46     %put >>>>>> Before data step: %sysfunc(getoption(mprint)) >>>>>>>>>>>;
47     data _null_;
48       set class;
49     run;
50     options nomprint;
51     %put >>>>>> After data step: %sysfunc(getoption(mprint)) >>>>>>>>>;
52   %mend test;
53
54   %test(data=class);
MPRINT(TEST):   options nomprint;
>>>>>> Before data step: NOMPRINT >>>>>>>>>>>
1   + options mprint;
MPRINT(TEST):   options nomprint;
>>>>>> After data step: NOMPRINT >>>>>>>>

In the above case we seemed to have solved the problem. The answer is to reset system options after each data step where the foreign data comes in first time. But what if there is a double hack attempt and the View contains an old-style macro definition? Here it is again but with an old-style macro defined in the View. MPRINT is back again!!
 
55   options nonotes;
56   data class / view = class;
57     if _n_ eq 1 then call execute('options mprint; macro nomprint mprint %');
58     set sashelp.class;
59   run;
60
61   options mprint;
62
63   %macro test(data=);
64     options nomprint;
65     %put >>>>>> Before data step: %sysfunc(getoption(mprint)) >>>>>>>>>>>;
66     data _null_;
67       set class;
68     run;
69     options nomprint;
70     %put >>>>>> After data step: %sysfunc(getoption(mprint)) >>>>>>>>>;
71   %mend test;
72
73   %test(data=class);
MPRINT(TEST):   options nomprint;
>>>>>> Before data step: NOMPRINT >>>>>>>>>>>
1   + options mprint; macro nomprint mprint %
MPRINT(TEST):   macro nomprint
MPRINT(TEST):   mprint  %
MPRINT(TEST):   options mprint ;
>>>>>> After data step: MPRINT >>>>>>>>>

Is there a lesson to be learned from this? Yes there is. That is, if you are allowing Views, to have data steps at the top of your macro where they are read in and then follow that with your old-style macros that thwart hack attempts followed by your desired system options or used %listm, as shown above, to abort your job if any old-style macros are detected.

What about banning the use of Views? It's up to you. I have  macro named %mtype which will test a dataset and return VIEW or DATA - but be careful when you test for the word VIEW. Maybe your hacker has added this to his armoury:
 
macro view DATA %

Maybe this one extra, old-style macro inside your own macro would be a good idea or, instead, use %listm in the way described above.
 
macro view VIEW %

The ultimate anti-hack macro?

I have written what I think is the ultimate anti-hack macro, but I might be proven wrong. You will see its code soon. It has no comments and therefore no explanation of how it works as I consider comment lines to be vulnerable to hacking attack. To be fair to the old-style macro language, a substitution will never be made in a comment line, but I can't be sure that somebody has found a way around this so I don't want any comment lines to be a target. The macro is called %osMacrosExist and it sets up a global macro variable of the same name (note that this is more than 8 characters so it can not be substituted using an old-style macro). It also sets up a fileref named capturel for capturing log output and then "clears" it. The intention is to call it as the first line of code within an important macro. If you are doing clinical reporting then nobody should be using old-style macros. They shouldn't have even heard of them, as they belong to sas version 5 or earlier. If any exist then you should abort. Also, any input data sets should be data sets and not views. Only then will you be safe from hacking attempts. You can use my %mtype macro for this but remember to put the test in quotes to prevent old-style macros from making substitutions. The following is safe:
 
%if "%mtype(dataset)" EQ "VIEW" %then %do;

But the following is not safe:
 
%if %mtype(dataset) EQ VIEW %then %do;

And now for the anti-hack macro, which time alone will tell whether I have made it hack-proof or not. It is simple enough to use. You should use it right at the start of your macro code and then test the setting of osMacrosExist and if it is set to 1 then exit the macro. But you have got to think.The code below shows a very big mistake.
 
%if "%mtype(dataset)" NE "VIEW" %then %goto allok;

There is a huge exposure to hacking in the above code. The hacker will find out that you have a label named allok that you jump to if everything is OK and they maybe have the chance to jump to that point directly using a "call execute" hidden inside their view, if the view gets the chance to run. You have got to be cleverer than that. Test tight and jump right to the macro exit, if you think anything is wrong.

So here comes the anti-hacking macro. It should be the first line of code inside your production macro and you should very carefully code the aborting of the macro if old-style macros are determined to be in existence. Remember, the reason there are no comments in the macro is because comment lines can also be the target of hacking attempts.

If anyone manages to hack this macro then please send me details.
 
%macro osMacrosExist;
%listm;
macro filename filename %
macro capturel capturel %
macro temp TEMP %
macro log log %
macro printto printto %
filename capturel TEMP;
proc printto log=capturel;
run;
%delete filename capturel temp log printto;
%listm;
proc printto log=log;
run;
macro capturel capturel %
macro infile infile %
macro _infile_ _infile_ %
macro index index %
macro call call %
macro symput symput %
macro then then %
macro do do %
macro input input %
macro put put %
macro end end %
macro data data %
macro warning WARNING %
macro clear clear %
%global osMacrosExist ;
%let osMacrosExist=0;
data _null_;
infile capturel;
input;
if index(_infile_,"Old-style") then do;
if index(_infile_,"Old-style")=1 then do;
call symput("osMacrosExist","1");
end;
end;
run;
filename capturel clear;
%delete capturel infile _infile_ index call symput then do input put end data warning clear;
%mend osMacrosExist;

Here is how I expect the %osMacrosExist macro to be used.
 
%macro secretmacro;
  %osMacrosExist;
  %if &osMacrosExist=1 %then %do;
    %put ERROR: Disallowed old-style macros have been detected and the list written to the log.;
    %let error=1;
    %goto error;
  %end;
  ...... etc.

But don't forget the views. Check for views and abort if you find any. And don't forget to use double quotes around the word in the form "VIEW" to thwart the hacker's attempt to hack your solution.

Should you be worried?

I would say that you have to consider the circumstances and work out whether it is worthwhile to protect your macros against hacking. It all depends on the risk. If these are financial macros and money is changing hands then it would be a good idea to fully protect your code against hacking attempts. If your SAS code had to produce the correct results otherwise some major accident could occur (like if it were doing calculations for a nuclear facility) then again it is best to protect your code fully.

I am very disappointed that the SAS Institute has chosen to cover up this weakness with SAS software. On the theme of the nuclear industry again, supposing a SAS system were in place to track the storage, location and movements of dangerous nuclear materials. Supposing this were controlled by read-only sas code. It would be the easiest thing in the world for a hacker to substitute the code, using old-style macros and views, to disguise the disappearance and theft of nuclear materials. And all done right under the noses of those who control the code, due to their being unaware of this weakness and the ease with which this weakness can be exploited.

Covering up a weakness in software does nobody any favours. Instead, it betrays an ignorance of the way hackers work and plays into their hands. Hackers have networks that share information about application or code weakness. Once one hacker knows then any interested hackers will know about it within days or hours. Not all hackers are up to mischief, however. If you look up "hacking" on Wiki you will learn that there are "white hat", "grey hat" and "black hat" hackers. A "white hat" hacker will attempt to find weaknesses in software and inform the software vendor about it and give them sufficient time to remedy the situation or to document the weakness so that IT staff can protect against it. If the software vendor refuses to do anything then the "white hat" hacker will document the weakness and explain how to combat hacking attempts. Hopefully, this document has achieved that.

Conclusion

On this page my aim was to make you aware about how hacking can be achieved using sas code and how this could affect your production environment. I have suggested some solutions but I can not guarantee that they will save you from some serious hacking attempts. If people are determined to hack your system, then they will eventually find a way. This is an eternal battle between IT administrators and the hacker.
 
 


 
 

Go back to the home page.

E-mail the macro and web site author.