Last modified: 2009-09-10 21:18:22 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T21646, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 19646 - Localization of img_auth.php - with enhancements
Localization of img_auth.php - with enhancements
Status: RESOLVED FIXED
Product: MediaWiki
Classification: Unclassified
File management (Other open bugs)
1.16.x
All All
: Normal enhancement (vote)
: ---
Assigned To: Jack D. Pond
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-07-10 21:18 UTC by Jack D. Pond
Modified: 2009-09-10 21:18 UTC (History)
4 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments
Updated img_auth.php (4.23 KB, patch)
2009-07-10 21:18 UTC, Jack D. Pond
Details
Localization file (en only) for img_auth (1.26 KB, patch)
2009-07-10 21:19 UTC, Jack D. Pond
Details
Patch File of final (6.55 KB, patch)
2009-09-01 22:48 UTC, Jack D. Pond
Details
Complete Tested code - ready for code review (4.71 KB, application/php)
2009-09-01 22:49 UTC, Jack D. Pond
Details
Updated img_auth.php using suggestions from code review (6.80 KB, patch)
2009-09-02 18:41 UTC, Jack D. Pond
Details
Complete Tested code - ready for final code review before commit to trunk (4.63 KB, application/php)
2009-09-02 18:42 UTC, Jack D. Pond
Details
Additional Messages rqd for img_auth script (1.45 KB, patch)
2009-09-02 23:28 UTC, Jack D. Pond
Details
Message Instructions for localization (1.80 KB, patch)
2009-09-02 23:29 UTC, Jack D. Pond
Details
Moved messages and default settings to language and DefaultSettings.php respectively (6.41 KB, patch)
2009-09-02 23:31 UTC, Jack D. Pond
Details
Complete Tested Code ready for commit to trunk (4.24 KB, application/php)
2009-09-02 23:32 UTC, Jack D. Pond
Details
Unified Diff for bug patches (10.39 KB, patch)
2009-09-02 23:40 UTC, Jack D. Pond
Details
Diff Patches for bug (11.22 KB, patch)
2009-09-03 20:21 UTC, Jack D. Pond
Details
Cleaned up code from revert (12.38 KB, patch)
2009-09-09 03:54 UTC, Jack D. Pond
Details
Final Touches and localisation files (75.19 KB, patch)
2009-09-09 21:20 UTC, Jack D. Pond
Details

Description Jack D. Pond 2009-07-10 21:18:59 UTC
Created attachment 6320 [details]
Updated img_auth.php

This started with localizing the messages with img_auth.php but expanded.

1. Localize img_auth.php using img_auth.i18.php and current EN language
2. Reorder checks to make sense (and eliminate redundancy).  New order of checks should be:
   * See if this is a public Wiki (no protections)
   * See if server allows PATH_INFO
   * Basic directory traversal check
   * See if could create the title object
   * Check to see if the file exists
   * Check to see if tried to access a directory
   * See if could create the title object
   * Run hook for extended checks
   * Check user authorization for this title (UserCan)
   * Whitelist check was deprecated - redundant to UserCan
3. Add a hook to allow custom checking for Custom FileRepo(s)
4. Add a global variable wgImgAuthDetails (img_auth only) that defaults to minimum info, but allows
   Details if set to true
5. Move all "wfDebugLog" into the rejection functions - since they should never get there anyway.

This really cleans up the script file and with the hook and localization should minimize future maintenance.

I've tested to the extent that I can in my environment, but really need code check and other testers.

Would also do documentation.
Comment 1 Jack D. Pond 2009-07-10 21:19:55 UTC
Created attachment 6321 [details]
Localization file (en only) for img_auth
Comment 2 Jack D. Pond 2009-07-10 21:36:50 UTC
Installation Instructions for testers:

1. Copy img_auth.php into ($IP) dir (overwrites existing)
2. Copy img_auth.i18.php into ($IP) dir (where img_auth.php) resides

Note:  First "* See if could create the title object" in check order of description is redundant, and a typo.  Real check is right before hook.
Comment 3 Brion Vibber 2009-07-11 02:28:03 UTC
Couple quick notes:

