Files
dc/sas/sasjs/services/public/getrawdata.test.1.sas
T
dc 4bcee706ff
Build / Build-and-ng-test (pull_request) Successful in 5m37s
Lighthouse Checks / lighthouse (pull_request) Successful in 20m58s
Build / Build-and-test-development (pull_request) Failing after 34m57s
fix(getcolvals): report an invalid value, not missing inputs
libds and col2 are only populated once validation passes, so the
"Missing inputs from iwant" abort - which tested those macro variables - fired for
any invalid payload and hid the specific reason.  It now tests whether the
request carried rows at all, leaving Invalid libds / Invalid col to report the
value.  The service still refuses the same requests; only the message changes.

The matching tests carried two faults of their own: getcolvals.test.4 sent its
libds through single quotes so the libref itself was invalid, and getdiffs /
getrawdata expected "Invalid table" for cases their own field names.
2026-10-27 16:23:31 +00:00

142 lines
3.3 KiB
SAS

/**
@file
@brief testing getrawdata service - input validation (security)
@details table must be a well-formed LIBREF.DATASET (the trailing
format-catalog suffix is permitted), filter must be an integer and
type one of the supported download types. An invalid value aborts
the service before any request content can execute. The abort is
asserted from the child job state: the payloads either resolve to a
real table when executed as macro code, or write a file outside the
WORK directory (verified by live probe) - so on the vulnerable
service the job completes, and only the validating service cancels
it. The assertion cannot pass against a service that does not
validate.
<h4> SAS Macros </h4>
@li mpe_assert_abort.sas
@li mp_assert.sas
@li mpe_execute.sas
**/
%let _program=&appLoc/services/public/getrawdata;
/**
* Test 1 - macro content in table must abort the service
* (the payload resolves to a real table when executed as macro code)
*/
data work.params1;
length name $32 value $1000;
name='type';value='CSV';output;
name='table';value='%sysfunc(coalescec(&mpelib..MPE_X_TEST,))';output;
name='filter';value='0';output;
run;
%mpe_execute(&_program,
viyacontext=&defaultcontext,
inputparams=work.params1,
outref=web1,
outstatus=work.ab1,
failfast=0,
viyaresult=WEBOUT_TXT
)
%mpe_assert_abort(
desc=Macro content in table aborts the service,
outref=web1,
msg=Invalid table
)
/**
* Test 2 - sql injection in filter must abort the service
*/
data work.params2;
length name $32 value $1000;
name='type';value='CSV';output;
name='table';value="&dclib..MPE_X_TEST";output;
name='filter';value='0 or 1=1';output;
run;
%mpe_execute(&_program,
viyacontext=&defaultcontext,
inputparams=work.params2,
outref=web2,
outstatus=work.ab2,
failfast=0,
viyaresult=WEBOUT_TXT
)
%mpe_assert_abort(
desc=SQL injection in filter aborts the service,
outref=web2,
msg=Invalid filter
)
/**
* Test 3 - path traversal in table must abort the service
* (verified by live probe: on a vulnerable service this writes
* ../SECPROBE.csv outside the WORK directory and completes)
*/
data work.params3;
length name $32 value $1000;
name='type';value='CSV';output;
name='table';value='../secprobe';output;
name='filter';value='0';output;
run;
%mpe_execute(&_program,
viyacontext=&defaultcontext,
inputparams=work.params3,
outref=web3,
outstatus=work.ab3,
failfast=0,
viyaresult=WEBOUT_TXT
)
%mpe_assert_abort(
desc=Path traversal in table aborts the service,
outref=web3,
msg=Invalid table
)
/**
* Test 4 - the valid request must still work (positive control)
*/
data work.params4;
length name $32 value $1000;
name='type';value='CSV';output;
name='table';value="&dclib..MPE_X_TEST";output;
name='filter';value='0';output;
run;
%mpe_execute(&_program,
viyacontext=&defaultcontext,
inputparams=work.params4,
outref=web4,
viyaresult=WEBOUT_TXT
)
%let ok4=0;
data _null_;
infile web4;
input;
if _infile_=:'PRIMARY_KEY_FIELD' then do;
call symputx('ok4',1);
stop;
end;
run;
%mp_assert(
iftrue=(&ok4=1),
desc=Valid table request still returns data,
outds=work.test_results
)
/**
* dump results to the log for offline inspection
*/
data _null_;
set work.test_results;
putlog 'TEST_RESULT_LINE: ' test_result ' - ' test_description;
run;