W jaki sposób XSS jest tutaj negowany?

0

Tak trochę nawiązując do posta @Wibowita https://4programmers.net/Forum/1583932

Mam jakiś prawie pusty widok Index.cshtml, a w nim button do wysłania GETa na serwer, który zwraca View jako string, oraz diva do wstrzyknięcia tego stringa.

Wstrzykiwanie:

document.getElementById("Injectable").innerHTML = response;

Index.cshtml

<button onclick="xss()">Inject html</button>

<div id="Injectable">

</div>

Tutaj kod XSS.cshtml którego renderuje i zwracam jako string do w/w GETa i wstrzykuje w diva Injectable

@{
    Layout = "";
}

<script>
    alert('XSSdd')
</script>


<b>test</b>
<img src="https://www.w3schools.com/html/pic_trulli.jpg" alt="Italian Trulli">

I ku mojemu zdziwieniu b oraz img są poprawnie renderowane, a script się nie wykonuje

Dlaczego? jeżeli w zwrotce z kontrolera jest:

<script>
alert('XSSdd')
</script>
<b>test</b>

<img src="https://www.w3schools.com/html/pic_trulli.jpg" alt="Italian Trulli">

Przechwytywanie.PNG

W ogóle jak jest z bezpieczeństwem takiego rozwiązania?

0

Jeżeli chodzi o bezpieczeństwo to już chyba łapie
HTML z XSS.cshtml nie jest escapowany, ale parametry wrzucone do tego View już są

public async Task<IActionResult> GetHTML()
{
	string url = @"https://www.w3schools.com/html/pic_trulli.jpg";

	string xss = @"
				<script>
					alert('XSSdd')
				</script>
				";

	string somehtml = @"<b>sometext</b>";

	var s = await this.RenderViewAsync("XSS", (url, xss, somehtml));

	return Content(s, "text/html");
}
@model (string url, string xss, string somehtml)
@{
Layout = "";
}

@Model.xss

@Model.somehtml

<img src="@Model.url" alt="Italian Trulli">

Wynik:


                        <script>

                            alert('XSSdd')

                   </script>
                   

<b>sometext</b>

<img src="https://www.w3schools.com/html/pic_trulli.jpg" alt="Italian Trulli">

xss2.PNG

ale dlaczego w 1 poście ten alert nie jest wkonywany?

1

Pewnie dlatego, że skrypty wykonują się podczas ładowania DOM przez przeglądarkę (lub zaraz po jego załadowaniu). Przy wczytaniu html z partiala za pomocą ajaxa nic takiego się nie dzieje. Równie dobrze, mógłbyś w źródłach strony wkleić ten kawałek i efekt będzie taki sam. Czyli nic

0

@szydlak:

Czyli można uznać, że tak długo jak wstawiamy wszystko przez parametry, aby zostało escapnięte, to nie ma żadnego niebezpieczeństwa przy takim wstrzykiwaniu htmla?

1

Szczerze powiedziawszy to nie wiem. W maju mam zaplanowane szkolenie z bezpieczeństwa aplikacji webowych (Niebezpiecznik) więc pewnie dowiem się coś więcej :p

1

I ku mojemu zdziwieniu b oraz img są poprawnie renderowane, a script się nie wykonuje

Kod javascript nie jest wykonywany w momencie wstrzyknięcia go, jeśli użyjemy do tego innerHtml.

Jeśli chodzi o renderowanie tekstu za pomocą razora, to razor domyślnie koduje tekst HTMLowy

1

zamiast

<script>
    alert('XSSd')
</script>

wstrzyknij to :):

<img src="bububububububbbbb" onerror="javascript:alert('xss :D');">
panDawid napisał(a):

Kod javascript nie jest wykonywany w momencie wstrzyknięcia go, jeśli użyjemy do tego innerHtml.

nieprawda, pełny przykład:

 <!DOCTYPE html>
<html>
<body>

<h1>My First Heading</h1>
<p></p>

<div id="Injectable">

</div>

<script>
document.getElementById("Injectable").innerHTML = "<img src=\"bububububububbbbb\" onerror=\"javascript:alert('xss :D');\">";

</script>
</body>
</html> 
0

@neves:

Nie działa, jest escapnięty bo jest wkładany jako parametr do tego View

string xss = "<img src=\"bububububububbbbb\" onerror=\"javascript: alert('xss :D');\">";

string xss = "<img src='bububububububbbbb' onerror='javascript: alert('xss :D');'>";

xss3.PNG

7.PNG

xss6.PNG

8.PNG

0
panDawid napisał(a):

Kod javascript nie jest wykonywany w momencie wstrzyknięcia go, jeśli użyjemy do tego innerHtml.

nieprawda, pełny przykład:

 <!DOCTYPE html>
<html>
<body>

<h1>My First Heading</h1>
<p></p>

<div id="Injectable">

</div>

<script>
document.getElementById("Injectable").innerHTML = "<img src=\"bububububububbbbb\" onerror=\"javascript:alert('xss :D');\">";

</script>
</body>
</html> 

Racja, źle się wyraziłem. Kod, który jest między znacznikami <script> </script> nie jest wykonywany. Generalnie zamiast innerHtml zalecałbym używanie html()

1

Także jak chcesz spać spokojnie po nocy, to trzeba ustawić restrykcyjne CSP, tak żeby inlinowane rzeczy nie były wykonywane, a pliki wczytywane tylko z pewnych źródeł, w net core np w ten sposób + kilka innych nagłówków które też warto ustawić:

app.Use(async (context, nextMiddleware) =>
{
    context.Response.OnStarting(() =>
    {
        if (env.IsDevelopment())
        {
            // In devlopemnt React add-on to browser requires script-src set to unsafe-inline
            //               React-Hot-Loader requires script-src set to unsafe-eval
            //               Webpack requires style-src set to unsafe-inline
            context.Response.Headers.Add("Content-Security-Policy", "default-src 'self'; connect-src localhost:* wss://localhost:*; font-src data:; img-src * data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.googletagmanager.com *.google-analytics.com;  style-src 'self' 'unsafe-inline';");
        }
        else
        {
            context.Response.Headers.Add("Content-Security-Policy", "default-src 'self'; connect-src localhost:* wss://localhost:*; font-src data:; img-src * data:; script-src 'self' *.googletagmanager.com *.google-analytics.com;  style-src 'self';");
        }
        context.Response.Headers.Add("X-Frame-Options", "deny");
        context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
        context.Response.Headers.Add("Referrer-Policy", "same-origin");
        context.Response.Headers.Add("X-Xss-Protection", "1; mode=block");

        return Task.CompletedTask;
    });
    await nextMiddleware();
});

1 użytkowników online, w tym zalogowanych: 0, gości: 1