Security fixes for the input-validation gaps in the public download and metadata services, plus missing in-code admin gates: - mpe_accesscheck: validate base_table (LIBDS) and access_level before they reach the authorisation query, and escape embedded quotes in the SQL literals (defence in depth for direct macro callers) - getrawdata: validate table (LIBDS / format-catalog form), filter (integer) and type before they are used; read all inputs with symget in a data step so macro content cannot execute at a resolution boundary - getdiffs: validate libds, table and stp_diffs_csv before the access check and the staging-file stream path - getcols, getcolvals, validatefilter: read the IWANT inputs with symget in a data step and validate (LIBDS / SAS name) before use - admin dirlist, refreshlibs, refreshcatalog, exportconfig: require membership of the DC administrators group (the admin folder prefix is not an access control) - admin dirlist: read parent with symget and reject macro characters Tests (all proven RED on the vulnerable services first, then GREEN on the fix): getrawdata.test.1, getdiffs.test, getcols.test, getcolvals.test.4, validatefilter.test.1, dirlist.test, refreshcatalog.test.1
75 lines
1.7 KiB
SAS
75 lines
1.7 KiB
SAS
/**
|
|
@file refreshcatalog.sas
|
|
@brief Refreshes the library data catalog
|
|
@details A library may be passed in a LIBREF url param.
|
|
Requires membership of the DC administrators group.
|
|
|
|
<h4> SAS Macros </h4>
|
|
@li mpeinit.sas
|
|
@li dc_refreshcatalog.sas
|
|
@li mpe_getgroups.sas
|
|
@li mp_abort.sas
|
|
@li mp_validatecol.sas
|
|
@li mpeterm.sas
|
|
|
|
@version 9.3
|
|
@author 4GL Apps Ltd
|
|
@copyright 4GL Apps Ltd. This code may only be re-distributed or re-sold
|
|
without the express permission of 4GL Apps Ltd.
|
|
|
|
**/
|
|
%global libref;
|
|
%mpeinit()
|
|
|
|
/**
|
|
* libref is a request input used in dc_assignlib and catalog queries -
|
|
* it must be a well-formed libref before use. Read with symget (never
|
|
* re-resolved) and validated in a data step.
|
|
*/
|
|
%let is_lib=0;
|
|
data _null_;
|
|
length _libref $8;
|
|
_libref=coalescec(symget('libref'),'');
|
|
/* an absent libref is a valid, full catalog refresh */
|
|
if missing(_libref) then do;
|
|
call symputx('is_lib',1,'l');
|
|
call symputx('libref','','g');
|
|
stop;
|
|
end;
|
|
%mp_validatecol(_libref,ISLIB,is_lib)
|
|
if is_lib=0 then putlog 'ERR' 'OR: Invalid libref:' _libref;
|
|
call symputx('is_lib',is_lib,'l');
|
|
if is_lib=1 then call symputx('libref',upcase(_libref),'g');
|
|
run;
|
|
|
|
%mp_abort(iftrue= (&is_lib ne 1)
|
|
,mac=&_program..sas
|
|
,msg=%str(Invalid libref)
|
|
)
|
|
|
|
/* check user is in admin group */
|
|
%let cnt=0;
|
|
%mpe_getgroups(user=%mf_getuser(),outds=work.usergroups)
|
|
proc sql noprint;
|
|
select count(*) into:cnt
|
|
from usergroups
|
|
where groupname="&mpeadmins";
|
|
%mp_abort(iftrue= (&cnt=0)
|
|
,mac=&_program
|
|
,msg=%str(This service is only available to &mpeadmins members)
|
|
)
|
|
|
|
%dc_refreshcatalog(&libref)
|
|
|
|
|
|
data sasparams;
|
|
length msg $64;
|
|
msg='Catalog Refresh Complete';
|
|
run;
|
|
|
|
%webout(OPEN)
|
|
%webout(OBJ,sasparams)
|
|
%webout(CLOSE)
|
|
|
|
%mpeterm()
|