Skip to content

Commit f7d86a1

Browse files
committed
update JsonLdScriptEncoding
1 parent 370d074 commit f7d86a1

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

Razor.Blade/Internals/ReplaceExtension.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,26 @@ public static class ReplaceExtension
99
/// <summary>
1010
/// Returns a new string in which all occurrences of a specified string in the current instance are replaced with another specified string.
1111
/// This is to be used in .NET Framework or .netstandard 2.0 because .NET 5+ already has this string.Replace() method
12-
/// https://stackoverflow.com/a/36317315
12+
/// based on https://stackoverflow.com/a/36317315
1313
/// </summary>
1414
/// <param name="str">The string performing the replace method.</param>
15+
/// <param name="find">The string find.</param>
1516
/// <param name="oldValue">The string to be replaced.</param>
1617
/// <param name="newValue">The string replace all occurrences of oldValue.</param>
1718
/// <param name="comparisonType">Type of the comparison.</param>
1819
/// <returns></returns>
19-
public static string Replace(this string str, string oldValue, string newValue, StringComparison comparisonType)
20+
public static string Replace(this string str, string find, string oldValue, string newValue, StringComparison comparisonType)
2021
{
2122
newValue = newValue ?? string.Empty;
22-
if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(oldValue) || oldValue.Equals(newValue, comparisonType))
23-
{
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)
2427
return str;
25-
}
2628
int foundAt;
27-
while ((foundAt = str.IndexOf(oldValue, 0, comparisonType)) != -1)
29+
while ((foundAt = str.IndexOf(find, 0, comparisonType)) != -1)
2830
{
29-
str = str.Remove(foundAt, oldValue.Length).Insert(foundAt, newValue);
31+
str = str.Remove(foundAt + findOffset, oldValue.Length).Insert(foundAt + findOffset, newValue);
3032
}
3133
return str;
3234
}

Razor.Blade/Wip/XssPrevention.cs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ namespace ToSic.Razor.Wip
88
/// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
99
/// https://cheatsheetseries.owasp.org/cheatsheets/DotNet_Security_Cheat_Sheet.html#a7-cross-site-scripting-xss
1010
/// </summary>
11-
internal class XssPrevention
11+
public class XssPrevention
1212
{
1313
/// <summary>
14-
/// Output Encoding for "JSON-LD Context"
14+
/// Output Encoding for "JSON-LD Contexts"
1515
/// https://w3c.github.io/json-ld-syntax/#restrictions-for-contents-of-json-ld-script-elements
1616
/// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-javascript-contexts
1717
/// Authors should avoid using character sequences in scripts embedded in HTML which may be confused with a
@@ -20,14 +20,11 @@ internal class XssPrevention
2020
/// </summary>
2121
/// <param name="unsafeJsonLd"></param>
2222
/// <returns></returns>
23-
internal static string JsonLdScriptEncoding(string unsafeJsonLd) => unsafeJsonLd
24-
.Replace("<!--", @"\u003C!--", StringComparison.OrdinalIgnoreCase)
25-
.Replace("<script", @"\u003Cscript", StringComparison.OrdinalIgnoreCase)
26-
.Replace("-->", @"--\u003E", StringComparison.OrdinalIgnoreCase)
27-
// TODO @STV: use </script and NOT </script> - the closing tag can be much later
28-
// also write a test to verify
29-
// and also a test to verify different script cases
30-
.Replace("</script>", @"\u003C/script>", StringComparison.OrdinalIgnoreCase);
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);
3128

3229
///// <summary>
3330
///// Output Encoding for "HTML Contexts"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using ToSic.Razor.Wip;
3+
4+
namespace ToSic.RazorBladeTests.WIP
5+
{
6+
[TestClass]
7+
public class XssPreventionTests
8+
{
9+
[TestMethod]
10+
[DataRow("<script>alert('xss')</script><!-- html comment -->", @"\u003Cscript>alert('xss')\u003C/script>\u003C!-- html comment --\u003E")]
11+
[DataRow(null, null)]
12+
[DataRow("", "")]
13+
[DataRow("nothing to do", "nothing to do")]
14+
[DataRow("</script", "\\u003C/script")]
15+
[DataRow("</scriptnewtag", "\\u003C/scriptnewtag")]
16+
[DataRow("</ScRiPt>", "\\u003C/ScRiPt>")]
17+
[DataRow("</script >", "\\u003C/script >")]
18+
[DataRow(" </script", " \\u003C/script")]
19+
[DataRow("\n</script\n\t>", "\n\\u003C/script\n\t>")]
20+
[DataRow("<<<</script", "<<<\\u003C/script")]
21+
[DataRow("<><></script", "<><>\\u003C/script")]
22+
[DataRow("</ script >", "</ script >")]
23+
[DataRow("< / script >", "< / script >")]
24+
[DataRow("-->", "--\\u003E")]
25+
[DataRow("-->>", "--\\u003E>")]
26+
[DataRow("<-->>", "<--\\u003E>")]
27+
[DataRow("-- >", "-- >")]
28+
[DataRow(" --\t\n>\n ", " --\t\n>\n ")]
29+
public void JsonLdScriptEncoding(string content, string expected) => Assert.AreEqual(expected, XssPrevention.JsonLdScriptEncoding(content));
30+
}
31+
}

0 commit comments

Comments
 (0)