Page MenuHomePhabricator

Inconsistent behavior of User::isIP between IPv4 and IPv6 ranges
Open, Needs TriagePublic

Description

User::isIP() accepts IPv6 ranges (like 2001:db8::/32) but not IPv4 ranges (like 192.0.2.0/24). It should probably be made consistent somehow; this might involve having one method to accept ranges and another to not.

An audit of existing uses and whether they seem like they should or shouldn't accept ranges is in T239527#5705550.

Details

Related Gerrit Patches:

Event Timeline

Restricted Application added a project: Core Platform Team. · View Herald TranscriptDec 1 2019, 6:59 AM
Restricted Application added a subscriber: Aklapper. · View Herald Transcript

That calls User::isIP for verification, which is:

User::isIP
return preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/', $name )
	|| IP::isIPv6( $name );

the regex doesn't support IPv4 ranges. But, IP::isIPv6 and IP::isIPv4 both do.

Yes, I'm going to submit a patch once I figure out what's gone wrong with my git review. Coming soon! :)

Change 553835 had a related patch set uploaded (by DannyS712; owner: MusikAnimal):
[mediawiki/core@master] Make User::isIP consider IPv4 ranges as valid

https://gerrit.wikimedia.org/r/553835

@DannyS712, just curious, what happened here?

@DannyS712, just curious, what happened here?

Gerritbot didn't recognize the patch because of the extra line at the end of the commit message (https://www.mediawiki.org/wiki/Gerrit/Commit_message_guidelines) - I didn't realize that removing the line would trigger the bot, so I manually posted here and then removed it. Was that not okay?

MusikAnimal added a comment.EditedDec 1 2019, 8:02 AM

Gerritbot didn't recognize the patch because of the extra line at the end of the commit message (https://www.mediawiki.org/wiki/Gerrit/Commit_message_guidelines) - I didn't realize that removing the line would trigger the bot, so I manually posted here and then removed it. Was that not okay?

Ah! I missed the big red bar clearly indicating removed something, and not just the other change which is what I questioning :) Thanks!

I have a tiny worry some consumers of Users:isIP rely on this misbehaviour, but the tests are all green.

Anomie added a subscriber: Anomie.EditedDec 2 2019, 3:52 PM

I have a tiny worry some consumers of Users:isIP rely on this misbehaviour, but the tests are all green.

