Skip to content

Commit 6713ba5

Browse files
committed
Merge branch 'release/v03.13'
2 parents 76a6c61 + f7d86a1 commit 6713ba5

File tree

11 files changed

+215
-8
lines changed

11 files changed

+215
-8
lines changed

Razor.Blade/Html5/Script.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace ToSic.Razor.Html5
1+
using ToSic.Razor.Wip;
2+
3+
namespace ToSic.Razor.Html5
24
{
35
/// <summary>
46
/// Special tag for generating JsonLd markup
@@ -12,7 +14,10 @@ public class ScriptJsonLd : Script
1214
public ScriptJsonLd(string content)
1315
{
1416
Type("application/ld+json");
15-
TagContents = content;
17+
// https://w3c.github.io/json-ld-syntax/#restrictions-for-contents-of-json-ld-script-elements
18+
// Authors should avoid using character sequences in scripts embedded in HTML which may be confused
19+
// with a comment-open, script-open, comment-close, or script-close.
20+
TagContents = XssPrevention.JsonLdScriptEncoding(content);
1621
}
1722

1823
/// <summary>

Razor.Blade/Internals/Html.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
24
using System.Net;
35
#if NET5_0_OR_GREATER
46
using System.Text.Json;
@@ -17,7 +19,7 @@ internal static string Encode(string value)
1719
=> WebUtility.HtmlEncode(value)
1820
?.Replace("&#39;", "&apos;");
1921

20-
22+
2123
/// <summary>
2224
/// Internal string-based commands to keep data simple till ready for output
2325
/// </summary>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace ToSic.Razor.Internals
6+
{
7+
public static class ReplaceExtension
8+
{
9+
/// <summary>
10+
/// Returns a new string in which all occurrences of a specified string in the current instance are replaced with another specified string.
11+
/// This is to be used in .NET Framework or .netstandard 2.0 because .NET 5+ already has this string.Replace() method
12+
/// based on https://stackoverflow.com/a/36317315
13+
/// </summary>
14+
/// <param name="str">The string performing the replace method.</param>
15+
/// <param name="find">The string find.</param>
16+
/// <param name="oldValue">The string to be replaced.</param>
17+
/// <param name="newValue">The string replace all occurrences of oldValue.</param>
18+
/// <param name="comparisonType">Type of the comparison.</param>
19+
/// <returns></returns>
20+
public static string Replace(this string str, string find, string oldValue, string newValue, StringComparison comparisonType)
21+
{
22+
newValue = newValue ?? string.Empty;
23+
if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(find) || string.IsNullOrEmpty(oldValue) || oldValue.Equals(newValue, comparisonType))
24+
return str;
25+
var findOffset = find.IndexOf(oldValue, 0, comparisonType);
26+
if (findOffset < 0)
27+
return str;
28+
int foundAt;
29+
while ((foundAt = str.IndexOf(find, 0, comparisonType)) != -1)
30+
{
31+
str = str.Remove(foundAt + findOffset, oldValue.Length).Insert(foundAt + findOffset, newValue);
32+
}
33+
return str;
34+
}
35+
}
36+
}

Razor.Blade/Razor.Blade.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net472;net5.0</TargetFrameworks>
55
<RootNamespace>ToSic.Razor</RootNamespace>
6-
<Version>03.11.00</Version>
6+
<Version>03.13.00</Version>
77
<AssemblyName>ToSic.Razor</AssemblyName>
88
<PackageId>ToSic.Razor</PackageId>
99
<Authors>ToSic.Razor</Authors>
@@ -36,7 +36,7 @@
3636
<Reference Include="System.Web" />
3737
<Reference Include="System.Web.Extensions" />
3838
<PackageReference Include="Microsoft.Extensions.DependencyInjection">
39-
<Version>2.2.0</Version>
39+
<Version>2.1.1</Version>
4040
</PackageReference>
4141
</ItemGroup>
4242