First, the first parameter to wfForbidden() seems to always be the "access forbidden" message; it's probably cleaner to just call that from the function. :)

The debug log messages shouldn't be localized; those are internal messages which should be consistently readable by site administrators in a multilingual environment so they can debug issues.

With $wgImgAuthDetails on, input filenames are being passed into HTML error messages without validation or escaping; this is a script injection vuln. wfMsgHTML() escapes the text of the message, then replaces in your parameters -- the expectation being that your parameters are formatted HTML such as links.

Also we'd generally want config vars like this defined in DefaultSettings.php so they can be consistently located.

I'm a little vague on what the hook accomplishes; if meant for alternate file repository types, it'll fail as we've already dropped out a 403 result due to the file not existing in $wgUploadDirectory... It looks like the only thing it could do is reject access to local files which would otherwise have been allowed.

Probably if alternate source backends are desired here (say, database storage or a WebDAV storage backend), they'd need their own implementation on the repository class for checking path validity and doing the output streaming.
Comment 4 Jack D. Pond 2009-07-12 03:19:31 UTC
(In reply to comment #3)
> Couple quick notes:
> First, the first parameter to wfForbidden() seems to always be the "access
> forbidden" message; it's probably cleaner to just call that from the function.
> :)
There are two parts to the HTML 403 message, the header and the body.
* msg1 is header
* msg2 is body
Would be glad to change, but many gov sites have a standard header text
such as:
* We're big bad mothers so don't mess with us
Followed by standard body text
* The knock you're hearing on the door is our black suited, dark eyeglass goon
squad who are going to take you to a dark place and do terrible things to you.

I'd be glad to reduce the customization, but thought, what the heck.

> The debug log messages shouldn't be localized; those are internal messages
> which should be consistently readable by site administrators in a multilingual
> environment so they can debug issues.

When I updated the messaging, I thought, hey, some people may want to give out
more detailed messages than "you can't get here", so I added that capability
with the localization.  As long as that message was being sent to the user,
thought it might make sense to send the exact same message to the log file.

> With $wgImgAuthDetails on, input filenames are being passed into HTML error
> messages without validation or escaping; this is a script injection vuln.
> wfMsgHTML() escapes the text of the message, then replaces in your parameters
> -- the expectation being that your parameters are formatted HTML such as links.

Good point about the script vunerability.  Don't know how I missed that one.
Unless you have a better approach, I think I'll just take out the "$1" capability
in all the messages.

Should I be using straight wfMsg instead of wfMsgHTML too?  Other suggestions
(or someone who might help without bothering you?)

> Also we'd generally want config vars like this defined in DefaultSettings.php
> so they can be consistently located.

I think that img_auth.php isn't used in the majority of MediaWiki installations.
Adding that parameter to the generic is something that would only be used if
img_auth (rewriting) is used.  If you think it's better there, I'm all for it.
This way, only used when needed.

> I'm a little vague on what the hook accomplishes; if meant for alternate file
> repository types, it'll fail as we've already dropped out a 403 result due to
> the file not existing in $wgUploadDirectory... It looks like the only thing it
> could do is reject access to local files which would otherwise have been
> allowed.
> Probably if alternate source backends are desired here (say, database storage
> or a WebDAV storage backend), they'd need their own implementation on the
> repository class for checking path validity and doing the output streaming.

You saw straight through me on this one.  Yes, I was intending to use it on
NSFileRepo, which does namespace validation.  That implementation, based on
Tim Starling's recommendation, is an extension and alternate
"backend" source - and yes, I used a new repository class to do it.

With this hook, would be able to use this extension and possibly future acess
rejections without branching img_auth.php.

