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
79 lines
1.7 KiB
SAS
79 lines
1.7 KiB
SAS
/**
|
|
@file
|
|
@brief testing admin refreshcatalog service - admin gate + libref validation (security)
|
|
@details The service requires membership of the DC administrators
|
|
group and a well-formed libref (or none). An invalid libref aborts
|
|
the service, which shows up as a canceled child job (an aborted
|
|
service registers no webout). The test suite runs as a member of
|
|
the admin group, so the gate passes here.
|
|
|
|
<h4> SAS Macros </h4>
|
|
@li mp_assert.sas
|
|
@li mx_execute.sas
|
|
|
|
**/
|
|
|
|
%let _program=&appLoc/services/admin/refreshcatalog;
|
|
|
|
/**
|
|
* Test 1 - an invalid libref must abort the service
|
|
*/
|
|
data work.params1;
|
|
length name $32 value $1000;
|
|
name='libref';value='A.%sysevalf(3+4)B';output;
|
|
run;
|
|
|
|
%mx_execute(&_program,
|
|
viyacontext=&defaultcontext,
|
|
inputparams=work.params1,
|
|
outref=web1,
|
|
viyaresult=WEBOUT_TXT
|
|
)
|
|
|
|
%let abort1=0;
|
|
data _null_;
|
|
set work.results;
|
|
if state='canceled' then call symputx('abort1',1);
|
|
run;
|
|
|
|
%mp_assert(
|
|
iftrue=(&abort1=1),
|
|
desc=Macro content in libref aborts the service,
|
|
outds=work.test_results
|
|
)
|
|
|
|
/**
|
|
* Test 2 - a valid libref still refreshes the catalog (admin user)
|
|
*/
|
|
data work.params2;
|
|
length name $32 value $1000;
|
|
name='libref';value='DCTEST';output;
|
|
run;
|
|
|
|
%mx_execute(&_program,
|
|
viyacontext=&defaultcontext,
|
|
inputparams=work.params2,
|
|
outlib=web2
|
|
)
|
|
|
|
%let msgcheck=0;
|
|
data _null_;
|
|
set web2.sasparams;
|
|
putlog (_all_)(=);
|
|
if index(msg,'Catalog Refresh Complete') then call symputx('msgcheck',1);
|
|
run;
|
|
|
|
%mp_assert(
|
|
iftrue=(&msgcheck=1),
|
|
desc=Valid libref refresh completes for admin user,
|
|
outds=work.test_results
|
|
)
|
|
|
|
/**
|
|
* dump results to the log for offline inspection
|
|
*/
|
|
data _null_;
|
|
set work.test_results;
|
|
putlog 'SECREVRESULT: ' test_result ' - ' test_description;
|
|
run;
|