I did an audit:

  • SearchNearMatcher: Probably an improvement, results in a suggestion for something like "Special:Contributions/192.0.2.0/24".
  • EditPage: No effect, calling code already strips everything after the first "/".
  • DerivedPageDataUpdater: Probably negative, will call User::setNewtalk() on edits to User talk-namespace subpages like "User talk:192.0.2.0/24". IPv6 ranges similarly shouldn't be accepted here.
  • Skin.php: Possibly negative. Will start considering ranges as a "relevant user", even though ranges aren't users.
  • Article: No effect, calling code already strips everything after the first "/".
  • SpecialContributions: No effect, specifically checks for ranges.
  • ImageListPager: Probably negative, removes the "user does not exist" message which hints that the special page doesn't actually support ranges. IPv6 ranges similarly shouldn't be accepted here.
  • ApiQueryBlocks: Probably positive, although gerrit:434718 will probably refactor this code anyway.
  • ApiQueryUserContribs: Probably positive, same as ApiQueryBlocks. Probably negative, wouldn't work. To query ranges, it would need logic to use the ip_changes table (and probably also either a separate parameter or some other way of restricting it to just one range). See T177150.
  • ApiRollback: Probably negative, will allow trying to rollback a range (which will still fail, but I think with an "already rolled back" error rather than "invalid username"). IPv6 ranges similarly shouldn't be accepted here.
  • maintenance/reassignEdits.php: Probably negative, allows reassigning to/from a range even though ranges aren't users. IPv6 ranges similarly shouldn't be accepted here.
  • maintenance/rollbackEdits.php: Probably negative, same as ApiRollback.
  • MediaWiki-extensions-LdapAuthentication LdapAuthenticationPlugin: Probably no effect? Won't try to munge IPv4 ranges anymore, whatever effect that has.
  • MobileFrontend ExtMobileFrontend: No effect, caller will skip it as a subpage of the User-namespace page.
  • MobileFrontend SpecialMobileContributions: Unclear. Possibly negative where it will start claiming User:192.0.2.0/24 is a user page, but possibly positive in that it'll now pass ranges through to ContribsPager.
  • MediaWiki-extensions-WikibaseClient ChangeLineFormatter: No effect, looks like the caller can never pass a range to begin with.
  • Notifications DiscussionParser::getUserMentions(): No effect, subpages are skipped earlier in the code path.
  • Notifications DiscussionParser::extractUserFromLink(): Unclear. Seems unused?
  • MediaWiki-extensions-WikimediaIncubator SpecialViewUserLang: Probably positive, will start reporting an error for ranges like it does IPs.
  • VisualEditor ApiVisualEditor: No effect, calling code already strips everything after the first "/".
  • MinervaNeue SkinUserPageHelper: No effect, subpages are skipped earlier in the code path.
  • Nostalgia NostalgiaTemplate: Probably negative, will start considering pages like User:192.0.2.0/24 as user pages. Probably shouldn't be treating IPv6 ranges as user pages either.
  • RegexBlock RegexBlockCore: Unclear, not taking the time to work it out.
  • LookupUser LookupUser.body.php: Probably positive, in that it'll not add its link to Special:Contributions/192.0.2.0/24 anymore (which it presumably doesn't handle since it's already not adding its link to Special:Contributions/192.0.2.0)
  • BlueSpiceReaders extension InsertTrace: Probably no effect, code path shouldn't even be reached.
  • MediaWiki-extensions-OnlineStatusBar OnlineStatusBar.hooks.php and ApiOnlineStatus: Unclear, not taking the time to work it out.
  • NoBogusUserpages extension NoBogusUserpages: No effect, calling code already strips everything after the first "/".
  • StaffPowers extension StaffPowers: Probably no effect, not taking the time to work it out.
  • Sudo extension SpecialSudo: Probably no effect, code path should be unreachable since User::newFromName( $name ) will have returned null earlier.
  • ChangeAuthor extension ChangeAuthor: Probably negative, unless the following code handles ranges. Not taking time to work it out.
  • BlueSpiceAuthors extension AuthorsList: Probably no effect, looks it it can never pass a range to begin with.

@Anomie Thanks for the very thorough research! It sounds like maybe this is too risky. My goal was merely to fix the list=blocks API. Maybe I could just rework it to accept all IP ranges, rather than changing Users:isIP directly?

Skin.php: Possibly negative. Will start considering ranges as a "relevant user", even though ranges aren't users.

See also T206954: Enable wgRelevantUserName for IP ranges

Anomie added a comment.Dec 3 2019, 5:13 PM

Probably the thing to do would be to create "User::isIPRange()" or the like, fix User::isIP to not return true for IPv6 ranges, and switch callers of isIP to the new method where that seems to give more-correct behavior.

Yes! Or at least they have the same solution :) I say let's merge that one into this one, given here we have made some progress through discussion.

Another pseudo-duplicate: T177150: Add IP range support to list=usercontribs API

The issue probably carries over there, but that one deserves it's own ticket as it is a new feature (or missing feature) and not a bug report.

  • ApiQueryBlocks: Probably positive, although gerrit:434718 will probably refactor this code anyway.

That's indeed happening, so this task as stated would be obsolete.

I'll do as @MusikAnimal suggested in T239527#5745074 by merging the other task into this one and extending the scope of this accordingly.

Anomie renamed this task from list=blocks does not support IPv4 ranges to Inconsistent behavior of User::isIP between IPv4 and IPv6 ranges.Tue, Jan 14, 10:21 PM
Anomie updated the task description. (Show Details)