hardening(forms): render input attributes safely#7253
Conversation
There was a problem hiding this comment.
Pull request overview
This PR hardens HTML form rendering in Cacti by introducing centralized helpers for safely rendering <input> attributes and then adopting them in a couple of high-risk spots (package import hidden fields and aggregate graph filtering) to reduce reflected-XSS exposure.
Changes:
- Add
html_attributes(),html_hidden_input(), andhtml_text_input()helpers inlib/html.phpto consistently escape attribute values. - Replace raw hidden-field serialization in
package_import.phpwith a session-backedimport_statetoken and render hidden inputs via the new helper. - Migrate the Aggregate Graphs “rfilter” textbox to
html_text_input()and add unit tests covering the new helpers.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
lib/html.php |
Adds attribute/input rendering helpers that escape attribute values (and sanitize attribute names). |
package_import.php |
Switches import execution state from request-hidden serialized blobs to a session token, and uses helper-rendered hidden inputs. |
aggregate_graphs.php |
Uses the new helper to safely render the request-derived rfilter textbox value. |
tests/Unit/HtmlEscapeTest.php |
Adds unit tests for the new helpers’ escaping behavior. |
c45d2bb to
1f44c43
Compare
TheWitness
left a comment
There was a problem hiding this comment.
CI is failing on this one.
|
@somethingwithproof, it looks like your commits are not running the pre-commit hooks. Failing from a PSR issue now. |
|
Addressed in 8f519b2. The failing CI check was PHP-CS-Fixer only: its required alignment for the package-import state token is now applied. No runtime behavior changed. Validation: PHP lint and diff check passed; the PR CI rerun is the remaining confirmation. |
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
9ec556b to
3319c47
Compare
|
The previously reported formatting check is now passing on the latest completed CI run; the remaining review gate is ready for re-check. |
|
@copilot review |
|
CI failure fixed. Green now. |
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
|
Fixed, that was the php-cs-fixer PSR issue the pre-commit hook catches on the test file. |
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
package_import.php:140
- When
import_stateis present, the code overrides several import-affecting inputs from the stored state, butdrp_actionis still read from the request later (e.g.if (grv('drp_action') == 1)). That means a validimport_statetoken can still be replayed with a mismatcheddrp_action, undermining the “bind every import-affecting input” goal and potentially altering behavior.
At minimum, force drp_action to the expected action when consuming an import_state token (or ideally store/restore it from the state token as well).
if (isrv('import_state')) {
$import_state = package_import_take_state(grv('import_state'));
if ($import_state === false) {
raise_message('invalid_import_state', __('The selected package import state has expired or is invalid. Please review the package and try again.'), MESSAGE_LEVEL_ERROR);
header('Location: package_import.php');
exit;
}
$package_location = $import_state['package_location'];
$profile_id = $import_state['data_source_profile'];
$remove_orphans = $import_state['remove_orphans'];
$replace_svalues = $import_state['replace_svalues'];
}
Adds small HTML input rendering helpers that escape attribute names and values, then migrates package import hidden fields and the aggregate graph rfilter textbox away from raw value interpolation.
This narrows two recurring reflected-XSS patterns: serialized hidden state in single-quoted attributes and request-derived filter text in text input values. Package import state now uses safer form helpers instead of hand-built hidden inputs.
Validation: local PHP syntax checks passed for the changed files. GitHub checks pass for PHP 8.1, 8.2, 8.3, 8.4, and the Pest coverage gate.
Part of #7371