You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-commits@axis.apache.org by ro...@apache.org on 2026/01/30 23:21:21 UTC

(axis-axis2-c-core) 06/07: AXIS2C-1708 Modern security hardening: Address Gemini code review findings - security hardening

This is an automated email from the ASF dual-hosted git repository.

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-c-core.git

commit db01aeee4ca4fcbbed19897c7b55ca7ab01b7c1a
Author: Robert Lazarski <ro...@gmail.com>
AuthorDate: Fri Jan 30 12:36:24 2026 -1000

    AXIS2C-1708 Modern security hardening: Address Gemini code review findings - security hardening
    
    Fixes identified during automated code review:
    
    1. SSL/TLS Hardening (ssl_utils.c):
       - Disable TLS 1.0/1.1 (RFC 8996 deprecation)
       - Configure strong cipher suites (AEAD with forward secrecy)
       - CVEs addressed: BEAST, Lucky13, various TLS 1.0/1.1 weaknesses
    
    2. JSON Reader Security (axis2_json_reader.c):
       - Add payload size tracking to HTTP/2 streaming mode
       - Enforce AXIS2_JSON_MAX_PAYLOAD_SIZE in streaming reads
       - Prevents DoS via large JSON in HTTP/2 multiplexed streams
    
    3. Integer Safety (http_client.c):
       - Add INT_MAX check when converting size_t to int return value
       - Prevents truncation in axis2_prepend_stream_read()
    
    4. Documentation (SECURITY.md):
       - Document TLS 1.2+ requirement and cipher configuration
       - Add Phase 3 attack surface reduction summary
       - Document Gemini code review findings and fixes
    
    Co-Authored-By: Claude Opus 4.5 <no...@anthropic.com>
---
 docs/SECURITY.md                                 | 73 ++++++++++++++++++++++--
 src/core/transport/http/sender/http_client.c     |  6 +-
 src/core/transport/http/sender/ssl/ssl_utils.c   | 26 +++++++--
 src/core/transport/http/util/axis2_json_reader.c | 31 ++++++++--
 4 files changed, 119 insertions(+), 17 deletions(-)

diff --git a/docs/SECURITY.md b/docs/SECURITY.md
index 8967c75ff..e5dca2345 100644
--- a/docs/SECURITY.md
+++ b/docs/SECURITY.md
@@ -77,12 +77,33 @@ in both supported parsers.
 
 ### Protocol Configuration
 
-Axis2/C SSL transport is configured to:
+Axis2/C SSL transport is configured with modern security defaults:
 
-1. **Use TLS 1.2+ by default** (OpenSSL 1.1.0+)
-2. **Disable SSLv2 and SSLv3** to prevent POODLE and DROWN attacks
-3. **Disable compression** to prevent CRIME attacks
-4. **Validate hostnames** against certificate CN/SAN fields
+1. **TLS 1.2+ required** - TLS 1.0 and TLS 1.1 are disabled (RFC 8996 deprecation)
+2. **SSLv2 and SSLv3 disabled** - Prevents POODLE (CVE-2014-3566) and DROWN (CVE-2016-0800)
+3. **Compression disabled** - Prevents CRIME attack (CVE-2012-4929)
+4. **Strong cipher suites** - AEAD ciphers only (GCM, ChaCha20) with forward secrecy
+5. **Hostname validation** - Certificate CN/SAN fields verified against target host
+
+### Cipher Suite Configuration
+
+The following cipher suites are preferred (in order):
+- `ECDHE+AESGCM` - ECDHE key exchange with AES-GCM
+- `DHE+AESGCM` - DHE key exchange with AES-GCM
+- `ECDHE+CHACHA20` - ECDHE with ChaCha20-Poly1305
+- `DHE+CHACHA20` - DHE with ChaCha20-Poly1305
+
+Excluded cipher suites: NULL, EXPORT, DES, 3DES, RC4, MD5, PSK, SRP, DSS, SEED, IDEA
+
+### Disabled Protocols and CVEs Addressed
+
+| Protocol | Status | CVEs Addressed |
+|----------|--------|----------------|
+| SSLv2 | Disabled | DROWN (CVE-2016-0800), many others |
+| SSLv3 | Disabled | POODLE (CVE-2014-3566) |
+| TLS 1.0 | Disabled | BEAST (CVE-2011-3389), Lucky13 (CVE-2013-0169) |
+| TLS 1.1 | Disabled | Various CBC weaknesses, RFC 8996 deprecation |
+| TLS 1.2+ | Enabled | Modern, secure |
 
 ### Certificate Validation
 
@@ -772,3 +793,45 @@ with ASAN enabled. All tests passed with no memory errors detected:
 | JSON Parser | Max payload size | 10 MB (configurable) |
 
 All tests completed with **zero ASAN errors** detected.
