fix(security): HTML-escape attribute dropdown option labels in items attributes view (#4715)

This commit is contained in:
jekkos authored and GitHub committed 2026-09-28 08:44:37 +02:00
1 parent 60f6c8f5d0
commit dc1accc65a
2 files changed
+32 -2

No files matched your search

+30
View File
@@ -189,6 +189,36 @@ class ItemsControllerTest extends CIUnitTestCase
$this->assertTrue($result['success']);
}
/**
* Regression test for GHSA-cm7j-957q-8pgg: an attribute definition whose
* `definition_name` contains HTML must be entity-escaped when rendered in the
* items attributes dropdown, not emitted as a live (executable) tag.
*/
public function testGetAttributesEscapesMaliciousDefinitionName(): void
{
$employeeId = $this->createItemsEmployee();
$this->loginAsItemsEmployee($employeeId);
$payload = '<img src=x onerror=alert(1)>';
$definitionData = [
'definition_name' => $payload,
'definition_type' => TEXT,
'definition_flags' => 0,
'deleted' => 0,
];
$this->assertTrue($this->attribute->saveDefinition($definitionData));
$this->assertNotEmpty($definitionData['definition_id']);
$response = $this->get('/items/attributes/1');
$output = (string) $response->getBody();
// A live, unescaped tag in the dropdown label is the stored-XSS sink.
$this->assertStringNotContainsString($payload, $output);
// The payload must be present only in entity-escaped form.
$this->assertStringContainsString('&lt;img src=x onerror=alert(1)&gt;', $output);
}
public function testGenerateCsvHeaderBasic(): void
{
$stockLocations = ['Warehouse'];