Joel_66443
Jun 16, 2009Nimbostratus
Encrypting POST variables before they hit the server
Hi All,
I'm attempting to encrypt two form variables as they are in transit from the user's browser to the web server. That is, I want to encrypt the two variables before they hit the web server.
The variables in this case consist of a credit card number (CCNumber) and ccv number (CCV) number.
In order to accomplish this, I am attempting to split the HTTP: Payload into it's key/value pairs, then encrypt the two form values, then finally compile a new HTTP: Payload to replace the old before sending it onto the webserver.
I'm finding that it's not quite as simple to implement as first thought. whilst the iRule does indeed encrypt the two variables and rebuild a new HTTP: Payload, it fails to replace the old with the new, balking with the error:
- Out of bounds (line 1) invoked from within "HTTP::payload replace 0 [string length $::newPayload] $::newPayload"
Attempts to place the 'HTTP::payload replace' into HTTP_RESPONSE_DATA fails to modify the POST data in any way. It's still unencrypted to the server.
I'd sincerely appreciate if a more experienced engineer could have a glance over the code and pick out any key errors.
- Jason
when RULE_INIT {
set ::aes_key 7ef82a9b038c19d4a6b2c014d812
}
when HTTP_REQUEST {
Prevent the server from sending a compressed response
remove the compression offerings from the client
HTTP::header remove "Accept-Encoding"
Don't allow response data to be chunked
if { [HTTP::version] eq "1.1" } {
Force downgrade to HTTP 1.0, but still allow keep-alive connections.
Since HTTP 1.1 is keep-alive by default, and 1.0 isn't,
we need make sure the headers reflect the keep-alive status.
Check if this is a keep alive connection
if { [HTTP::header is_keepalive] } {
Replace the connection header value with "Keep-Alive"
HTTP::header replace "Connection" "Keep-Alive"
}
Set server side request version to 1.0
This forces the server to respond without chunking
HTTP::version "1.0"
log local0. "Original Payload: [HTTP::payload]"
log local0. "Original Payload Length: [string length [HTTP::payload]]"
set parametersList [split [HTTP::payload] "&"]
for {set i 0} {$i < [llength $parametersList]} {incr i} {
set parameter [split [lindex $parametersList $i] "="]
set ::postVars([lindex $parameter 0]) [lindex $parameter 1];
}
encrypt the credit card number and ccv
set card_number_encrypted [URI::encode [b64encode [AES::encrypt $::aes_key $::postVars(CCNumber)]]]
set ccv_number_encrypted [URI::encode [b64encode [AES::encrypt $::aes_key $::postVars(CCV)]]]
create a new http payload
set ::newPayload "CCNumber=$card_number_encrypted&CCV=$ccv_number_encrypted"
log local0. "New Payload: $::newPayload"
log local0. "New Payload Length: [string length $::newPayload]"
replace the old payload with the new
HTTP::payload replace 0 [string length $::newPayload] $::newPayload
}
}
when HTTP_RESPONSE {
}
when HTTP_RESPONSE_DATA {
HTTP::payload replace 0 [string length $::newPayload] $::newPayload
}
The following logs demonstrate that the script is successfully compiling a new payload, but is failing to apply it to the stream.
Original Payload: CCNumber=1111+1111+1111+1111&CCV=123
Original Payload Length: 53
New Payload: CCNumber=edCEWkxt0jh28CkaNezCLift0eHxpJRGiNLMXoBk8RU5AnBMo9xzaubcwspj%2bLLqZXJfDsaUl9ij&CCV=OaszTOZA%2by5P2UAaNezCLift0eHxpHggtCfx8%2fSs4q9uNtTGxEthMTA%3d
New Payload Length: 171