+
+## Attack Surface Reduction (Phase 3)
+
+The following deprecated features have been removed to reduce attack surface:
+
+| Feature | Reason for Removal |
+|---------|-------------------|
+| NTLM Authentication | Security vulnerabilities (pass-the-hash, relay attacks), Microsoft deprecating |
+| TCP Transport | Obsolete - HTTP/2 provides multiplexing with full HTTP semantics |
+| CGI Transport | Obsolete deployment model, security concerns with CGI execution |
+| libcurl HTTP Backend | Redundant with native HTTP client, MTOM broken (AXIS2C-1270) |
+
+### Removed Configure Options
+- `--enable-ntlm` / `--enable-heimdal` / `--enable-libntlm`
+- `--enable-tcp`
+- `--enable-cgi`
+- `--enable-libcurl`
+
+## Automated Code Review (Gemini)
+
+Security hardening commits are reviewed using Google Gemini AI for:
+- Memory safety issues (buffer overflows, use-after-free)
+- Input validation gaps
+- SSL/TLS configuration weaknesses
+- Error handling issues
+
+### January 2026 Review Findings (All Addressed)
+
+| Severity | File | Issue | Status |
+|----------|------|-------|--------|
+| MEDIUM | `libxml2_reader_wrapper.c` | Missing error check for `xmlTextReaderDepth()` | ✅ Fixed |
+| MEDIUM | `libxml2_reader_wrapper.c` | Error messages missing source context | ✅ Fixed |
+| MEDIUM | `ssl_utils.c` | TLS 1.0/1.1 enabled | ✅ Fixed (disabled) |
+| MEDIUM | `ssl_utils.c` | No explicit cipher suite config | ✅ Fixed |
+| MEDIUM | `axis2_json_reader.c` | HTTP/2 stream missing size limit | ✅ Fixed |
+| MEDIUM | `http_client.c` | INT_MAX check for size_t to int conversion | ✅ Fixed |
+
+### Recommendations Implemented
+1. TLS 1.2+ required (TLS 1.0/1.1 completely disabled)
+2. Strong cipher suites configured (AEAD with forward secrecy)
+3. JSON payload size limits enforced in HTTP/2 streaming mode
+4. Improved error messages include source context for debugging
diff --git a/src/core/transport/http/sender/http_client.c b/src/core/transport/http/sender/http_client.c
index f5727db5e..ae5d1e2be 100644
--- a/src/core/transport/http/sender/http_client.c
+++ b/src/core/transport/http/sender/http_client.c
@@ -112,7 +112,8 @@ axis2_prepend_stream_read(
         /* If we've satisfied the request from prepend, return */
         if (total_read >= count)
         {
-            return (int)total_read;
+            /* Security: Prevent size_t to int truncation */
+            return (total_read > INT_MAX) ? INT_MAX : (int)total_read;
         }
 
         /* Otherwise, read remainder from underlying stream */
@@ -135,7 +136,8 @@ axis2_prepend_stream_read(
         }
     }
 
-    return (int)total_read;
+    /* Security: Prevent size_t to int truncation */
+    return (total_read > INT_MAX) ? INT_MAX : (int)total_read;
 }
 
 static int AXIS2_CALL
diff --git a/src/core/transport/http/sender/ssl/ssl_utils.c b/src/core/transport/http/sender/ssl/ssl_utils.c
index 3361ac0ba..10c1c6375 100644
--- a/src/core/transport/http/sender/ssl/ssl_utils.c
+++ b/src/core/transport/http/sender/ssl/ssl_utils.c
@@ -127,14 +127,30 @@ axis2_ssl_utils_initialize_ctx(
         return NULL;
     }
 
-    /* Disable insecure SSL protocols (SSLv2, SSLv3) to prevent:
-     * - POODLE attack (CVE-2014-3566)
-     * - DROWN attack (CVE-2016-0800)
-     * - Other SSLv2/v3 vulnerabilities
+    /* Disable insecure SSL/TLS protocols to prevent:
+     * - POODLE attack (CVE-2014-3566) - SSLv3
+     * - DROWN attack (CVE-2016-0800) - SSLv2
+     * - BEAST attack (CVE-2011-3389) - TLS 1.0
+     * - Lucky13 (CVE-2013-0169) - TLS 1.0/1.1 CBC ciphers
+     * - Various TLS 1.0/1.1 weaknesses (RFC 8996 deprecates them)
      * Also enable other security options:
      * - SSL_OP_NO_COMPRESSION: Prevent CRIME attack (CVE-2012-4929)
+     *
+     * TLS 1.2+ is required. Legacy TLS is not supported.
+     */
+    SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
+                        SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
+                        SSL_OP_NO_COMPRESSION);
+
+    /* Configure secure cipher suites - prefer AEAD ciphers (GCM, ChaCha20)
+     * Excludes: NULL, EXPORT, DES, 3DES, RC4, MD5, PSK, SRP, DSS, SEED, IDEA
+     * Requires: TLS 1.2+ cipher suites with forward secrecy (ECDHE/DHE)
      */
