You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
Added configurable masking for the request, the response and the request arguments, replacing the hardcoded Authorization header and username/password handling. Rules are declared as $request_fields_to_mask, $response_fields_to_mask and $argument_fields_to_mask, or passed as the $masked_fields constructor argument, where they merge into what the class already declares.
Added an allow list to the masking configuration. The reserved keep key masks every key in a container that it does not name, so a field the provider adds later is masked by default.
Added Krokedil\WpApi\FieldMasker, so a plugin that logs from outside a Request subclass can apply the same configured rules.
Added mask_request_url() for APIs that address a resource by a token in the path. It returns the URL unchanged by default, and an override that throws costs the log line and not the API call.
Added PHPUnit, PHPCS and PHPStan with composer test, composer phpcs and composer phpstan, and GitHub Actions workflows for pull requests.
Added XML support for response bodies. get_response_body() parses the body by its content type: JSON is decoded, XML is parsed into an array, HTML is returned as a string. A body with no or an unknown content type is decoded as JSON when it is valid JSON, so the response masking rules still reach into it.
Added log levels. Logger::log() writes with the WooCommerce logger at the log_level of the entry, error for a non 2xx response and for a body status of error, warning for a body status of warning, otherwise info.
WP_Error responses from wp_remote_request() are now logged.
Added the krokedil_wp_api_mask_log_data filter. Return false to turn the log masking off while debugging. It gets the plugin slug as its second argument. There is deliberately no setting for it.
Added Krokedil\WpApi\Masking, with mask_fields(), mask_keys() and is_enabled(), so a plugin that masks data outside a Request subclass honours the filter too.
Changed
[MISSING] now tells an empty value from a sent one on every masked field, rather than only on the Authorization header.
Masking no longer decides by length whether a header holds a token. Any value a rule names is replaced, whatever its length.
Data nested deeper than twelve levels is masked rather than walked.
request() returns the body parsed by its content type rather than always through json_decode(). A 2xx HTML body, or a body with no or an unknown content type that is not JSON, is now returned as a string where it used to be null, and a body labelled JSON or XML that cannot be parsed returns a WP_Error.
Request logs are written at the info level rather than the notice default of WC_Logger::add(), so a store with its log threshold at notice or higher no longer records successful requests.
Deprecated
sanitize_request_args() is deprecated and delegates to the configured masking, keeping its behaviour.
Security
The response body is now masked. It was logged in full, so every field the provider returned, customer details included, reached the log.
Stack trace arguments are now masked. With extended debugging on, every value passed to every caller was json encoded into the log as it was. Frame arguments are positional, so a bare token with no key name still survives unless its shape gives it away.
Added a key name pass over the finished log entry. Krokedil\WpApi\KeyMasker masks by key name wherever it appears, and by shape for an Authorization value, a JWT and a standalone base64 blob, catching what no rule describes. Consuming plugins widen the list with KeyMasker::add_keys().
Masking fails closed. A section that cannot be masked is logged as [MASKING FAILED] rather than in the clear.