@@ -201,6 +201,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
201201 private static final String SANITIZATION_REGEX = "[\n \r ]" ;
202202
203203 private static boolean encodeApiResponse = false ;
204+ private boolean isEnforcePostRequestsAndTimestamps = false ;
204205
205206 /**
206207 * Non-printable ASCII characters - numbers 0 to 31 and 127 decimal
@@ -284,6 +285,13 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
284285 , "Session cookie is marked as secure if this is enabled. Secure cookies only work when HTTPS is used."
285286 , false
286287 , ConfigKey .Scope .Global );
288+ static final ConfigKey <Boolean > EnforcePostRequestsAndTimestamps = new ConfigKey <>(ConfigKey .CATEGORY_ADVANCED
289+ , Boolean .class
290+ , "enable.enforce.post.requests.and.timestamps"
291+ , "false"
292+ , "enables/disables whether the ApiServer only accepts state-changing POST requests and requests with timestamps."
293+ , false
294+ , ConfigKey .Scope .Global );
287295 private static final ConfigKey <String > JSONDefaultContentType = new ConfigKey <> (ConfigKey .CATEGORY_ADVANCED
288296 , String .class
289297 , "json.content.type"
@@ -441,6 +449,7 @@ protected void setupIntegrationPortListener(Integer apiPort) {
441449 public boolean start () {
442450 Security .addProvider (new BouncyCastleProvider ());
443451 Integer apiPort = IntegrationAPIPort .value (); // api port, null by default
452+ isEnforcePostRequestsAndTimestamps = EnforcePostRequestsAndTimestamps .value ();
444453
445454 final Long snapshotLimit = ConcurrentSnapshotsThresholdPerHost .value ();
446455 if (snapshotLimit == null || snapshotLimit <= 0 ) {
@@ -720,6 +729,11 @@ public String handleRequest(final Map params, final String responseType, final S
720729 return response ;
721730 }
722731
732+ @ Override
733+ public boolean isEnforcePostRequestsAndTimestamps () {
734+ return isEnforcePostRequestsAndTimestamps ;
735+ }
736+
723737 private String getBaseAsyncResponse (final long jobId , final BaseAsyncCmd cmd ) {
724738 final AsyncJobResponse response = new AsyncJobResponse ();
725739
@@ -967,7 +981,6 @@ public boolean verifyRequest(final Map<String, Object[]> requestParameters, fina
967981
968982 // put the name in a list that we'll sort later
969983 final List <String > parameterNames = new ArrayList <>(requestParameters .keySet ());
970-
971984 Collections .sort (parameterNames );
972985
973986 String signatureVersion = null ;
@@ -1019,12 +1032,22 @@ public boolean verifyRequest(final Map<String, Object[]> requestParameters, fina
10191032 }
10201033
10211034 final Date now = new Date (System .currentTimeMillis ());
1035+ final Date thresholdTime = new Date (now .getTime () + 15 * 60 * 1000 );
10221036 if (expiresTS .before (now )) {
10231037 signature = signature .replaceAll (SANITIZATION_REGEX , "_" );
10241038 apiKey = apiKey .replaceAll (SANITIZATION_REGEX , "_" );
10251039 logger .debug ("Request expired -- ignoring ...sig [{}], apiKey [{}]." , signature , apiKey );
10261040 return false ;
1041+ } else if (isEnforcePostRequestsAndTimestamps && expiresTS .after (thresholdTime )) {
1042+ signature = signature .replaceAll (SANITIZATION_REGEX , "_" );
1043+ apiKey = apiKey .replaceAll (SANITIZATION_REGEX , "_" );
1044+ logger .debug (String .format ("Expiration parameter is set for too long -- ignoring ...sig [%s], apiKey [%s]." , signature , apiKey ));
1045+ return false ;
10271046 }
1047+ } else if (isEnforcePostRequestsAndTimestamps ) {
1048+ // Force expiration parameter
1049+ logger .debug ("Signature Version must be 3, and should be along with the Expires parameter -- ignoring request." );
1050+ return false ;
10281051 }
10291052
10301053 final TransactionLegacy txn = TransactionLegacy .open (TransactionLegacy .CLOUD_DB );
@@ -1648,6 +1671,7 @@ public String getConfigComponentName() {
16481671 @ Override
16491672 public ConfigKey <?>[] getConfigKeys () {
16501673 return new ConfigKey <?>[] {
1674+ EnforcePostRequestsAndTimestamps ,
16511675 IntegrationAPIPort ,
16521676 ConcurrentSnapshotsThresholdPerHost ,
16531677 EncodeApiResponse ,
0 commit comments