See http://www.mediawiki.org/wiki/Extension:NSFileRepo
Comment 5 Jack D. Pond 2009-07-12 14:02:51 UTC
(In reply to comment #3)
> With $wgImgAuthDetails on, input filenames are being passed into HTML error
> messages without validation or escaping; this is a script injection vuln.
> wfMsgHTML() escapes the text of the message, then replaces in your parameters

Revisiting this one.  I used wfMsgHTML() which has htmlspecialchars() escaping in it.
I may be displaying my ignorance here, but wouldn't that avoid any injection by
displaying it as a string versus allowing the injection of html links, javascript, etc.

This would actually allow the admin to view what the injection attack was, rather than
allow it to proceed.  I'll admit I'm no expert here, so this might be dead wrong.

Would also need to inform hook users to do same in hook documentation.
Comment 6 Jack D. Pond 2009-07-12 14:47:23 UTC
(In reply to comment #3)
> With $wgImgAuthDetails on, input filenames are being passed into HTML error
> messages without validation or escaping; this is a script injection vuln.
> wfMsgHTML() escapes the text of the message, then replaces in your parameters

Ah, stupid me - disregard previous comment.  Would this solve that problem (wherever used)?

   wfForbidden(wfMsgHTML('image_auth-accessdenied'),wfMsgHTML('image_auth-noread',htmlspecialchars($name)));
Comment 7 Jack D. Pond 2009-09-01 22:48:57 UTC
Created attachment 6515 [details]
Patch File of final

Tested and ready for code review if acceptable
Comment 8 Jack D. Pond 2009-09-01 22:49:42 UTC
Created attachment 6516 [details]
Complete Tested code - ready for code review
Comment 9 Jack D. Pond 2009-09-01 23:18:02 UTC
Had an idea that would allow late loading of 18n file.

Instead of invoking wfMsgHTML before calling forbidden, could wait til after then add the 18n require_once in wfForbidden and wfPublicError.

That way the only time the 18n file would load would be when an error has occured.  Down-side would be that hook extensions would have to use only message ID's, not actual messages - but I'm not sure that's bad.
Comment 10 Platonides 2009-09-02 00:05:01 UTC
You could use a wrapper function, eg:
function wfImgAuthMsg() {
 static $fileloaded = false;
 if (!$fileloaded) {
  require_once( dirname( __FILE__ ) . '/img_auth.i18n.php' );
  $fileloaded = true;
 }
  return call_user_func('wfMsgHTML', func_get_args() );
}
Comment 11 Jack D. Pond 2009-09-02 18:41:05 UTC
Created attachment 6517 [details]
Updated img_auth.php using suggestions from code review

1) Only loads message file if error encountered (should be rare)
2) All logged messages are in english - user messages localized.
3) Errors return message index instead of error messages - actual interpretation of message in wfForbidden.
4) Eliminated all caching, compressed both error messages routines into a single routine.
Comment 12 Jack D. Pond 2009-09-02 18:42:24 UTC
Created attachment 6518 [details]
Complete Tested code - ready for final code review before commit to trunk
Comment 13 Jack D. Pond 2009-09-02 23:28:25 UTC
Created attachment 6519 [details]
Additional Messages rqd for img_auth script
Comment 14 Jack D. Pond 2009-09-02 23:29:30 UTC
Created attachment 6520 [details]
Message Instructions for localization
Comment 15 Jack D. Pond 2009-09-02 23:31:46 UTC
Created attachment 6521 [details]
Moved messages and default settings to language and DefaultSettings.php respectively

Will still have to add the following to DefaultSettings.php

$wgImgAuthDetails   = false; ///< defaults to false - only set to true if you use img_auth and want the user to see details on why access failed
$wgImgAuthPublicTest = true; ///< defaults to true - if public read is turned on, no need for img_auth, config error unless other access is used
Comment 16 Jack D. Pond 2009-09-02 23:32:58 UTC
Created attachment 6522 [details]
Complete Tested Code ready for commit to trunk
Comment 17 Jack D. Pond 2009-09-02 23:40:58 UTC
Created attachment 6523 [details]
Unified Diff for bug patches

