rfc:escaping_operator

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:escaping_operator [2016/07/24 09:52] michael-vostrikovrfc:escaping_operator [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
-====== PHP RFC: New operator for context-dependent escaping ======+====== PHP RFC: New operator (short tag) for context-dependent escaping ======
   * Version: 1.0   * Version: 1.0
   * Date: 2016-07-14   * Date: 2016-07-14
   * Author: Michael Vostrikov <michael.vostrikov@gmail.com>   * Author: Michael Vostrikov <michael.vostrikov@gmail.com>
-  * Status: Under Discussion+  * Status: Declined
   * First Published at: http://wiki.php.net/rfc/escaping_operator   * First Published at: http://wiki.php.net/rfc/escaping_operator
  
Line 22: Line 22:
  
 The problem is that <php><?= h($something) ?></php> and <php><?= $something ?></php> both work good, and unsafe variant works exactly as safe one until we get unsafe data. There is no such problem with other contexts. If we don't call json_encode() when passing an array or object into javascript, this only will break the script, and this will be noticeable, there won't be a problem with security. Also, because we need to call escaping function everywhere, the problem is that we must copy-paste it, and there is a possibility to forget to do this sometime. The problem is that <php><?= h($something) ?></php> and <php><?= $something ?></php> both work good, and unsafe variant works exactly as safe one until we get unsafe data. There is no such problem with other contexts. If we don't call json_encode() when passing an array or object into javascript, this only will break the script, and this will be noticeable, there won't be a problem with security. Also, because we need to call escaping function everywhere, the problem is that we must copy-paste it, and there is a possibility to forget to do this sometime.
 +
 +Calling an escaping function manually on every output is the same as calling constructor manually after every 'new' statement:
 +<PHP>
 +(new User)->__construct(...);
 +(new Profile)->__construct(...);
 +</PHP>
  
 Main argument against such operator is that main problem is in specific context. There are various contexts and each one requires special escaping. But I think this is not required to support all of them. Because - who asks about it?) There are no requests about special operator for json_encode(), but there are many requests for htmlspecialchars(). You can not deny the problem with HTML escaping really exists. My first goal is to draw the attention on it. Exact implementation is a secondary thing. Main argument against such operator is that main problem is in specific context. There are various contexts and each one requires special escaping. But I think this is not required to support all of them. Because - who asks about it?) There are no requests about special operator for json_encode(), but there are many requests for htmlspecialchars(). You can not deny the problem with HTML escaping really exists. My first goal is to draw the attention on it. Exact implementation is a secondary thing.
Line 54: Line 60:
  
 The purpose of this operator is The purpose of this operator is
-  - To make frequent operations for escaping and default escaping easier to use, to add a simple way to call an escaping function.+  - To make frequent operations for escapingand especially default escapingeasier to use, to add a simple way to call an escaping function.
   - To remove copy-paste for calling an escaping function.   - To remove copy-paste for calling an escaping function.
   - To improve a security, because the escaping will become automatic in all places, and this will prevent XSS.   - To improve a security, because the escaping will become automatic in all places, and this will prevent XSS.
Line 92: Line 98:
 Function restore_escape_handler() removes current handler and restores previously set handler. Function restore_escape_handler() removes current handler and restores previously set handler.
  
-Function escape_handler_call() just pass given arguments into user-defined handler. Second argument is not required. If the handler is not set, it throws an exception. There is no default handler for any context, to prevent 'built-in' wrong work of <?* $str ?> constructions in non-HTML contexts like CSV. This is not hard to create a handler once. Default context can be set in it as default value for second argument.+Function escape_handler_call() just pass given arguments into user-defined handler. Second argument is not required. If the handler is not set, it throws an exception. Default context can be set in it as default value for second argument.
  
  
Line 149: Line 155:
  
 Passes given arguments into user-defined handler. Argumants are passed 'as is', without any changes. Passes given arguments into user-defined handler. Argumants are passed 'as is', without any changes.
-Second argument is not required. If the handler is not set, it throws an exception. There is no default handler for any context, to prevent 'built-in' wrong work of <?* $str ?> constructions in non-HTML contexts. User must define itws own handler before using escaping operator. Default context can be set in it as default value for second argument.+Second argument is not required. If the handler is not set, it throws an exception. Default context can be set in it as default value for second argument.
  
 ===== Main arguments 'for' and 'against' ===== ===== Main arguments 'for' and 'against' =====
