diff --git a/architecture.yml b/architecture.yml index 91f9a01..285566e 100644 --- a/architecture.yml +++ b/architecture.yml @@ -101,12 +101,6 @@ module: Note: apr_time_now() returns microseconds with microsecond precision. The nanosecond representation is for API compatibility only. example: 1708948770000000000 - - name: req_id - type: string - description: > - Unique request identifier generated by Apache 2.4 (r->log_id). - Useful for cross-referencing this log with standard access and error logs. - example: "Yj2x-abcd-1234" - name: scheme type: string description: Connection scheme evaluated via ap_http_scheme(r). @@ -136,12 +130,19 @@ module: type: string description: Cleaned and normalized path (r->parsed_uri.path). example: "/api/users" - - name: args + - name: query type: string description: > - Query string parameters from the URL (r->args). - Allows detection of payloads like SQLi or XSS passed in GET requests. + Query string component from the parsed URI (r->parsed_uri.query). + Does not include the leading '?'. Allows detection of payloads like + SQLi or XSS passed in GET requests. example: "id=1%20UNION%20SELECT" + - name: fragment + type: string + description: > + Fragment component from the parsed URI (r->parsed_uri.fragment). + Does not include the leading '#'. + example: "section1" - name: host type: string example: "example.com" @@ -173,7 +174,7 @@ module: header_X-Request-Id: "abcd-1234" header_User-Agent: "curl/7.70.0" example_full: | - {"time":"2026-02-26T11:59:30Z","timestamp":1708948770000000000,"req_id":"Yj2x-abcd-1234","scheme":"https","src_ip":"192.0.2.10","src_port":45678,"dst_ip":"198.51.100.5","dst_port":443,"method":"GET","unparsed_uri":"//api/users?id=1","path":"/api/users","args":"id=1","host":"example.com","http_version":"HTTP/1.1","keepalives":0,"content_length":0,"header_X-Request-Id":"abcd-1234","header_User-Agent":"curl/7.70.0"} + {"time":"2026-02-26T11:59:30Z","timestamp":1708948770000000000,"scheme":"https","src_ip":"192.0.2.10","src_port":45678,"dst_ip":"198.51.100.5","dst_port":443,"method":"GET","unparsed_uri":"//api/users?id=1#section","path":"/api/users","query":"id=1","fragment":"section","host":"example.com","http_version":"HTTP/1.1","keepalives":0,"content_length":0,"header_X-Request-Id":"abcd-1234","header_User-Agent":"curl/7.70.0"} configuration: scope: global diff --git a/mod_reqin_log.spec b/mod_reqin_log.spec index f541e54..8c95533 100644 --- a/mod_reqin_log.spec +++ b/mod_reqin_log.spec @@ -1,4 +1,4 @@ -%global spec_version 1.0.8 +%global spec_version 1.0.9 Name: mod_reqin_log Version: %{spec_version} @@ -37,13 +37,14 @@ install -m 644 %{_pkgroot}/%{_sysconfdir}/httpd/conf.d/mod_reqin_log.conf %{buil %doc %{_docdir}/%{name} %changelog +* Mon Mar 02 2026 Developer - 1.0.9 +- CHANGE: Remove req_id field from JSON output +- FEATURE: Add query and fragment fields (URI components) + * Mon Mar 02 2026 Developer - 1.0.8 - FEATURE: Add req_id, scheme, unparsed_uri, args, keepalives, content_length fields to JSON output - FIX: Change socket type from SOCK_STREAM to SOCK_DGRAM per architecture.yml -* Sun Mar 01 2026 Developer - 1.0.7 -- FEATURE: Add JsonSockLogLevel directive (DEBUG, INFO, WARNING, ERROR, EMERG) - * Sun Mar 01 2026 Developer - 1.0.6 - BUILD: Fix RPM package paths in Dockerfile.package (el8, el9, el10 directories) - BUILD: Fix Makefile RPM extraction with separate volume mounts diff --git a/src/mod_reqin_log.c b/src/mod_reqin_log.c index 7906aa2..e57dc29 100644 --- a/src/mod_reqin_log.c +++ b/src/mod_reqin_log.c @@ -670,8 +670,8 @@ static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child const char *http_version; const char *scheme; const char *unparsed_uri; - const char *args; - const char *req_id; + const char *query; + const char *fragment; const char *content_length_str; apr_int64_t content_length; @@ -726,15 +726,19 @@ static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child unparsed_uri = apr_pstrmemdup(pool, unparsed_uri, 2048); } - /* args (query string) */ - args = r->args ? r->args : ""; - /* Sanitize args to prevent oversized values */ - if (strlen(args) > 2048) { - args = apr_pstrmemdup(pool, args, 2048); + /* query (query string from parsed URI, e.g., ?foo=bar) */ + query = r->parsed_uri.query ? r->parsed_uri.query : ""; + /* Sanitize query to prevent oversized values */ + if (strlen(query) > 2048) { + query = apr_pstrmemdup(pool, query, 2048); } - /* req_id (unique request identifier from Apache) */ - req_id = r->log_id ? r->log_id : ""; + /* fragment (fragment from parsed URI, e.g., #section) */ + fragment = r->parsed_uri.fragment ? r->parsed_uri.fragment : ""; + /* Sanitize fragment to prevent oversized values */ + if (strlen(fragment) > 2048) { + fragment = apr_pstrmemdup(pool, fragment, 2048); + } /* content_length (from Content-Length header) */ content_length_str = apr_table_get(r->headers_in, "Content-Length"); @@ -770,11 +774,6 @@ static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child dynbuf_append(&buf, ",", 1); } - /* req_id (unique request identifier) */ - dynbuf_append(&buf, "\"req_id\":\"", 9); - append_json_string(&buf, req_id); - dynbuf_append(&buf, "\",", 2); - /* scheme (http or https) */ dynbuf_append(&buf, "\"scheme\":\"", 10); append_json_string(&buf, scheme); @@ -825,13 +824,18 @@ static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child append_json_string(&buf, unparsed_uri); dynbuf_append(&buf, "\",", 2); - /* args (query string) */ - dynbuf_append(&buf, "\"args\":\"", 8); - append_json_string(&buf, args); + /* query (query string without leading ?, e.g., foo=bar) */ + dynbuf_append(&buf, "\"query\":\"", 8); + append_json_string(&buf, query); dynbuf_append(&buf, "\",", 2); + /* fragment (fragment without leading #, e.g., section) */ + dynbuf_append(&buf, "\"fragment\":\"", 11); + append_json_string(&buf, fragment); + dynbuf_append(&buf, "\"", 1); + /* host */ - dynbuf_append(&buf, "\"host\":\"", 8); + dynbuf_append(&buf, ",\"host\":\"", 9); append_json_string(&buf, host); dynbuf_append(&buf, "\",", 2);