Log redaction for sensitive input values, C side
authorDan Wells <dbw2@calvin.edu>
Wed, 10 Oct 2012 21:28:07 +0000 (17:28 -0400)
committerBill Erickson <berick@esilibrary.com>
Thu, 8 Nov 2012 17:48:24 +0000 (12:48 -0500)
Some service/methods deal with sensitive information (passwords,
financial, etc.).  All input values (e.g. gateway method params)
are currently logged in the activity log regardless of your log
level.  This commit will allow you to redact the params of any
method which matches a configurable set of left-anchored string
values.

This commit adds the initial config, and covers redaction of method
parameters sent through the gateway, the translator, and more general
OpenSRF C applications.

Signed-off-by: Dan Wells <dbw2@calvin.edu>
Signed-off-by: Dan Scott <dan@coffeecode.net>

examples/opensrf_core.xml.example
include/opensrf/osrf_application.h
include/opensrf/osrf_system.h
src/gateway/osrf_http_translator.c
src/gateway/osrf_json_gateway.c
src/libopensrf/osrf_application.c
src/libopensrf/osrf_system.c

index 816a20c..a4367d3 100644 (file)
@@ -159,4 +159,16 @@ vim:et:ts=2:sw=2:
 
   <!-- ======================================================================================== -->
 
+  <shared>
+    <!-- Any methods which match any of these match_string node values will
+         have their params redacted from lower-level input logging.
+         Adjust these examples as needed. -->
+    <!--
+    <log_protect>
+      <match_string>open-ils.auth_proxy.login</match_string>
+      <match_string>open-ils.some_service.some_method</match_string>
+    </log_protect>
+    -->
+  </shared>
+
 </config>
index d7560be..d05f2cc 100644 (file)
@@ -35,6 +35,7 @@
 #include <opensrf/log.h>
 #include <opensrf/osrf_app_session.h>
 #include <opensrf/osrf_hash.h>
+#include <opensrf/string_array.h>
 
 #include <opensrf/osrf_json.h>
 #include <stdio.h>
index b39645d..328d149 100644 (file)
@@ -37,6 +37,8 @@ void osrfSystemIgnoreTransportClient();
 
 int osrfSystemInitCache(void);
 
+extern osrfStringArray* log_protect_arr;
+
 #ifdef __cplusplus
 }
 #endif
index 83855e9..f6d492b 100644 (file)
@@ -8,6 +8,7 @@
 #include <opensrf/osrfConfig.h>
 #include <opensrf/osrf_json.h>
 #include <opensrf/osrf_cache.h>
+#include <opensrf/string_array.h>
 
 #define MODULE_NAME "osrf_http_translator_module"
 #define OSRF_TRANSLATOR_CONFIG_FILE "OSRFTranslatorConfig"
