Skip to content

Add custom header and text settings for access-denial display#16

Open
yaronkoren wants to merge 7 commits intomywikis:mainfrom
yaronkoren:patch-2
Open

Add custom header and text settings for access-denial display#16
yaronkoren wants to merge 7 commits intomywikis:mainfrom
yaronkoren:patch-2

Conversation

@yaronkoren
Copy link

This allows for much greater freedom in choosing the error code, the language of the message, and even the visual look.

@yaronkoren
Copy link
Author

@jeffw16 - what do you think?

@jeffw16
Copy link
Member

jeffw16 commented Mar 4, 2026

@yaronkoren I think this is a good compromise, but I'd still like to see the use 418 code be kept for backwards compatibility. It can be deprecated for now and removed in a later version.

@yaronkoren
Copy link
Author

Alright, done.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the extension’s “fast deny” behavior for protected special pages by moving from a hard-coded 418 teapot response to configurable denial header/text values, with a compatibility fallback to the existing 418 option.

Changes:

  • Add new configuration keys for a custom denial header and denial text.
  • Update the SpecialPage hook to use the custom denial response (or derive it from the legacy 418 setting).
  • Replace the denyAccessWith418() helper with a new denyAccessCustom() helper.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
includes/Hooks.php Reads new config values and uses a new fast-deny helper to short-circuit expensive special-page execution.
extension.json Adds CrawlerProtectionDenialHeader / CrawlerProtectionDenialText config defaults alongside the legacy CrawlerProtectionUse418.

Comment on lines +140 to +142
protected function denyAccessCustom( $customDenialHeader, $customDenialText ) {
header( htmlspecialchars( $customDenialHeader ) );
die( htmlspecialchars( $customDenialText ) );
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

denyAccessCustom() uses header( htmlspecialchars( ... ) ). htmlspecialchars() is for HTML output, not HTTP headers; it will corrupt valid status/header lines (e.g. turning quotes/ampersands into entities) and still doesn’t prevent response-splitting via CR/LF. Use MediaWiki’s response API (WebResponse/status handling) and validate/sanitize the header value specifically for HTTP headers (e.g. reject/strip \r/\n and restrict to a status line or allowlisted header names).

Copilot uses AI. Check for mistakes.
Comment on lines +124 to 126
if ( $customDenialHeader !== null && $customDenialText !== null ) {
$this->denyAccessCustom( $customDenialHeader, $customDenialText );
}
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fast-deny path was renamed from denyAccessWith418() to denyAccessCustom(), but the PHPUnit suite still references/mocks denyAccessWith418 (e.g. HooksTest covers and expects that method). This will break tests/CI; update the unit tests (and any stubs) to use the new method and add coverage for the new config combinations.

Copilot uses AI. Check for mistakes.
Comment on lines +124 to 126
if ( $customDenialHeader !== null && $customDenialText !== null ) {
$this->denyAccessCustom( $customDenialHeader, $customDenialText );
}
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom-denial branch only triggers when both CrawlerProtectionDenialHeader and CrawlerProtectionDenialText are non-null. If an admin sets only one of the two, the code silently falls back to the expensive denyAccess() path (and the use418 fallback won’t fill the missing value). Consider supporting partial configuration by providing defaults (e.g. default status header and/or default text) or treating either value being set as enabling the fast-deny path.

Copilot uses AI. Check for mistakes.
Comment on lines 31 to +38
"CrawlerProtectionUse418": {
"value": false
},
"CrawlerProtectionDenialHeader": {
"value": null
},
"CrawlerProtectionDenialText": {
"value": null
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR title/description says the "use 418" option is being replaced, but CrawlerProtectionUse418 remains in extension.json and is still read/used as a fallback in Hooks. If this option is intentionally kept for backwards compatibility, it should be documented as deprecated (and docs/tests updated accordingly); otherwise remove it to match the PR intent.

Copilot uses AI. Check for mistakes.
@yaronkoren yaronkoren changed the title Replace "use 418" option with custom header and text options Add custom header and text settings for access-denial display Mar 4, 2026
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.

3 participants