Razor.Blade/Wip/XssPrevention.cs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System;
2+
using ToSic.Razor.Internals;
3+
4+
namespace ToSic.Razor.Wip
5+
{
6+
/// <summary>
7+
/// TODO: WIP
8+
/// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
9+
/// https://cheatsheetseries.owasp.org/cheatsheets/DotNet_Security_Cheat_Sheet.html#a7-cross-site-scripting-xss
10+
/// </summary>
11+
public class XssPrevention
12+
{
13+
/// <summary>
14+
/// Output Encoding for "JSON-LD Contexts"
15+
/// https://w3c.github.io/json-ld-syntax/#restrictions-for-contents-of-json-ld-script-elements
16+
/// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-javascript-contexts
17+
/// Authors should avoid using character sequences in scripts embedded in HTML which may be confused with a
18+
/// comment-open, script-open, comment-close, or script-close.
19+
/// Partial encode < and > characters with the \uXXXX unicode encoding format (X = Integer).
20+
/// </summary>
21+
/// <param name="unsafeJsonLd"></param>
22+
/// <returns></returns>
23+
public static string JsonLdScriptEncoding(string unsafeJsonLd) => unsafeJsonLd
24+
.Replace("<!--", "<", @"\u003C", StringComparison.OrdinalIgnoreCase)
25+
.Replace("<script", "<", @"\u003C", StringComparison.OrdinalIgnoreCase)
26+
.Replace("-->", ">", @"\u003E", StringComparison.OrdinalIgnoreCase)
27+
.Replace("</script", "<", @"\u003C", StringComparison.OrdinalIgnoreCase);
28+
29+
///// <summary>
30+
///// Output Encoding for "HTML Contexts"
31+
///// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-html-contexts
32+
///// Convert & to &amp;
33+
///// Convert < to &lt;
34+
///// Convert > to &gt;
35+
///// Convert " to &quot;
36+
///// Convert ' to &#x27;
37+
///// Convert / to &#x2F;
38+
///// </summary>
39+
///// <param name="unsafeHtml"></param>
40+
///// <returns></returns>
41+
//internal static string HtmlEntityEncoding(string unsafeHtml) => unsafeHtml
42+
// .Replace("&", "&amp;") // TODO: encode & only in case that unsafeHtml is not already entity encoded
43+
// .Replace("<", "&lt;")
44+
// .Replace(">", "&gt;")
45+
// .Replace("\"", "&quot;")
46+
// .Replace("'", "&apos;");
47+
48+
///// <summary>
49+
///// TODO: Output Encoding for "HTML Attribute Contexts"
50+
///// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-html-attribute-contexts
51+
///// Except for alphanumeric characters, encode all characters with the
52+
///// HTML Entity &#xHH; format, including spaces. (HH = Hex Value)
53+
///// </summary>
54+
///// <param name="unsafeAttributeValue"></param>
55+
///// <returns></returns>
56+
//internal static string HtmlAttributeEncoding(string unsafeAttributeValue) => unsafeAttributeValue;
57+
58+
///// <summary>
59+
///// TODO: Output Encoding for "URL Contexts"
60+
///// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-url-contexts
61+
///// Standard percent encoding. URL encoding should only be used to encode parameter values,
62+
///// not the entire URL or path fragments of a URL.
63+
///// </summary>
64+
///// <param name="unsafeParameterValue"></param>
65+
///// <returns></returns>
66+
//internal static string UrlParameterEncoding(string unsafeParameterValue) => unsafeParameterValue;
67+
68+
///// <summary>
69+
///// TODO: Output Encoding for "JavaScript Contexts"
70+
///// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-javascript-contexts
71+
///// Except for alphanumeric characters, encode all characters with the
72+
///// \uXXXX unicode encoding format (X = Integer).
73+
///// </summary>
74+
///// <param name="unsafeJavaScript"></param>
75+
///// <returns></returns>
76+
//internal static string JavaScriptEncoding(string unsafeJavaScript) => unsafeJavaScript;
77+
78+
///// <summary>
79+
///// TODO: Output Encoding for "CSS Contexts"
80+
///// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-css-contexts
81+
///// CSS encoding supports \XX and \XXXXXX. Using a two character encode can cause problems if
82+
///// the next character continues the encode sequence. There are two solutions:
83+
///// (a) Add a space after the CSS encode (will be ignored by the CSS parser)
84+
///// (b) use the full amount of CSS encoding possible by zero padding the value.
85+
///// </summary>
86+
///// <param name="unsafeCss"></param>
87+
///// <returns></returns>
88+
//internal static string CssHexEncoding(string unsafeCss) => unsafeCss;
89+
}
90+
}

ToSic.Razor.Dnn/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@
3030
//
3131
// You can specify all the values or you can default the Revision and Build Numbers
3232
// by using the '*' as shown below:
33-
[assembly: AssemblyVersion("03.11.0.00")]
34-
[assembly: AssemblyFileVersion("03.11.0.00")]
33+
[assembly: AssemblyVersion("03.13.0.00")]
34+
[assembly: AssemblyFileVersion("03.13.0.00")]

ToSic.Razor.Dnn/ToSic_Razor_Blade_Dnn.dnn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<dotnetnuke type="Package" version="5.0">
22
<packages>
3-
<package name="ToSic.RazorBlade" type="Library" version="03.11.00">
3+
<package name="ToSic.RazorBlade" type="Library" version="03.13.00">
44
<friendlyName>2sic RazorBlade</friendlyName>
55
<description>2sic RazorBlade</description>
66
<iconFile>icon.png</iconFile>

ToSic.RazorBladeTests/HtmlTagsTests/ImgTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ public void ImgWithUmlaut()
4242
public void ImgWithUmlautAndResizer()
4343
=> Is("<img src='L%C3%A9onie%20M%C3%BCller.jpg?w=17'>", Tag.Img().Src("Léonie Müller.jpg?w=17"));
4444

45+
[TestMethod]
46+
public void ImgWithMultipleParamsShouldConvertAmp()
47+
=> Is("<img src='test.jpg?w=100&amp;h=100'>", Tag.Img().Src("test.jpg?w=100&h=100"));
48+
4549

4650
[TestMethod]
4751
public void ImgSizes()

ToSic.RazorBladeTests/HtmlTagsTests/Script_JsonLdTests.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,36 @@ public void JsonLdObject()
2424
new ScriptJsonLd(new { key = "value" }));
2525
}
2626

27+
//[TestMethod]
28+
//public void JsonLdStringXssExists()
29+
//{
30+
// Is("<script type='application/ld+json'>{\"key\":\"</script>\"}</script>",
31+
// new ScriptJsonLd("{\"key\":\"</script>\"}"));
32+
//}
33+
34+
[TestMethod]
35+
public void ValidJsonLdString()
36+
{
37+
Is("<script type='application/ld+json'>{ \"name\": \"Jane Doe\", \"@context\": \"http://schema.org/\", \"@type\": \"Person\" }</script>",
38+
new ScriptJsonLd("{ \"name\": \"Jane Doe\", \"@context\": \"http://schema.org/\", \"@type\": \"Person\" }"));
39+
}
40+
41+
[TestMethod]
42+
public void ValidJsonLdStringWithXss()
43+
{
44+
Is("<script type='application/ld+json'>{ \"name\": \"\\u003C/script>\\u003Cscript>\", \"@context\": \"http://schema.org/\", \"@type\": \"Person\" }</script>",
45+
new ScriptJsonLd("{ \"name\": \"</script><script>\", \"@context\": \"http://schema.org/\", \"@type\": \"Person\" }"));
46+
Is("<script type='application/ld+json'>{ \"name\": \"\\u003C!-- html comment --\\u003E\", \"@context\": \"http://schema.org/\", \"@type\": \"Person\" }</script>",
47+
new ScriptJsonLd("{ \"name\": \"<!-- html comment -->\", \"@context\": \"http://schema.org/\", \"@type\": \"Person\" }"));
48+
}
49+
50+
[TestMethod]
51+
public void JsonLdObjectWithXss()
52+
{
53+
Is("<script type='application/ld+json'>{\"name\":\"\\u003C/script>\\u003Cscript>\"}</script>",
54+
new ScriptJsonLd(new { name = "</script><script>" }));
55+
Is("<script type='application/ld+json'>{\"name\":\"\\u003C!-- html comment --\\u003E\"}</script>",
56+
new ScriptJsonLd(new { name = "<!-- html comment -->" }));
57+
}
2758
}
2859
}

ToSic.RazorBladeTests/TagTests/TagTestBase.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Linq;
22
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using Newtonsoft.Json;
34
using ToSic.Razor.Blade;
45
using ToSic.Razor.Html5;
56
using ToSic.Razor.Markup;
@@ -11,6 +12,13 @@ namespace ToSic.RazorBladeTests.TagTests
1112
public class TagTestBase
1213

1314
{
15+
public TagTestBase()
16+
{
17+
// setup use of Newtonsoft.Json for serialization to
18+
// ensure same behavior in tests as in 2sxc
19+
Razor.StartUp.StartUp.RegisterToJson(JsonConvert.SerializeObject);
20+
}
21+
1422
public void Is(string expected, TagBase result, string message = null)
1523
{
1624
Is(expected, result.ToString(), message);

0 commit comments

Comments
 (0)