summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/quickstart/protected/pages/Advanced/Security.page12
-rw-r--r--demos/quickstart/protected/pages/Fundamentals/Components.page25
-rw-r--r--framework/TComponent.php54
3 files changed, 87 insertions, 4 deletions
diff --git a/demos/quickstart/protected/pages/Advanced/Security.page b/demos/quickstart/protected/pages/Advanced/Security.page
index c3d0b511..226d7e49 100644
--- a/demos/quickstart/protected/pages/Advanced/Security.page
+++ b/demos/quickstart/protected/pages/Advanced/Security.page
@@ -36,7 +36,17 @@ One of the most important measures to prevent XSS attacks is to check user input
<p id="730570" class="block-content">
PRADO incorporates the work of <a href="http://pixel-apes.com/safehtml/">SafeHTML</a> and provides developers with a useful component called <tt>TSafeHtml</tt>. By enclosing content within a <tt>TSafeHtml</tt> component tag, the enclosed content are ensured to be safe to end users. In addition, the commonly used <tt>TTextBox</tt> has a <tt>SafeText</tt> property which contains user input that are ensured to be safe if displayed directly to end users.
</p>
-
+<p class="block-content">
+With the broad use of active controls and more generally of AJAX-enabled controls using Javascript to transfer data between the server and the client, it's common to see attackers target javascript itself as a vector to inject malicious code.
+</p>
+<p class="block-content">
+Imagine a validator that uses an ajax callback to check user input from a textbox and returns an error message including the user input, example: 'The email address is not valid: test@example.com'.
+In such a situation user input <b>must</b> be checked to avoid possible injection.
+</p>
+<p class="block-content">
+The classic xss check involves checking for html tags inside the message and encode them; but since the message gets sent back to the client inside a javascript block, it needs to be encoded again to avoid any possible javascript escaping.
+By default PRADO encodes all variables sent clientside inside a javascript block to avoid any user-generated input from injecting malicious javascript code.
+</p>
<h2 id="5604">Cookie Attack Prevention</h2>
<p id="730571" class="block-content">
Protecting cookies from being attacked is of extreme important, as session IDs are commonly stored in cookies. If one gets hold of a session ID, he essentially owns all relevant session information.
diff --git a/demos/quickstart/protected/pages/Fundamentals/Components.page b/demos/quickstart/protected/pages/Fundamentals/Components.page
index 5662b53b..2ce96607 100644
--- a/demos/quickstart/protected/pages/Fundamentals/Components.page
+++ b/demos/quickstart/protected/pages/Fundamentals/Components.page
@@ -49,10 +49,33 @@ This is equivalent to the following,
$name = $component->getFont()->getName();
$component-&gt;getFont()-&gt;setName( $name );
</com:TTextHighlighter>
+</p>
-
+<h3>Js-friendly properties</h3>
+<p class="block-content">
+A JavaScript-friendly property is a property that can accept both simple strings and raw javascript.
+Prado automatically encodes all properties sent clientside inside javascript blocks to avoid security problems (like injections or cross site scripting).
+If a property is known to always contain only safe javascript code and its value needs to bypass this encoding, that property can be defined in a special way that will make Prado mark its value as "safe".
+Js-friendly properties are identified by their name starting with 'js' (case insensitive):
+<com:TTextHighlighter CssClass="source block-content">
+// getter, defines a readable property 'Text'
+function getJsText() { … }
+// setter, defines a writable property 'Text', with $value being the value to be set to the property
+function setJsText(TJavaScriptLiteral $value) { … }
+</com:TTextHighlighter>
+Js-friendly properties can be accessed using both their Js-less name and their Js-enabled name:
+<com:TTextHighlighter CssClass="source block-content">
+// set some simple text as property value
+$component-&gt;Text = 'text';
+// set some javascript code as property value
+$component-&gt;JsText = 'raw javascript';
+</com:TTextHighlighter>
+In the first case, the property value will automatically gets encoded when sent clientside inside a javascript block.
+In the second case, the property will be 'marked' as being a safe javascript statement and will not be encoded when rendered inside a javascript block.
+This special handling makes use of the <tt>TJavaScriptLiteral</tt> class.
</p>
+
<h2 id="703">Component Events</h2>
<p id="110119" class="block-content">
Component events are special properties that take method names as their values. Attaching (setting) a method to an event will hook up the method to the places at which the event is raised. Therefore, the behavior of a component can be modified in a way that may not be foreseen during the development of the component.
diff --git a/framework/TComponent.php b/framework/TComponent.php
index e413aebc..e0afac44 100644
--- a/framework/TComponent.php
+++ b/framework/TComponent.php
@@ -35,6 +35,31 @@
* in the format of concatenated words, with the first letter of each word
* capitalized (e.g. DisplayMode, ItemStyle).
*
+ * Since Prado 3.2 a new class of javascript-friendly properties have been introduced
+ * to better deal with potential security problems like cross-site scripting issues.
+ * All the data that gets sent clientside inside a javascript block is now encoded by default.
+ * Sometimes there's the need to bypass this encoding and be able to send raw javascript code.
+ * This new class of javascript-friendly properties are identified by their name
+ * starting with 'js' (case insensitive):
+ * <code>
+ * // getter, defines a readable property 'Text'
+ * function getJsText() { ... }
+ * // setter, defines a writable property 'Text', with $value being the value to be set to the property
+ * function setJsText(TJavaScriptLiteral $value) { ... }
+ * </code>
+ * Js-friendly properties can be accessed using both their Js-less name and their Js-enabled name:
+ * <code>
+ * // set some simple text as property value
+ * $component->Text = 'text';
+ * // set some javascript code as property value
+ * $component->JsText = 'raw javascript';
+ * </code>
+ * In the first case, the property value will automatically gets encoded when sent
+ * clientside inside a javascript block.
+ * In the second case, the property will be 'marked' as being a safe javascript
+ * statement and will not be encoded when rendered inside a javascript block.
+ * This special handling makes use of the {@link TJavaScriptLiteral} class.
+ *
* An event is defined by the presence of a method whose name starts with 'on'.
* The event name is the method name and is thus case-insensitive.
* An event can be attached with one or several methods (called event handlers).
@@ -955,8 +980,25 @@ class TComponentReflection extends TComponent
/**
* TJavaScriptLiteral class that encloses string literals that are not
- * supposed to be escaped by TJavaScript::encode()
+ * supposed to be escaped by {@link TJavaScript::encode() }
+ *
+ * Since Prado 3.2 all the data that gets sent clientside inside a javascript statement
+ * is encoded by default to avoid any kind of injection.
+ * Sometimes there's the need to bypass this encoding and send raw javascript code.
+ * To ensure that a string doesn't get encoded by {@link TJavaScript::encode() },
+ * construct a new TJavaScriptLiteral:
+ * <code>
+ * // a javascript test string
+ * $js="alert('hello')";
+ * // the string in $raw will not be encoded when sent clientside inside a javascript block
+ * $raw=new TJavaScriptLiteral($js);
+ * // shortened form
+ * $raw=_js($js);
+ * </code>
*
+ * @version $Id$
+ * @package System
+ * @since prado 3.2
*/
class TJavaScriptLiteral
{
@@ -978,10 +1020,18 @@ class TJavaScriptLiteral
}
}
+/**
+ * TJavaScriptString class is an internal class that marks strings that will be
+ * forcibly encoded when rendered inside a javascript block
+ *
+ * @version $Id$
+ * @package System
+ * @since prado 3.2
+ */
class TJavaScriptString extends TJavaScriptLiteral
{
public function toJavaScriptLiteral()
{
return TJavaScript::jsonEncode((string)$this->_s,JSON_HEX_QUOT | JSON_HEX_APOS | JSON_HEX_TAG);
}
-} \ No newline at end of file
+}