@@ -7,6 +7,24 @@ namespace EventLogExpert.UI.Tests.Services;
77
88public sealed class ReleaseNotesMarkdownRendererTests
99{
10+ [ Theory ]
11+ [ InlineData ( "[evil](javascript:alert(1))" ) ]
12+ [ InlineData ( "[evil](data:text/html,<script>)" ) ]
13+ [ InlineData ( "[evil](file:///etc/passwd)" ) ]
14+ [ InlineData ( "[evil](ftp://example.com)" ) ]
15+ public void RenderToHtml_AllLinkSchemes_StrippedToTextOnly ( string markdown )
16+ {
17+ var html = ReleaseNotesMarkdownRenderer . RenderToHtml ( markdown ) ;
18+
19+ Assert . DoesNotContain ( "<a " , html ) ;
20+ Assert . DoesNotContain ( "href=" , html ) ;
21+ Assert . DoesNotContain ( "javascript:" , html ) ;
22+ Assert . DoesNotContain ( "data:" , html ) ;
23+ Assert . DoesNotContain ( "file://" , html ) ;
24+ Assert . DoesNotContain ( "ftp://" , html ) ;
25+ Assert . Contains ( "evil" , html ) ;
26+ }
27+
1028 [ Fact ]
1129 public void RenderToHtml_BlankLineBetweenBullets_StartsNewList ( )
1230 {
@@ -106,19 +124,25 @@ public void RenderToHtml_Headings(string markdown, string expected)
106124 }
107125
108126 [ Fact ]
109- public void RenderToHtml_HttpLink_RendersAnchor ( )
127+ public void RenderToHtml_HttpLink_RendersTextOnlyWithoutAnchor ( )
110128 {
111129 var html = ReleaseNotesMarkdownRenderer . RenderToHtml ( "[link](http://example.com)" ) ;
112130
113- Assert . Contains ( "<a href=\" http://example.com\" " , html ) ;
131+ Assert . DoesNotContain ( "<a " , html ) ;
132+ Assert . DoesNotContain ( "href=" , html ) ;
133+ Assert . DoesNotContain ( "http://example.com" , html ) ;
134+ Assert . Contains ( "link" , html ) ;
114135 }
115136
116137 [ Fact ]
117- public void RenderToHtml_HttpsLink_RendersAnchor ( )
138+ public void RenderToHtml_HttpsLink_RendersTextOnlyWithoutAnchor ( )
118139 {
119140 var html = ReleaseNotesMarkdownRenderer . RenderToHtml ( "see [docs](https://example.com/page)" ) ;
120141
121- Assert . Contains ( "<a href=\" https://example.com/page\" target=\" _blank\" rel=\" noopener noreferrer\" >docs</a>" , html ) ;
142+ Assert . DoesNotContain ( "<a " , html ) ;
143+ Assert . DoesNotContain ( "href=" , html ) ;
144+ Assert . DoesNotContain ( "https://example.com/page" , html ) ;
145+ Assert . Contains ( "see docs" , html ) ;
122146 }
123147
124148 [ Fact ]
@@ -185,14 +209,14 @@ public void RenderToHtml_PlainTextLines_RenderAsParagraph()
185209 [ Theory ]
186210 [ InlineData ( "[xss](https://example.com\" onload=alert(1))" ) ]
187211 [ InlineData ( "[xss](https://example.com'onclick='alert(1))" ) ]
188- public void RenderToHtml_QuotesInUrl_AreEscapedNotInjected ( string markdown )
212+ public void RenderToHtml_QuotesInUrl_StrippedAlongWithUrl ( string markdown )
189213 {
190214 var html = ReleaseNotesMarkdownRenderer . RenderToHtml ( markdown ) ;
191215
192- Assert . DoesNotContain ( "\" onload=" , html ) ;
193- Assert . DoesNotContain ( "\" onload =" , html ) ;
194- Assert . DoesNotContain ( "\" onclick =" , html ) ;
195- Assert . DoesNotContain ( "'onclick= ", html ) ;
216+ Assert . DoesNotContain ( "onload=" , html ) ;
217+ Assert . DoesNotContain ( "onclick =" , html ) ;
218+ Assert . DoesNotContain ( "href =" , html ) ;
219+ Assert . Contains ( "xss ", html ) ;
196220 }
197221
198222 [ Fact ]
@@ -224,7 +248,9 @@ public void RenderToHtml_RichLayoutSample_RendersAllElements()
224248 Assert . Contains ( "<h3>Features</h3>" , html ) ;
225249 Assert . Contains ( "<h3>Bug Fixes</h3>" , html ) ;
226250 Assert . Contains ( "<strong>Column reordering</strong>" , html ) ;
227- Assert . Contains ( "<a href=\" https://example.com/docs\" " , html ) ;
251+ Assert . Contains ( "<li>Support for exported logs</li>" , html ) ;
252+ Assert . DoesNotContain ( "href=" , html ) ;
253+ Assert . DoesNotContain ( "https://example.com" , html ) ;
228254 Assert . Contains ( "<li>Fixed crash when opening empty file</li>" , html ) ;
229255 }
230256
@@ -263,24 +289,13 @@ public void RenderToHtml_UnmatchedBoldMarkers_LeftAsLiteral()
263289 Assert . Contains ( "**unclosed bold" , html ) ;
264290 }
265291
266- [ Theory ]
267- [ InlineData ( "[evil](javascript:alert(1))" ) ]
268- [ InlineData ( "[evil](data:text/html,<script>)" ) ]
269- [ InlineData ( "[evil](file:///etc/passwd)" ) ]
270- [ InlineData ( "[evil](ftp://example.com)" ) ]
271- public void RenderToHtml_UnsafeLinkSchemes_NotRenderedAsAnchor ( string markdown )
272- {
273- var html = ReleaseNotesMarkdownRenderer . RenderToHtml ( markdown ) ;
274-
275- Assert . DoesNotContain ( "<a " , html ) ;
276- Assert . DoesNotContain ( "href=" , html ) ;
277- }
278-
279292 [ Fact ]
280- public void RenderToHtml_UrlWithAmpersand_PreservesEscapedEntity ( )
293+ public void RenderToHtml_UrlWithAmpersand_NotRenderedInOutput ( )
281294 {
282295 var html = ReleaseNotesMarkdownRenderer . RenderToHtml ( "[link](https://example.com/path?a=1&b=2)" ) ;
283296
284- Assert . Contains ( "href=\" https://example.com/path?a=1&b=2\" " , html ) ;
297+ Assert . DoesNotContain ( "href=" , html ) ;
298+ Assert . DoesNotContain ( "https://example.com" , html ) ;
299+ Assert . Contains ( "link" , html ) ;
285300 }
286301}
0 commit comments