Skip to content

fix: scan .phtml files as PHP - #2037

Open
arpitjain099 wants to merge 1 commit into
Bearer:mainfrom
arpitjain099:fix/phtml-php-scanning
Open

arpitjain099 wants to merge 1 commit into
Bearer:mainfrom
arpitjain099:fix/phtml-php-scanning

Conversation

@arpitjain099

Copy link
Copy Markdown

.phtml files are never scanned. enry classifies them as HTML+PHP rather than PHP:

a.php      GetLanguageByExtension="Hack"      byExtension=[Hack PHP]
a.phtml    GetLanguageByExtension="HTML+PHP"  byExtension=[HTML+PHP]
a.php5     GetLanguageByExtension="PHP"       byExtension=[PHP]

and languagescanner.Scan bails before reading the file when the detected language is not in the list the language declares:

if !slices.Contains(scanner.language.EnryLanguages(), fileInfo.Language) {
    return nil, nil, nil
}

PHP declares only "PHP". There is no warning and no effect on the exit code, so the file is simply absent from the run.

Byte-identical vuln.php and vuln.phtml in one directory, through the built CLI:

critical vuln.php:3 php_lang_exec_using_user_input
high     vuln.php:4 php_lang_raw_output_using_user_input
total: 2

The .phtml copy contributes nothing. After the change both report the same two findings.

.phtml is the default template extension for Magento 2 and Laminas, so this is not an unusual file to have in a PHP codebase; it is where the output rendering lives, which is exactly where the XSS rules are aimed.

A template in the shape those projects actually use, HTML with an embedded PHP block rather than a bare <?php file, is also detected correctly once the language is accepted:

critical template.phtml:7 php_lang_exec_using_user_input

so tree-sitter-php already parses mixed content and the enry string was the only barrier.

javascript already declares three enry languages for the same reason, so the multi-value list is the existing pattern rather than a new one.

Verification

TestEnryLanguagesCoversPhtml asserts both entries are present, and also asserts enry still classifies .phtml as HTML+PHP, so if that ever changes upstream the test says so rather than silently passing. It fails on main.

go test ./pkg/languages/... is 12 packages ok with no failures, and go vet and gofmt -l are clean.

One thing I left alone: GoclocLanguages() still returns ["PHP"]. gocloc uses its own language names, so I did not want to guess at the right string for line-count statistics without checking what it calls these files. Happy to follow up if it matters.

enry classifies .phtml as HTML+PHP, not PHP, and languagescanner.Scan returns
early when the detected language is not in the language's EnryLanguages list.
PHP declares only "PHP", so every .phtml file is dropped before it is read, with
no skipped-file warning and no effect on the exit code.

.phtml is the default template extension for Magento 2 and Laminas, so the
templates that render user input in those projects have never been scanned.

Byte-identical vuln.php and vuln.phtml: the .php copy reports
php_lang_exec_using_user_input CRITICAL and php_lang_raw_output_using_user_input
HIGH, the .phtml copy reports nothing. A .phtml with HTML wrapped around the PHP
block, which is the shape these templates actually take, is detected correctly
once the language is accepted, so tree-sitter-php already handles mixed content.

javascript already lists three enry languages for the same reason.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
@arpitjain099 arpitjain099 changed the title Scan .phtml files as PHP fix: scan .phtml files as PHP Sep 17, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant