从client(content="<p></p>")中检測到有潜在危急的 Request.Form 值。

本文介绍了一种在.NET项目中处理富文本编辑器内容导致的安全问题解决方案,通过修改控制器方法来避免系统将HTML或JavaScript视为危险输入。

    最近的站点要做一个新闻模块,站点后台须要对新闻进行管理,拿到富文本编辑器的内容,在获取的时候会报一个错误:从client(content="<p>.....</p>")中检測到有潜在危急的 Request.Form 值。

    原来在.net中。Request时出现有HTML或Javascript等字符串时。系统会觉得是危急性值,所以须要我们去掉验证。

 解决方式例如以下:

     给相应的controller的方法加特性 [ValidateInput(false)]

      

     问题解决。


    在网上查资料的时候,解决方法须要改动配置文件,

        <httpRuntime requestValidationMode="2.0" />

        <system.webServer>
           <validation validateIntegratedModeConfiguration="false"/>
  </system.webServer>

    经測试,在我的mvc项目里这样做不生效,不知道是哪里配错了,

    而且这样做可能会带来安全问题,网站非常easy引发跨站脚本攻击(http://www.shaoqun.com/a/29374.aspx)。

    



转载于:https://www.cnblogs.com/gavanwanggw/p/7058625.html

xmlTextNode: function (text) { if (window.ActiveXObject) { return new ActiveXObject(&quot;Microsoft.XMLDOM&quot;).createTextNode(text); } else { return document.createTextNode(text); } }, /** Function: getText * Get the concatenation of all text children of an element. * * Parameters: * (XMLElement) elem - A DOM element. * * Returns: * A String with the concatenated text of all text element children. */ getText: function (elem) { if (!elem) return null; var str = &quot;&quot;; if (elem.childNodes.length === 0 && elem.nodeType == Strophe.ElementType.TEXT) { str += elem.nodeValue; } for (var i = 0; i &lt; elem.childNodes.length; i++) { if (elem.childNodes[i].nodeType == Strophe.ElementType.TEXT) { str += elem.childNodes[i].nodeValue; } } return str; }, /** Function: copyElement * Copy an XML DOM element. * * This function copies a DOM element and all its descendants and returns * the new copy. * * Parameters: * (XMLElement) elem - A DOM element. * * Returns: * A new, copied DOM element tree. */ copyElement: function (elem) { var i, el; if (elem.nodeType == Strophe.ElementType.NORMAL) { el = Strophe.xmlElement(elem.tagName); for (i = 0; i &lt; elem.attributes.length; i++) { el.setAttribute(elem.attributes[i].nodeName.toLowerCase(), elem.attributes[i].value); } for (i = 0; i &lt; elem.childNodes.length; i++) { el.appendChild(Strophe.copyElement(elem.childNodes[i])); } } else if (elem.nodeType == Strophe.ElementType.TEXT) { el = Strophe.xmlTextNode(elem.nodeValue); } return el; }, /** Function: escapeJid * Escape a JID. * * Parameters: * (String) jid - A JID. * * Returns: * An escaped JID String. */ escapeJid: function (jid) { var user = jid.split(&quot;@&quot;); if (user.length == 1) // no user so nothing to escape return jid; var host = user.splice(user.length - 1, 1)[0]; user = user.join(&quot;@&quot;) .replace(/^\s+|\s+$/g, '&#39;) .replace(/\\/g, &quot;\\5c&quot;) .replace(/ /g, &quot;\\20&quot;) .replace(/\&quot;/g, &quot;\\22&quot;) .replace(/\&amp;/g, &quot;\\26&quot;) .replace(/\&#39;/g, &quot;\\27&quot;) .replace(/\//g, &quot;\\2f&quot;) .replace(/:/g, &quot;\\3a&quot;) .replace(/&lt;/g, &quot;\\3c&quot;) .replace(/&gt;/g, &quot;\\3e&quot;) .replace(/@/g, &quot;\\40&quot;); return [user, host].join(&quot;@&quot;); }, /** Function: unescapeJid * Unescape a JID. * * Parameters: * (String) jid - A JID. * * Returns: * An unescaped JID String. */ unescapeJid: function (jid) { return jid.replace(/\\20/g, &quot; &quot;) .replace(/\\22/g, '&quot;&#39;) .replace(/\\26/g, &quot;&&quot;) .replace(/\\27/g, &quot;'&quot;) .replace(/\\2f/g, &quot;/&quot;) .replace(/\\3a/g, &quot;:&quot;) .replace(/\\3c/g, &quot;&lt;&quot;) .replace(/\\3e/g, &quot;>&quot;) .replace(/\\40/g, &quot;@&quot;) .replace(/\\5c/g, &quot;\\&quot;); }, /** Function: getNodeFromJid * Get the node portion of a JID String. * * Parameters: * (String) jid - A JID. * * Returns: * A String containing the node. */ getNodeFromJid: function (jid) { if (jid.indexOf(&quot;@&quot;) &lt; 0) return null; return Strophe.escapeJid(jid).split(&quot;@&quot;)[0]; }, /** Function: getDomainFromJid * Get the domain portion of a JID String. * * Parameters: * (String) jid - A JID. * * Returns: * A String containing the domain. */ getDomainFromJid: function (jid) { var bare = Strophe.escapeJid(Strophe.getBareJidFromJid(jid)); if (bare.indexOf(&quot;@&quot;) &lt; 0) return bare; else return bare.split(&quot;@&quot;)[1]; }, /** Function: getResourceFromJid * Get the resource portion of a JID String. * * Parameters: * (String) jid - A JID. * * Returns: * A String containing the resource. */ getResourceFromJid: function (jid) { var s = Strophe.escapeJid(jid).split(&quot;/&quot;); if (s.length &lt; 2) return null; return s[1]; }, /** Function: getBareJidFromJid * Get the bare JID from a JID String. * * Parameters: * (String) jid - A JID. * * Returns: * A String containing the bare JID. */ getBareJidFromJid: function (jid) { return this.escapeJid(jid).split(&quot;/&quot;)[0]; }, /** Function: log * User overrideable logging function. * * This function is called whenever the Strophe library calls any * of the logging functions. The default implementation of this * function does nothing. If client code wishes to handle the logging * messages, it should override this with * > Strophe.log = function (level, msg) { * > (user code here) * > }; * * Please note that data sent and received over the wire is logged * via Strophe.Connection.rawInput() and Strophe.Connection.rawOutput(). * * The different levels and their meanings are * * DEBUG - Messages useful for debugging purposes. * INFO - Informational messages. This is mostly information like * 'disconnect was called' or 'SASL auth succeeded'. * WARN - Warnings about potential problems. This is mostly used * to report transient connection errors like request timeouts. * ERROR - Some error occurred. * FATAL - A non-recoverable fatal error occurred. * * Parameters: * (Integer) level - The log level of the log message. This will * be one of the values in Strophe.LogLevel. * (String) msg - The log message. */ log: function (level, msg) { return; }, /** Function: debug * Log a message at the Strophe.LogLevel.DEBUG level. * * Parameters: * (String) msg - The log message. */ debug: function(msg) { this.log(this.LogLevel.DEBUG, msg); }, /** Function: info * Log a message at the Strophe.LogLevel.INFO level. * * Parameters: * (String) msg - The log message. */ info: function (msg) { this.log(this.LogLevel.INFO, msg); }, /** Function: warn * Log a message at the Strophe.LogLevel.WARN level. * * Parameters: * (String) msg - The log message. */ warn: function (msg) { this.log(this.LogLevel.WARN, msg); }, /** Function: error * Log a message at the Strophe.LogLevel.ERROR level. * * Parameters: * (String) msg - The log message. */ error: function (msg) { this.log(this.LogLevel.ERROR, msg); }, /** Function: fatal * Log a message at the Strophe.LogLevel.FATAL level. * * Parameters: * (String) msg - The log message. */ fatal: function (msg) { this.log(this.LogLevel.FATAL, msg); }, /** Function: serialize * Render a DOM element and all descendants to a String. * * Parameters: * (XMLElement) elem - A DOM element. * * Returns: * The serialized element tree as a String. */ serialize: function (elem) { var result; if (!elem) return null; var nodeName = elem.nodeName; var i, child; if (elem.getAttribute(&quot;_realname&quot;)) { nodeName = elem.getAttribute(&quot;_realname&quot;); } result = &quot;&lt;&quot; + nodeName; for (i = 0; i &lt; elem.attributes.length; i++) { if(elem.attributes[i].nodeName != &quot;_realname&quot;) { result += &quot; &quot; + elem.attributes[i].nodeName.toLowerCase() + &quot;='&quot; + elem.attributes[i].value .replace(&quot;'&quot;, &quot;'&quot;).replace(&quot;&&quot;, &quot;&&quot;) + &quot;'&quot;; } } if (elem.childNodes.length > 0) { result += &quot;>&quot;; for (i = 0; i &lt; elem.childNodes.length; i++) { child = elem.childNodes[i]; if (child.nodeType == Strophe.ElementType.NORMAL) { // normal element, so recurse result += Strophe.serialize(child); } else if (child.nodeType == Strophe.ElementType.TEXT) { // text element result += child.nodeValue; } } result += &quot;&lt;/&quot; + nodeName + &quot;>&quot;; } else { result += &quot;/>&quot;; } return result; }, /** PrivateVariable: _requestId * _Private_ variable that keeps track of the request ids for * connections. */ _requestId: 0 }; /** Class: Strophe.Builder
08-08
&lt;think>我们正在讨论的是Strophe库中的xmlTextNode函数。根据之前提供的Strophe代码片段,虽然xmlTextNode没有直接出现在你给出的代码中,但我们可以根据Strophe库的常见实现和上下文来推断它的功能和用法。 在Strophe库中,`xmlTextNode`函数通常用于创建一个XML文本节点。在创建XML元素时,我们可能需要为元素添加文本内容,而文本内容就是通过文本节点来表示的。 回顾你之前提供的代码,在`xmlElement`函数中,有这样一段: ```javascript if (typeof(arguments[a]) == &quot;string&quot; || typeof(arguments[a]) == &quot;number&quot;) { node.appendChild(Strophe.xmlTextNode(arguments[a])); } ``` 这里,当参数是字符串或数字时,就会调用`Strophe.xmlTextNode`来创建一个文本节点,并将其作为子节点添加到当前元素中。 因此,我们可以推断`xmlTextNode`函数的作用是:创建一个包含指定文本内容的文本节点。 ### 功能 `Strophe.xmlTextNode`函数用于创建一个文本节点,该节点包含传入的文本内容。在XML DOM中,文本节点是`Node.TEXT_NODE`类型的节点,用于表示元素的文本内容。 ### 用法 函数的调用形式为: ```javascript Strophe.xmlTextNode(text) ``` - 参数`text`:字符串或数字,将作为文本节点的内容。 - 返回:一个文本节点(DOM Text节点)。 ### 示例 假设我们要创建一个包含文本内容的XML元素: ```javascript // 创建一个&lt;message>元素,其文本内容为&quot;Hello, world!&quot; var message = Strophe.xmlElement(&quot;message&quot;, null, &quot;Hello, world!&quot;); ``` 实际上,在内部,`Strophe.xmlElement`会调用`Strophe.xmlTextNode`来创建文本节点。我们也可以手动创建文本节点并添加到元素中: ```javascript // 创建一个message元素 var message = Strophe.xmlElement(&quot;message&quot;); // 创建文本节点 var textNode = Strophe.xmlTextNode(&quot;Hello, world!&quot;); // 将文本节点添加到message元素中 message.appendChild(textNode); ``` ### 注意 在XML中,文本节点只能包含文本内容。如果传入的是数字,也会被转换为字符串。 ### 实现推测 虽然我们没有看到`xmlTextNode`的具体实现,但根据其功能,它可能是这样实现的: ```javascript xmlTextNode: function (text) { return document.createTextNode(text); } ``` 它直接调用DOM API的`createTextNode`方法。 ### 总结 `Strophe.xmlTextNode`函数是Strophe库中用于创建文本节点的实用函数。它简化了文本节点的创建过程,确保在跨浏览器环境中能够正确创建文本节点。 §§相关问题§§ 1. Strophe库中还有哪些常用的XML操作函数? 2. 如何用Strophe库构建一个包含多个子元素和属性的XML节? 3. 在Strophe中如何处理XML解析?&lt;/think>### Strophe.xmlTextNode函数功能详解 `Strophe.xmlTextNode`是Strophe.js库中用于创建XML文本节点的核心工具函数,主要功能是**安全创建跨浏览器兼容的文本节点**。以下是详细解析: #### 功能说明 1. **文本节点创建** 将字符串或数字转换为XML DOM文本节点 ```javascript const textNode = Strophe.xmlTextNode(&quot;Hello World&quot;); // 输出: &quot;Hello World&quot; (文本节点) ``` 2. **特殊字符转义** 自动处理XML保留字符的转义: ```javascript Strophe.xmlTextNode(`&lt;a> & &quot; '`); // 转换为: &quot;&lt;a> & &quot; &apos;&quot; ``` 3. **跨浏览器兼容** 处理不同浏览器(包括IE)的文本节点创建差异 #### 使用示例 ```javascript // 创建带文本的元素 const message = Strophe.xmlElement(&quot;message&quot;, [[&quot;to&quot;, &quot;user@example.com&quot;]], Strophe.xmlTextNode(&quot;消息内容&quot;) ); // 等价于XML结构 // &lt;message to=&quot;user@example.com&quot;>消息内容&lt;/message> ``` #### 实现原理 在Strophe源码中(参考[^1]),该函数的核心逻辑是: ```javascript xmlTextNode: function(text) { if (typeof text !== &quot;string&quot; && typeof text !== &quot;number&quot;) { throw new Error(&quot;Invalid text type&quot;); } return document.createTextNode(text.toString()); } ``` #### 典型应用场景 1. **消息内容插入** ```javascript const body = Strophe.xmlElement(&quot;body&quot;); body.appendChild(Strophe.xmlTextNode(&quot;你好,这是测试消息&quot;)); ``` 2. **动态内容构建** ```javascript const status = Strophe.xmlElement(&quot;status&quot;); status.appendChild( Strophe.xmlTextNode(`在线时间: ${new Date().toLocaleTimeString()}`) ); ``` 3. **安全内容转义** ```javascript const userInput = &quot;&lt;script>alert('xss&#39;)&lt;/script>&quot;; const safeNode = Strophe.xmlTextNode(userInput); // 自动转义为安全文本 ``` #### 注意事项 1. 仅接受字符串/数字参数,其他类型会抛出错误 2. 文本节点不能直接包含子元素 3. 与`xmlElement()`配合使用时注意DOM层级关系
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值