-    SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION);
+    if (!SSL_CTX_set_cipher_list(ctx, "ECDHE+AESGCM:DHE+AESGCM:ECDHE+CHACHA20:DHE+CHACHA20:!aNULL:!MD5:!DSS"))
+    {
+        AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI,
+            "[ssl client] Could not set preferred cipher list, using defaults");
+    }
 
     /* Load our keys and certificates
      * If we need client certificates it has to be done here
diff --git a/src/core/transport/http/util/axis2_json_reader.c b/src/core/transport/http/util/axis2_json_reader.c
index eef3b1e6f..5a3e850b1 100644
--- a/src/core/transport/http/util/axis2_json_reader.c
+++ b/src/core/transport/http/util/axis2_json_reader.c
@@ -456,10 +456,11 @@ axis2_json_reader_read_http2_stream(
     json_object* json_obj = NULL;
     enum json_tokener_error jerr = json_tokener_success;
     int bytes_read = 0;
+    size_t total_bytes_read = 0;  /* Security: track total payload size */
     axis2_status_t status = AXIS2_SUCCESS;
 
     AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
-        "🚀 REVOLUTIONARY: HTTP/2 streaming JSON reader - Enhanced breed apart processing");
+        "HTTP/2 streaming JSON reader - processing request");
 
     if (!reader || !stream) {
         AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
@@ -475,14 +476,25 @@ axis2_json_reader_read_http2_stream(
         return AXIS2_FAILURE;
     }
 
-    /* REVOLUTIONARY: HTTP/2 streaming processing - handles multiplexed data efficiently */
+    /* HTTP/2 streaming processing - handles multiplexed data efficiently */
     if (enable_streaming) {
         AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
-            "🔥 REVOLUTIONARY: HTTP/2 streaming mode active - Processing multiplexed JSON data");
+            "HTTP/2 streaming mode active - processing multiplexed JSON data");
 
         do {
             bytes_read = axutil_stream_read(stream, env, buffer, sizeof(buffer) - 1);
             if (bytes_read > 0) {
+                /* Security: Enforce maximum payload size to prevent DoS
+                 * (mitigation for CVE-2020-12762 integer overflow in json-c) */
+                total_bytes_read += (size_t)bytes_read;
+                if (total_bytes_read > AXIS2_JSON_MAX_PAYLOAD_SIZE) {
+                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                        "[JSON_READER] Security: HTTP/2 JSON payload exceeds maximum size (%zu > %d bytes)",
+                        total_bytes_read, AXIS2_JSON_MAX_PAYLOAD_SIZE);
+                    json_tokener_free(tokener);
+                    return AXIS2_FAILURE;
+                }
+
                 buffer[bytes_read] = '\0';
 
                 /* Parse incrementally for HTTP/2 stream efficiency */
@@ -494,7 +506,7 @@ axis2_json_reader_read_http2_stream(
                     continue;
                 } else if (jerr != json_tokener_success) {
                     AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                        "Revolutionary HTTP/2 JSON streaming parse error: %s",
+                        "HTTP/2 JSON streaming parse error: %s",
                         json_tokener_error_to_str(jerr));
                     status = AXIS2_FAILURE;
                     break;
@@ -506,13 +518,22 @@ axis2_json_reader_read_http2_stream(
         /* Standard processing enhanced for HTTP/2 */
         bytes_read = axutil_stream_read(stream, env, buffer, sizeof(buffer) - 1);
         if (bytes_read > 0) {
+            /* Security: Check payload size even for non-streaming reads */
+            if ((size_t)bytes_read > AXIS2_JSON_MAX_PAYLOAD_SIZE) {
+                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                    "[JSON_READER] Security: HTTP/2 JSON payload exceeds maximum size (%d > %d bytes)",
+                    bytes_read, AXIS2_JSON_MAX_PAYLOAD_SIZE);
+                json_tokener_free(tokener);
+                return AXIS2_FAILURE;
+            }
+
             buffer[bytes_read] = '\0';
             json_obj = json_tokener_parse_ex(tokener, buffer, bytes_read);
             jerr = json_tokener_get_error(tokener);
 
             if (jerr != json_tokener_success) {
                 AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                    "Revolutionary HTTP/2 JSON parse error: %s",
+                    "HTTP/2 JSON parse error: %s",
                     json_tokener_error_to_str(jerr));
                 status = AXIS2_FAILURE;
             }