Defending Your SAF
We implemented a Verizon Stored Value interface in our OLS.Switch solution using jPOS’ FSDISOMsg. Using this facility, our retail clients can offer their customer phone card activation and refresh (aka. ‘top-up’) at the point of sale. Now comes some ‘prevent defense’ requirements on our part. Because Verizon is a non-standard interface, we need to take some extra protection to ensure that we don't get blown up by a crazy incoming dollar amount. We saw on Wednesday, May 28th where 10 position amounts are coming in from the POS. Our client’s Store System has a bug (re-created in the lab) causing ID numbers to come in as the amount. This situation doesn't blow up the other interfaces because ISO Field 4 is 12 positions in length. But on Verizon, we get an exception because the defined length in the outgoing request is only six (6) positions. Our q2.log shows this exception:
org.jpos.iso.ISOException: invalid len 10/6
The problem is further exacerbated because we put the item into SAF queue. The exception repeats until the item is removed. Thank god Alejandro’s very nice SAF facility bails us out by removing the crap record from the top of the queue after it expires. For the record, our 20_verizon_saf.xml participant looks like this:
<saf name='verizon-saf' logger='Q2' realm='verizon-saf' class='org.jpos.saf.SAF'>
<property name='space' value='jdbm:saf-verizon' />
<property name='mux' value='verizon-mux' />
<property name='flag-retransmissions' value='no'>
if MTI is in list, messages would be retransmitted as xxx1
</property>
<property name='initial-delay' value='60000' />
<property name='inter-message-delay' value='1000' />
<property name='wait-for-response' value='60000' />
<property name='max-retransmissions' value='1000' />
<property name='expire-after' value='1200'>
in seconds
</property>
<property name='valid-response-codes' value='*' />
<property name='retry-response-codes' value='ZZ' />
That red, bolded value is the failsafe here: the ‘expire-after’ feature trumps the fact that the record is malformed. After 20 minutes of retransmission misfires (the exception gets re-raised with every re-try), ‘expire-after’ cleans up the mess.
Now, we do the prevent defense thing as we’ve done in the past. We need to protect and defend the integrity of the SAF. In this case, we ought to flat-out reject the Verizon transaction locally if the incoming amount if the incoming amount string is > 6 positions.
So, we made this change in our CreateVerizonrequest.java program, leveraging one of OLS.Switch’s internal result codes:
- fsd.set ("purchase-price", msg.get ("amount"));
+ // If the amount length is greater than six, an
+ // exception occurs. The field length in VZN is 6;
+ // the store can do larger amounts. The problem is
+ // further exacerbated because we put the item into
+ // the SAF queue. The exception repeats until the
+ // item is removed.
+ String reqamt = msg.get ("amount");
+ assertTrue (reqamt.length() < 7, APPLERR_INVAMOUNT,
+ "Amount too big for Verizon outbound message format");
+ if (reqamt.length() < 7) {
+ fsd.set ("purchase-price", msg.get ("amount"));
+ }
+
As further prevention, Dave has suggested a change not to place an entry in the SAF if an exception is raised when processing the original. That’s something on deck.
Comments