Unified Diff for all required patches
Comment 18 Niklas Laxström 2009-09-03 07:27:25 UTC
(In reply to comment #13)
> Created an attachment (id=6519) [details]
> Additional Messages rqd for img_auth script

Is there some reason to use ` instead of " what is used elsewhere in MediaWiki?

(In reply to comment #17)
> Created an attachment (id=6523) [details]
+if (!wfRunHooks( 'ImgAuthBeforeStream', array( &$title, &$path, &$name, &$result ) ) )
+	call_user_func_array('wfForbidden',merge_array(array($result[0],$result[1]),array_slice($result,2)));
Maybe a short comment here about the type of $result wouldn't hurt. If this is a new hook, it should be documented in docs/hooks.txt.

+'img-auth-accessdenied'   => "[[Image Authorization]] Access Denied",
Is the link supposed to go somewhere? Documentation is also wikitext. It looks like you did not update maintenance/language/messages.inc, but hey, other developers forget to update it too.

I'm happy that you provided message documentation and that you pass around message keys instead of strings. It is a bit more flexible if you ever want to change something, like support magic words in the translations.

+'img-auth-nopathinfo'     => "Missing PATH_INFO.  Your server is not set up to pass this information - may be CGI-based and can't support img_auth. See `Image Authorization` on MediaWiki.",
Manual:x on MediaWiki.org?
+'img-auth-notindir' 	  => "Requested path not in upload directory.",
is not in the upload directory?
+'img-auth-badtitle' 	  => "Unable to construct a valid Title from `$1`.",
Title with lowercase, users don't need to care if it is Object for us or not.
+'img-auth-nologinnWL'     => "Not logged in and `$1` not in whitelist.",
"You are not logged in ... is not in the whitelist"
+'img-auth-nofile' 	      => "`$1` does not exist.",
Maybe prefix with File, to give a hint what is expected
+'img-auth-isdir' 		  => "`$1` is a directory.",
Same here, you could say we except a file, but directory was given.


Comment 19 Jack D. Pond 2009-09-03 20:21:52 UTC
Created attachment 6529 [details]
Diff Patches for bug

1. Added to messages.inc,used miscellaneous3 block.
2. Followed Niklas's suggestions and modified messages

If all is OK, will Commit.

On Commit, will document:

1) ImgAuthBeforeStream hook
2) $wgImgAuthDetails
3) wgImgAuthPublicTest
Comment 20 Brion Vibber 2009-09-04 23:22:08 UTC
Hrm... this code is *really* nasty looking and needs to be reverted or cleaned up.

What's with the call_user_func_array() stuff everywhere? If you need to pass more variable parameters, just have it take an array... Don't try to squish random params onto wfMsgHtml() when you can simply use wfMsgExt() which will take an array of options and an array of message arguments.
Comment 21 Brion Vibber 2009-09-08 18:08:53 UTC
Reverted in r56051.
Comment 22 Jack D. Pond 2009-09-09 03:54:44 UTC
Created attachment 6533 [details]
Cleaned up code from revert

Cleaned up code:
1) Removed all call_user_func_array(), used $arg array
2) Removed all htmlspecialchars() for file name escaping
3) Reapplied DefaultSettings.php
4) Reapplied messages.inc
5) Reapplied MessagesEn.php and MessagesQqq.php
6) Reapplied RELEASE-NOTES
7) Tested

Don't know how to handle reapplying all the internationalization patches - whether that is automatic or whether I should do it manually, but will find out on IRC before committing.
Comment 23 Brion Vibber 2009-09-09 17:35:36 UTC
Much cleaner code. :) The one additional recommendation (posted this in IRC, not sure if you saw):

my one other recommendation is to change the wgMsgHtml() here to wfMsg() and do an htmlspecialchars() on the outside yourself (or possibly this can be done with one of the escaping options on wfMsgExt() -- we want to HTML-escape after argument replacement, whereas wfMsgHtml() does the escaping before argument replacement)


The rest of the localizations got reverted in r56053; you can re-merge them like so:

  svn merge -r56053:56052 .

then do a commit as normal.
Comment 24 Jack D. Pond 2009-09-09 21:20:24 UTC
Created attachment 6535 [details]
Final Touches and localisation files

1) Replaced wgMsgHtml() with htmlspecialchars(wfMsg()).  Did not change wfMsgExt() because it is only used to output to log file - which cannot be injected.
2) Merged all localisation files back in.
3) Tested

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links