SAS® platform administrators can get quite familiar with the SAS NOXCMD option, usually when someone asks why their programs that used to work (in a different SAS version or execution environment) are now failing. Perhaps the programs ran ok with SAS Enterprise Guide 4.1 using a SAS 9.1.3 server but now fail with SAS Enterprise Guide 4.2 using a SAS 9.2 server. Maybe they were developing some code using SAS Display Manager (I know it’s no longer de rigueur but us old-timers will still confess to using it from time to time – some even quite proudly as a badge of honour!). When that code gets deployed in a stored process on a SAS 9.2 server it then starts failing (hmmm perhaps we should have been developing and testing it in SAS Enterprise Guide or SAS Data Integration Studio after all ;)). You may have seen logs with this error:
1 filename lscmd pipe 'ls -al /tmp';
ERROR: Insufficient authorization to access PIPE.
ERROR: Error in the FILENAME statement.
… or maybe this one:
ERROR: Shell escape is not valid in this SAS session.
1 %sysexec mkdir /tmp/test;
… these are the common error messages seen when trying to run external operating systems in a NOXCMD constrained environment.
If you do a Google search for these messages you might find these resources:
- Chris Hemedinger’s blog post “Using the X and SYSTASK commands from SAS Enterprise Guide” from Nov 2009, where he also explained how to overcome it with a single workstation installation of SAS Enterprise Guide and Foundation SAS.
- SAS Problem Note 41058: Unable to submit X commands from SAS® Enterprise Guide® connecting to a SAS® Metadata Server when running SAS® 9.2 or later. I noticed at the end of this SAS note it says “… the commands will execute on the metadata server and not on your local PC“. Whilst this would be the case if it were the SASMeta – Workspace Server (a workspace server restricted to metadata administrators that runs on the metadata server machine), it would only be the case for the SASApp – Workspace Server if the workspace server happened to be on the same machine as the metadata server. In many of the installations I see, the metadata server runs on its own dedicated machine, and so this is often not the case. To clarify, it runs the commands on the host machine that the SASApp – Workspace Server is configured to run on.
In the rest of this post I am going to provide some more info, from the platform administrator’s perspective, and try to offer some suggestions and pointers to additional resources that help you with the goal of trying to work with the NOXCMD option. Ideally we want to try to retain the security benefits by not turning it off for the entire user base, in a shared platform environment, when a subset of your users encounter it and perhaps try to persuade you to turn XCMD back on!
The NOXCMD option disables a number of SAS language features that allow the execution of operating system commands such as:
- the use of PIPE in the FILENAME statement (SAS documentation links for Windows and UNIX)
- the CALL SYSTEM routine
- the X command (SAS documentation links for Windows and UNIX)
- the %SYSEXEC macro statement
- the SYSTASK statement (SAS documentation links for Windows and UNIX)
The SAS documentation for NOXCMD can be found under its positive alternative, the XCMD system option. Here are links to the relevant documentation for Windows and UNIX.
We have become more familiar with NOXCMD in recent years because the the SASApp – Workspace Server, SASApp – Pooled Workspace Server and SASApp – Stored Process Server in SAS 9.2 installations commonly have the XCMD option disabled (i.e. NOXCMD). This is the default setting in newly installed SAS 9.2 deployments for its security benefits. To allow the general SAS user community (such as SAS Enterprise Guide users) to execute operating system commands on the servers, a SAS platform administrator has to make a conscious decision to enable XCMD, preferably after careful consideration of the potential security consequences ;). Here is a screenshot fragment showing where XCMD can be turned on in the server’s Launch Properties tab. You get to this tab using the SAS Management Console 9.2 Server Manager plug-in via the Advanced Options button on the Options tab in the server’s properties dialog.
While you are in the SAS Management Console, you might also notice that the SASMeta – Workspace Server is different in that it has XCMD enabled by default. Normal SAS users can’t use the SASMeta – Workspace Server because metadata access controls make it visible only to metadata administrators (members of the SAS Administrators group).
If you schedule SAS jobs to run in batch you might also want to check the NOXCMD status of the batch servers: SASApp – SAS DATA Step Batch Server, SASMeta – SAS DATA Step Batch Server and any others you may have. The XMCD/NOXCMD setting for these servers are specified not in metadata but in the batch server scripts. On Linux, my batch server scripts are in /usr/local/SAS/ebiedieg/Lev1/SASApp/BatchServer/sasbatch.sh and /usr/local/SAS/ebiedieg/Lev1/SASApp/BatchServer/sasbatch.sh. The SASApp one has -noxcmd whereas the SASMeta one has -xcmd. These are the default settings for batch server deployments in recent SAS 9.2 releases. If you have an older SAS 9.2 release (pre M2), you might find that the SASMeta one is also -noxcmd. The NOXCMD constrained SASMeta – SAS DATA Step Batch Server in older SAS 9.2 releases caused problems with scheduled metadata backups as described in SAS Problem Note 34923: A metadata backup that is scheduled to run by using the SAS DATA Step Batch Server might fail to copy the configuration files and the journal files
So what can you do if your security plan doesn’t allow you to enable XCMD for the general SAS user community, but some of your users, or batch processes, are failing to run operating system commands because of it? A couple of possible options include:
- using/suggesting native SAS language alternatives to operating system commands where possible;
- creating a new special purpose application server and associated workspace and/or stored process servers that are restricted in visibility (via metadata access controls) to a subset of trusted users/developers. There is a good example of this approach in Jim Fenton & Robert Ladd’s SAS Global Forum 2010 paper 311-2010: A Practical Approach to Securing a SAS® 9.2 Intelligence Platform Deployment
I’ll try to suggest some native SAS language alternatives to operating system commands in future blog posts. If you have any favourites yourself feel free to leave a comment.
I hope this post has helped you find out more about the NOXCMD option and that you don’t always have to turn it off at the first sign of trouble. Remember people tasked with managing security have a reputation to uphold: when it comes to security the first answer is almost always “no”, or perhaps the more pragmatic “no, but how about this alternative more secure method instead…” ;)
Paul, here’s one alternative to a common SYSTASK or SYSEXEC operation: copying a file from one location to another.
http://blogs.sas.com/sasdummy/index.php?/archives/261-How-to-use-SAS-DATA-step-to-copy-a-file-from-anywhere.html
Hi Paul,
Thanks for your article. The point looks unimportant at first sight but it is critical from an admin point of view. Without system commands, your SAS code is OS-free and could be launched both on Windows and on Unix/Linux as well. Moreover, some system command can have devastating impact on the SAS Compute Server (SASapp) : imagine, setting up an umask like 077 before updating some datamarts …
SAS code is highly portable as regards the access to the filesystem (broadly speaking). Chris gives above a good example of this using the data step buffer in binary mode. When the file’s size increases (eg > 1 Gb), other SAS features can be used to copy (transfer) binary files without any recourse to system commands, for instance using a MP Connect Session with Proc Download / Upload if SAS/Connect is licenced.
Some notes or technical documents on the subject :
http://support.sas.com/techsup/technote/ts581.pdf
http://support.sas.com/kb/25/074.html
http://www2.sas.com/proceedings/forum2007/008-2007.pdf
There are some limitations, of course but they’re not so obvious. Try, for example, getting the (Posix) Group Name out of a *directory* on Unix/Linux : DINFO function won’t give you much help, neither FINFO in that case :
http://support.sas.com/kb/42/606.html
Ronan
Hi Chris,
Thanks for your comment with the link to your blog post on platform independent file (and url) copying. That code looks very comforting to me as an old SAS/AF coder – it’s like SCL in a data step :)
Did you also see Ronan’s comment where he mentions that, assuming you have SAS/CONNECT licensed, another platform independent file copying method is to use MP CONNECT and proc upload/download to transfer a file to a different location on the same machine?
Cheers
Paul
Hi Ronan,
Thanks for your comment and links. You raise some interesting points about also trying to avoid platform dependant code. I especially like the idea of using MP CONNECT to connect back to the same machine and use standard SAS/CONNECT proc upload/download to copy files. That’s one I hadn’t thought of before! Have you by chance done any benchmarks comparing the relative performance of the operating system, data step, and MP CONNECT copy methods with large files? I’d be interested in hearing your results if you have.
I’d noticed that SASGF 2007 paper by Jason Secosky when I was looking for any existing data step directory traversal examples whilst responding to this question on stackoverflow recently: “How can SAS be used to determine the size of a directory in MBs (Windows)?” The question was for SAS 9.1.3 so the SAS 9.2 FCMP and data step example was not appropriate, but it did get me thinking about using PROC FCMP for a SAS language example for “du”. The directory traversal example in that paper is also in the documentation for PROC FCMP in the Base SAS® 9.2 Procedures Guide
Cheers
Paul
Paul,
Some bailouts are absolutely necessary because there is no SAS system command to call 3rd party apps. The built-in SAS functions are fine for O/S type operations but it doesn’t cover custom commands. Perhaps SAS should consider a ‘trusted app’ type of command that could be called and control passed to another application with parms.
I encounter this issue when we have used my product SaviCells which generates Excel binary files from an XML structure. We have to run a SAS datastep to generate the XML structures, then call SaviCells to interpret the XML and generate the XLS or XLSX files. If you have a suggestion for how to call out to a 3rd party exe, I am all ears.
Thanks for a great blog post,
Alan
Hi Alan,
Thanks for your comment.
I like your idea for a trusted apps list. A simple set of regular expressions, as a config option or maintained in metadata, for allowed X commands would be quite useful.
In terms of calling a third party executable with NOXCMD in force, I haven’t tried them yet, but since they are not specifically mentioned in the documentation as being blocked, I would try out:
1) the data step Java object capability to call a custom Java class which launches the required executable. This would require the compiled Java class on the server and the administrator to specifically make it available in the classpath on the server. The custom Java class could have a limited list of allowed commands.
2) using call module to call a custom DLL function (or maybe even custom OLE automation). With your background in Microsoft development technologies I’m sure you would know much more about the possibilities here than I would.
Of course these options might also be blocked even though they aren’t mentioned in the doc. I’ll try the Java option when I get some time. Please let me know what you discover if you try them out.
BTW I assume SaviCells does much more than can be accomplished using XSLT on the XML generated, otherwise you might be able to use proc xsl?
Cheers
Paul
Hi Paul,
This is the first time I write for you, although I follow your outstanding blog since 2010, when I let SAS DI development and started to administer SAS in my company.
At this moment we have same problem than related in this post. Some users want to allow XCMD for Enterprise Guide AppServer, but we are still looking for native SAS language alternatives to operating system commands. Do you know any alternative via native SAS language with XCMD disabled? We are trying to list a couple of files in UNIX directory and, moreover, read and convert then in SAS Data Set.
Thank you!
Hi Eduardo,
Thanks for your message and for following my blog too.
For some operations you will be able to find native SAS features to perform the work. Listing files in a directory can be done with a combination of dopen/dread/dclose functions. Here are some links to a few examples:
1) SAS Communities: “how to read filenames of a directory into a file” https://communities.sas.com/message/17067
2) SAS Communities: “Way to pick the latest file” https://communities.sas.com/message/56834
3) Base SAS(R) 9.2 Procedures Guide: The FCMP Procedure: Directory Transversal http://support.sas.com/documentation/cdl/en/proc/61895/HTML/default/viewer.htm#a003262733.htm
Once you know the file names you can read them via normal data steps and infile/input. If the filenames follow a known pattern (e.g. test*.csv) you can also use wildcards in a filename statement to read all files matching that pattern without necessarily knowing the individual filenames ahead of time.
If I understand your question correctly, I think you should be able to do everything you need without enabling XCMD, but if you find there are some other things you need to do that have to be done through operating system command or 3rd party executables you still might not need to open up XCMD access for everyone. The following conference paper has a nice example of using multiple application servers secured appropriately to direct users to a server with or without XCMD access enabled based on group membership for the user (assigned by trust/skill level).
SAS Global Forum 2010 Paper 311-2010: A Practical Approach to Securing a SAS® 9.2 Intelligence Platform Deployment, Jim Fenton & Robert Ladd http://support.sas.com/resources/papers/proceedings10/311-2010.pdf
I hope this gives you some pointers to help you with your task.
Cheers
Paul
Hi again Paul,
I used another method to concede xcmd for these users.
We followed your post about “Restricted Options on Unix” (http://platformadmin.com/blogs/paul/2011/07/sas-restricted-options-unix/) and conceded acess only for members of a certain UNIX group. Worked really fine! But I still want to study a bit more about these SAS native alternatives. Thank you!
Sometimes I think XCMD restriction is just unnecessary, because every SAS users in our company have user accounts (when connecting with any SAS application) on the host server, and everyone can access UNIX by SSH or TELNET and run commands. So, should be more important to configure group permissions in our server.
Anyways, thank you again!
Eduardo
Hi Eduardo,
I’m glad you were able to resolve it using restricted options and thanks for reporting back too. It’s always good to hear back from people about their experiences.
I understand what you mean about NOXCMD seeming necessary. For some sites it could very well be. However, others may have stricter IT security policies or regulatory requirements that mean they need those additional levels of protections. By using multiple layers/methods of protection you reduce the risk of exploitation if one of those layers fails or is forgotten. Certainly, if the operating system file system permissions are well done then it mitigates the risk of people running external commands that they shouldn’t. Some might also want to prevent execution of commands not just to protect the file system, but to prevent the execution of arbitrarily uploaded/created executables that do network access instead. By also disabling XCMD for those users that don’t really require it, it can cover situations where appropriate file system permissions might be lacking. Limiting SSH access to only users that require it might be considered another layer of protection. All of these things can be used in concert to try to make an installation more secure. The suitability of these measures would have to be assessed on a site by site basis. For some it would be overkill, for other maybe not so.
One other potential consideration is the use of service or proxy accounts. For example if a SAS Workspace Server is configured for SAS Token Authentication then all SAS processes launched for the various SAS users will run using the same operating system account. Your ability to differentiate between users at the operating system level is removed. Disabling XCMD might be a wise choice in that situation. Of course there are other options available such as using multiple application servers with multiple service/proxy accounts with access controls determining who should see which.
My main point is that various SAS sites have different requirements, some needing more secure environments that others. Personally I would rather have a more secure default configuration, opened up as required, rather than a less secure default configuration that needed to be closed down. I was very happy to see that change with SAS 9.2 over SAS 9.1.3.
Thanks again for your feedback.
Cheers
Paul
Hi there,
X is disabled in our environment.
In this situation, how can we check if a file has arrived in the UNIX path to trigger our SAS job?
You shouldn’t need to call operating system commands to check for the existence of a file. Try using the SAS fileexist function instead. Alternatively, if you are checking for the existence of files to trigger scheduled SAS jobs, and you have Platform software, you can create a job flow using the SAS Management Console Schedule Manager plug-in that has a file trigger that starts it.
Hi Paul
I’m wanting to turn on XCMD for e-guide running on a desktop (no server, object spawner etc). We don’t have a PC files licence and therefore I need to use DDE to be able to read in an excel file via code which I then convert to CSV. I’m using e-guide v6.1. It doesn’t seem to make a difference when I add -XCMD to my config file. I phoned tech support and they said the only way is to update my registry file since I have no spawner which I’m a bit hesitant to do and it is not a supported solution either. Do you have any other suggestions?
thanks
Tammy
Hi Tammy,
I tend to only work with platform (server based) installs these days, so this reply is based more on what I have read rather than what I have done :)
I’m assuming you are running SAS 9.1 or SAS 9.2 as my understanding is that XCMD should be allowed by default with SAS 9.3. See Chris Hemedinger’s blog post on the topic: XCMD and SAS 9.3: working together again. For earlier versions of SAS, Chris has another blog post on the topic: Using the X and SYSTASK commands from SAS Enterprise Guide where he explains the registry method (and provides a tool to help too).
I hope this helps you solve the problem.
Cheers
Paul
Hi Paul,
I’m having a hard time understanding why in the world this is such a security issue. If a user has access to system commands at the OS level for either Windows or Unix then what is the big deal about allowing them access from within SAS or SAS EG. It really makes no sense to me and it is frustrating as a user inside a big corporation that I can’t shell out to my local machine from EG and execute dos commands. Can you explain why on a local machine especially this would be any kind of a security risk. As a user if I can execute os commands I can do just as much damage at the os command line as I can from SAS EG. My two cents worth.
Dave
Hi Dave,
If you are using SAS EG as a client to Foundation SAS on your local machine then you might be interested in Chris Hemedinger’s blog post “XCMD and SAS 9.3: working together again”, where he explains that executing operating system commands on the same local machine was allowed by default from SAS 9.3. He also provides a link to another post “Using the X and SYSTASK commands from SAS Enterprise Guide”, that explains how to handle it with versions prior to SAS 9.3.
Regarding the question about why is it an issue, my thoughts are that, whilst it might not be an issue for some, it can be an important security feature for others. Of course, there are many different varieties of SAS sites with a myriad of security requirements. Some may have trusted internal users with less sensitive content, where those users have remote desktop or ssh access to shared servers and where they can run operating system commands on the server anyway. In that case it shouldn’t take much to persuade the SAS admin to allow xcmd. Other sites may have more complex requirements with multi-tenanted setups, a combination of trusted internal users, less trusted external users, sensitive data sources and no remote desktop or ssh access to the servers for non-administrative SAS client users. In that scenario it may be more prudent to have xcmd disabled for most and only enabled for a few. I often hear people say that operating system permissions are the only thing required to protect those servers and their resources (as opposed to SAS metadata permissions or other SAS security features). My response is that well configured operating system permissions are an essential part of a security plan, but I don’t think it is advisable to have that as the only security layer. It is common to take a multi-layered approach where additional layers can provide protection in the event that another layer is accidentally or deliberately compromised (i.e. don’t put all your eggs in one basket). From my own experiences, some practical examples of where a default noxcmd configuration has helped are:
1) Situations where SAS Stored Process Servers (by default) and SAS Workspace Servers (when configured with SAS Token Authentication) are launched with a service/proxy account (such as sassrv). When xcmd is enabled, operating system commands do not run as the requesting user but as the potentially more privileged service account. Any operating system layer permissions must consider the access requirements of the service account and take into account that all SAS users will appear to the operating system as the same user.
2) As an extension of 1, I sometimes see configurations where the sassrv account has been placed into an operating system administrators group. In this situation the ablity to execute operating system commands can be a significant security gap. In that scenario, any SAS user with the ability to author a stored process to run on a stored process server, or run code on a SAS Token Authentication configured SAS Workspace Server can then remotely run operating system commands on a server as an administrator. As you can imagine this type of accident can occur easily and go unnoticed for a long time. A default policy of noxcmd would have provided some level of protection in this scenario (at least for operating system commands but not for the SAS program itself).
I remember back with SAS 9.1.3 I often heard people say how it was not secured by default and required a knowledgeable person to go through a process of securing it (often not done). It was good to see that starting with SAS 9.2, the default baseline security settings were more of a secured-by-default arrangement. A conscious decision could then be made, after an assessment of the risks, to loosen up the security as required. Of course it is hard to provide a baseline security policy that works for everyone, but my preference would be a platform that is more secure and would need to be opened up as required, than an insecure default that required securing in most scenarios.
Those are my thoughts on the topic. I hope they help. Perhaps others can provide their input too?
Cheers
Paul
Currently investigating options to allow XCMD access to a very small number of selected users, and not to others by default.
Easy to do for batch processes, the sas.bat command already has a stub for this (an if statement), but far more opaque for Workspace server invocations of SAS.
Following the thread of the launch process for Workspace sessions, it looks achievable, but not exactly “clean”.
The Use Case is allowing developers to code up OS invocations for batch processes, particularly to allow programmatic control of LSF flows. Could of course go with allowing it in DEV, but only for batch processes PROD – perfectly viable if your control/mastery of the two environments is very solid.
Blanket enablement of XCMDs is a hard sell, but the capabilities it opens up are pretty compelling, IMHO.