Line 232: Line 238:
 It is easy to use and has small amount of code. It is easy to use and has small amount of code.
 It does not change Zend VM opcodes and does not break any existing code. It does not change Zend VM opcodes and does not break any existing code.
 +It can be used as a replacement for standard '<?= $str ?>' operator in the form like '<?* $str, 'raw' ?>'.
  
 Also it will be useful for beginners, which don't know about HTML escaping or forget about it. If there will be special operator for HTML-safe output, beginners will use it, because this is simple. Also it will be useful for beginners, which don't know about HTML escaping or forget about it. If there will be special operator for HTML-safe output, beginners will use it, because this is simple.
Line 273: Line 280:
 PHPEscaper::escapeHandlerCall() PHPEscaper::escapeHandlerCall()
 </PHP> </PHP>
 +
 +\\ 
 +Built-in contexts.\\  
 +Default handler with built-in contexts can cause 'built-in' wrong work of <?* $str ?> constructions with one parameter in non-HTML contexts like CSV or plain text. But maybe it would be enough to add a possibility to fully unregister default handler.
 +\\ 
  
 And also any names in source code or details of implementation, without changing main algorithm. And also any names in source code or details of implementation, without changing main algorithm.
Line 279: Line 291:
  
 What is not under discussion: What is not under discussion:
- 
-Built-in contexts.\\   
-Because escape_handler_call() is not an escaper itself, but just a helper to call user-defined escaper, it should not handle any contexts. This allows to prevent 'built-in' wrong work of <?* $str ?> constructions in non-HTML contexts like CSV. 
- 
  
 Multiple arguments.\\  Multiple arguments.\\ 
Line 293: Line 301:
 directly, and it will be something like\\  directly, and it will be something like\\ 
 <php><?= escape_handler_call(escape_handler_call($str, 'html'), 'js') ?></php>\\  <php><?= escape_handler_call(escape_handler_call($str, 'html'), 'js') ?></php>\\ 
-I.e. we anyway need to pass context as a second argument, so why not allow user to do it.+I.e. we anyway need to pass context as a second argument, so why not allow user to do this.
  
  
Line 313: Line 321:
  
 ==== To Existsing Applications/Extensions ==== ==== To Existsing Applications/Extensions ====
-There may be some applications or extensions which contains <?* some text ?> as raw text in PHP template.+There may be some applications or extensions which contains <?* some text ?> as raw text in PHP template, or which have the same function names.
  
  
Line 322: Line 330:
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
  
-Can this operator be useful for many people and implemented in PHP in some of forms described above?\\ 
-The choices are Yes or No\\ 
 Requires a 2/3 majority\\ Requires a 2/3 majority\\
 +Voting is open till August 6.\\ 
  
 +Will this short tag / operator be useful for many people with the functionality described above?
 +<doodle title="Add new operator (short tag) for context-dependent escaping to next PHP 7.x?" auth="michael-vostrikov" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
 +
 +\\ 
 +Additional questions. Voting is not required if you have voted 'No' in the first vote.
 +\\ 
 +<doodle title="Is default handler required, with a possibility to fully unregister it?" auth="michael-vostrikov" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
 +\\ 
 +
 +<doodle title="Is it needed to wrap the functions into static class?" auth="michael-vostrikov" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
 +\\ 
 +
 +<doodle title="Is the comma suitable as a separation sign?" auth="michael-vostrikov" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
 +\\ 
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
 +
 Diff with changes:\\ Diff with changes:\\
 https://github.com/michael-vostrikov/php-src/commit/ca149a3dfea71f529eb1647f2d0ed2b8d63e279d https://github.com/michael-vostrikov/php-src/commit/ca149a3dfea71f529eb1647f2d0ed2b8d63e279d
Line 337: Line 371:
  
 ===== References ===== ===== References =====
-Discussions: +Discussions:\\  
-http://marc.info/?t=146619199100001 +http://marc.info/?t=146619199100001\\  
-http://marc.info/?t=146868366400003+http://marc.info/?t=146868366400003\\ 
  
 Diff with changes: Diff with changes:
rfc/escaping_operator.1469353967.txt.gz · Last modified: 2017/09/22 13:28 (external edit)