test(security): assert aborts from the webout where there is no job state
The four security test programs proved that a bad input aborted the service by reading work.results, the job table %mv_jobflow writes in the Viya branch of %mx_execute. The SASjs Server and SAS 9 branches call %ms_testservice instead, so the table never exists, the data step fails with "File WORK.RESULTS.DATA does not exist." and the assertion reported (0=1) - a failure that says nothing about whether the service validated its input. The platform difference is now in one macro, dc_assert_abort: on Viya it reads the job state as before, elsewhere it looks for the sasjsAbort block that mp_abort leaves in the webout %mx_execute returns through outref. The call to the service stays outside the platform check, so the payloads are submitted on every platform and the assertion is real rather than a skip. Verified on SASjs Server (sas.4gl.io, target sas719, appLoc /Public/app/dc719): the seven abort assertions PASS, i.e. the services do abort on the macro, SQL injection and path traversal payloads. Negative control: the same program with a valid libds reports FAIL (0=1), so the assertion can still fail. sasjs lint: exit 0, no warnings in the five files.
This commit is contained in:
1 parent
0d58be975d
commit
36e168971c
5 files changed
+76
-63
No files matched your search
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
@file
|
||||
@brief Asserts that a service aborted, on any platform
|
||||
@details Records a PASS in the test results when the child program aborted.
|
||||
The evidence used depends on the platform:
|
||||
|
||||
@li SASVIYA - the child runs as a job, so the state is read from work.results,
|
||||
the table mv_jobflow writes for the request.
|
||||
@li SAS 9 and SASjs Server - there is no job state to read, so the abort is
|
||||
spotted from the sasjsAbort block that mp_abort leaves in the webout, which
|
||||
%mx_execute returns through outref.
|
||||
|
||||
Usage:
|
||||
|
||||
%mx_execute(&_program,
|
||||
viyacontext=&defaultcontext,
|
||||
inputfiles=&f1:iwant,
|
||||
outref=web1,
|
||||
viyaresult=WEBOUT_TXT
|
||||
)
|
||||
%dc_assert_abort(desc=Bad libds aborts the service, outref=web1)
|
||||
|
||||
@param [in] desc The description recorded in the test results
|
||||
@param [in] outref The fileref given to %mx_execute, holding the response
|
||||
@param [out] outds= (work.test_results) Results dataset
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_getplatform.sas
|
||||
@li mp_assert.sas
|
||||
|
||||
**/
|
||||
|
||||
%macro dc_assert_abort(desc, outref, outds=work.test_results);
|
||||
%local aborted;
|
||||
%let aborted=0;
|
||||
|
||||
%if %mf_getplatform()=SASVIYA %then %do;
|
||||
/* the job state is the only record of an abort on Viya */
|
||||
data _null_;
|
||||
set work.results;
|
||||
if state='canceled' then call symputx('aborted',1);
|
||||
run;
|
||||
%end;
|
||||
%else %do;
|
||||
/* no job state here - an aborted service returns the sasjsAbort block */
|
||||
data _null_;
|
||||
infile &outref;
|
||||
input;
|
||||
if index(_infile_,'sasjsAbort')>0 then call symputx('aborted',1);
|
||||
run;
|
||||
%end;
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(&aborted=1),
|
||||
desc=&desc,
|
||||
outds=&outds
|
||||
)
|
||||
%mend dc_assert_abort;
|
||||
@@ -12,6 +12,7 @@
|
||||
assertion cannot pass against a service that does not validate.
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li dc_assert_abort.sas
|
||||
@li mp_assert.sas
|
||||
@li mx_execute.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
@@ -37,16 +38,9 @@ run;
|
||||
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),
|
||||
%dc_assert_abort(
|
||||
desc=Macro content in libds aborts the service,
|
||||
outds=work.test_results
|
||||
outref=web1
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
validate.
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li dc_assert_abort.sas
|
||||
@li mp_assert.sas
|
||||
@li mx_execute.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
@@ -38,16 +39,9 @@ run;
|
||||
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),
|
||||
%dc_assert_abort(
|
||||
desc=Macro content in libds aborts the service,
|
||||
outds=work.test_results
|
||||
outref=web1
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -67,16 +61,9 @@ run;
|
||||
viyaresult=WEBOUT_TXT
|
||||
)
|
||||
|
||||
%let abort2=0;
|
||||
data _null_;
|
||||
set work.results;
|
||||
if state='canceled' then call symputx('abort2',1);
|
||||
run;
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(&abort2=1),
|
||||
%dc_assert_abort(
|
||||
desc=Macro content in col aborts the service,
|
||||
outds=work.test_results
|
||||
outref=web2
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
validate.
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li dc_assert_abort.sas
|
||||
@li mp_assert.sas
|
||||
@li mx_execute.sas
|
||||
|
||||
@@ -38,16 +39,9 @@ run;
|
||||
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),
|
||||
%dc_assert_abort(
|
||||
desc=Macro content in table aborts the service,
|
||||
outds=work.test_results
|
||||
outref=web1
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -67,16 +61,9 @@ run;
|
||||
viyaresult=WEBOUT_TXT
|
||||
)
|
||||
|
||||
%let abort2=0;
|
||||
data _null_;
|
||||
set work.results;
|
||||
if state='canceled' then call symputx('abort2',1);
|
||||
run;
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(&abort2=1),
|
||||
%dc_assert_abort(
|
||||
desc=SQL injection in filter aborts the service,
|
||||
outds=work.test_results
|
||||
outref=web2
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -98,16 +85,9 @@ run;
|
||||
viyaresult=WEBOUT_TXT
|
||||
)
|
||||
|
||||
%let abort3=0;
|
||||
data _null_;
|
||||
set work.results;
|
||||
if state='canceled' then call symputx('abort3',1);
|
||||
run;
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(&abort3=1),
|
||||
%dc_assert_abort(
|
||||
desc=Path traversal in table aborts the service,
|
||||
outds=work.test_results
|
||||
outref=web3
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
assertion cannot pass against a service that does not validate.
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li dc_assert_abort.sas
|
||||
@li mp_assert.sas
|
||||
@li mx_execute.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
@@ -37,16 +38,9 @@ run;
|
||||
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),
|
||||
%dc_assert_abort(
|
||||
desc=Macro content in filter_table aborts the service,
|
||||
outds=work.test_results
|
||||
outref=web1
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user