@@ -265,20 +266,34 @@ static char* osrfHttpTranslatorParseRequest(osrfHttpTranslator* trans) {
             case REQUEST: {
                 const jsonObject* params = msg->_params;
                 growing_buffer* act = buffer_init(128);        
+                char* method = msg->method_name;
                 buffer_fadd(act, "[%s] [%s] %s %s", trans->remoteHost, "",
-                    trans->service, msg->method_name);
+                    trans->service, method);
 
                 const jsonObject* obj = NULL;
                 int i = 0;
-                char* str; 
-                while((obj = jsonObjectGetIndex(params, i++))) {
-                    str = jsonObjectToJSON(obj);
-                    if( i == 1 )
-                        OSRF_BUFFER_ADD(act, " ");
-                    else 
-                        OSRF_BUFFER_ADD(act, ", ");
-                    OSRF_BUFFER_ADD(act, str);
-                    free(str);
+                const char* str;
+                int redactParams = 0;
+                while( (str = osrfStringArrayGetString(log_protect_arr, i++)) ) {
+                    //osrfLogInternal(OSRF_LOG_MARK, "Checking for log protection [%s]", str);
+                    if(!strncmp(method, str, strlen(str))) {
+                        redactParams = 1;
+                        break;
+                    }
+                }
+                if(redactParams) {
+                    OSRF_BUFFER_ADD(act, " **PARAMS REDACTED**");
+                } else {
+                    i = 0;
+                    while((obj = jsonObjectGetIndex(params, i++))) {
+                        str = jsonObjectToJSON(obj);
+                        if( i == 1 )
+                            OSRF_BUFFER_ADD(act, " ");
+                        else
+                            OSRF_BUFFER_ADD(act, ", ");
+                        OSRF_BUFFER_ADD(act, str);
+                        free(str);
+                    }
                 }
                 osrfLogActivity(OSRF_LOG_MARK, "%s", act->buf);
                 buffer_free(act);
index 53094e3..ecc02a2 100644 (file)
@@ -5,6 +5,7 @@
 #include <opensrf/osrf_json.h>
 #include <opensrf/osrf_json_xml.h>
 #include <opensrf/osrf_legacy_json.h>
+#include <opensrf/string_array.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <unistd.h>
@@ -289,14 +290,28 @@ static int osrf_json_gateway_method_handler (request_rec *r) {
                growing_buffer* act = buffer_init(128);
                buffer_fadd(act, "[%s] [%s] [%s] %s %s", r->connection->remote_ip,
                        authtoken, osrf_locale, service, method );
+
                const char* str; int i = 0;
-               while( (str = osrfStringArrayGetString(mparams, i++)) ) {
-                       if( i == 1 ) {
-                               OSRF_BUFFER_ADD(act, " ");
-                               OSRF_BUFFER_ADD(act, str);
-                       } else {
-                               OSRF_BUFFER_ADD(act, ", ");
-                               OSRF_BUFFER_ADD(act, str);
+               int redact_params = 0;
+               while( (str = osrfStringArrayGetString(log_protect_arr, i++)) ) {
+                       //osrfLogInternal(OSRF_LOG_MARK, "Checking for log protection [%s]", str);
+                       if(!strncmp(method, str, strlen(str))) {
+                               redact_params = 1;
+                               break;
+                       }
+               }
+               if(redact_params) {
+                       OSRF_BUFFER_ADD(act, " **PARAMS REDACTED**");
+               } else {
+                       i = 0;
+                       while( (str = osrfStringArrayGetString(mparams, i++)) ) {
+                               if( i == 1 ) {
+                                       OSRF_BUFFER_ADD(act, " ");
+                                       OSRF_BUFFER_ADD(act, str);
+                               } else {
+                                       OSRF_BUFFER_ADD(act, ", ");
+                                       OSRF_BUFFER_ADD(act, str);
+                               }
                        }
                }
 
index 57a372b..f7be6a6 100644 (file)
@@ -1035,11 +1035,30 @@ int osrfMethodVerifyContext( osrfMethodContext* ctx )
        // Log the call, with the method and parameters
        char* params_str = jsonObjectToJSON( ctx->params );
        if( params_str ) {
-        // params_str will at minimum be "[]"
-        params_str[strlen(params_str) - 1] = '\0'; // drop the trailing ']'
-               osrfLogInfo( OSRF_LOG_MARK, "CALL: %s %s %s",
-                        ctx->session->remote_service, ctx->method->name, params_str + 1);
+               // params_str will at minimum be "[]"
+               int i = 0;
+               const char* str;
+               char* method = ctx->method->name;
+               int redact_params = 0;
+               while( (str = osrfStringArrayGetString(log_protect_arr, i++)) ) {
+                       //osrfLogInternal(OSRF_LOG_MARK, "Checking for log protection [%s]", str);
+                       if(!strncmp(method, str, strlen(str))) {
+                               redact_params = 1;
+                               break;
+                       }
+               }
+
+               char* params_logged;
+               if(redact_params) {
+                       params_logged = strdup("**PARAMS REDACTED**");
+               } else {
+                       params_str[strlen(params_str) - 1] = '\0'; // drop the trailing ']'
+                       params_logged = strdup(params_str + 1);
+               }
                free( params_str );
+               osrfLogInfo( OSRF_LOG_MARK, "CALL: %s %s %s",
+                       ctx->session->remote_service, ctx->method->name, params_logged);
+               free( params_logged );
        }
        return 0;
 }
index 05244a9..f6d338c 100644 (file)
@@ -26,6 +26,7 @@
 static void report_child_status( pid_t pid, int status );
 struct child_node;
 typedef struct child_node ChildNode;
+osrfStringArray* log_protect_arr = NULL;
 
 /**
        @brief Represents a child process.
@@ -540,6 +541,11 @@ int osrfSystemBootstrapClientResc( const char* config_file,
                        osrfConfigSetDefaultConfig(cfg);
                else
                        return 0;   /* Can't load configuration?  Bail out */
+
+               // fetch list of configured log redaction marker strings
+               log_protect_arr = osrfNewStringArray(8);
+               osrfConfig* cfg_shared = osrfConfigInit(config_file, "shared");
+               osrfConfigGetValueList( cfg_shared, log_protect_arr, "/log_protect/match_string" );
        }
 
        char* log_file      = osrfConfigGetValue( NULL, "/logfile");