Po co robić input sanitization?

1

Od zawsze chyba wszystkie tutoriale, książki, kursy itd. o tym trąbiły, a właściwie po co robić sanityzować dane z wejścia?

Doszedłem do wniosku, że niewiele to daje i chciałbym się skonsultować :D

1

Trochę Rozwiń myśl, kiedy, w jakiej sytuacji, jakiś przykład, bo tak to szklana kula:)

0

@lion137:

W kontekście aplikacje webowych, formularzy, POSTów, itd.

Baz danych, jsonów, widoków htmlowych (server side rendered)

1

To, chociażby, ze względów bezpieczeństwa.

0

No ale jakiego?

6

Exploits of a Mom

0

@Wibowit:

W tych czasach chyba każde współczesne środowisko oferuje parametryzowanie zapytań oraz jeszcze pewnie więcej trików typu analiza AST zapytania, więc jak Ty chcesz ten sql injection robić?

0

Java ma PreparedStatement dostępne chyba od wersji 1.1 Javy wydanej w roku 1997, ale myślę, że do tej pory wiele SQLi jest klejonych ręcznie. Dzieje się tak np w spadkowej części systemu nad którym pracuję w firmie :]

0

@Wibowit:

Jeżeli chodzi o stare systemy to zgadzam się, że jest to konieczne, ale chodzi mi o współczesne, dojrzałe środowiska.

0

Myślę, że takie klejone SQLe będą się pojawiać i w nowych systemach, bo jeśli automatycznie wygenerowane zapytania są zbyt wolne, a ręcznie klejone są rozbite na wiele metod generujących poszczególne elementy zapytania to komuś może się nie chcieć pakować w PreparedStatement. Np:

val part1 = "column1 = $arg1"
val part2 = "column2 = $arg2"
// partów jest 10
val query =
  if (abc == xyz) {
    "select a from b where $part1 and $part3 and $part5"
  } else if (qwe == rty) {
    "select a from b where $part3 and $part8"
  } else {
    "select a from b where $part4 and $part9 union select c from d where $part1 and $part9"
  }

Zamiana tego na PreparedStatement jest możliwa, ale czy ktoś ją zrobi?

Oprócz SQL injection mamy np:

  • cross site scripting
  • lewe tokeny uwierzytelniające (np JWT ma tryb bez podpisu i bez szyfrowania - trzeba to jawnie odrzucać)
  • ścieżki do plików - ktoś może np zażądać pliku http://server.abc/assets/../../../../..//etc/passwd, a my mapujemy sobie własnym mapperem /assets/<path> na np /home/user/app/static/<path> i już nieszczęście gotowe
  • denial of service - dla przykładu możesz udostępnić język zapytań (taki jak tu na forum na przykład do wyszukiwania postów), a ktoś zrobi zapytanie na 5 megabajtów i zajedzie ci bazkę

Poza tym wczesne sprawdzenie poprawności danych pozwala w ogólności uniknąć niepotrzebnego mielenia danych. Jeśli od razu widać, że dane są złe to pchanie ich po całym systemie narobi niepotrzebnego ruchu, exceptionów, itd

Wszystko w ramach potrzeb oczywiście. Jeśli masz super hiper framework który robi wszystko za ciebie to oczywiście nie musisz nic robić.

0

@Wibowit:

cross site scripting

Brak sanityzacji nie implikuje braku escapowania na wyjściu

lewe tokeny uwierzytelniające (np JWT ma tryb bez podpisu i bez szyfrowania - trzeba to jawnie odrzucać)

nie wiem

ścieżki do plików - ktoś może np zażądać pliku http://server.abc/assets/../../../../..//etc/passwd, a my mapujemy sobie własnym mapperem /assets/<path> na np /home/user/app/static/<path> i już nieszczęście gotowe

no faktycznie, jeżeli ktoś takie coś robi, to jest możliwy wektor ataku, no ale kto w taki sposób to realizuje xD

denial of service - dla przykładu możesz udostępnić język zapytań (taki jak tu na forum na przykład do wyszukiwania postów), a ktoś zrobi zapytanie na 5 megabajtów i zajedzie ci bazkę

ale input sanitization to nie to samo co input validation i w sumie to też dotyczy tego przykładu z plikami.

Walidacja mogłaby polegać na sprawdzeniu czy path składa się tylko z literek i cyfr np. obrazek123 albo id pliku 5223abcd

0

Czym się różni input sanitization od walidacji?

0

@danek:

What Is Input Validation and Sanitization?

Validation checks if the input meets a set of criteria (such as a string contains no standalone single quotation marks).

Sanitization modifies the input to ensure that it is valid (such as doubling single quotes).

Sanityzacja = np. escapowanie znaczków "abc" => \"abc\"

Walidacja = np. sensowne dane np. PESEL o długości 1 znak => do odrzucenia.

2

Oh sweet summer child... I jeszcze ta ślepa wiara w W tych czasach chyba każde współczesne środowisko oferuje parametryzowanie zapytań oraz jeszcze pewnie więcej trików typu analiza AST zapytania, więc jak Ty chcesz ten sql injection robić? :D

Zobacz sobie: oraz i może jeszcze ;)

0

Dość często kleję ręcznie URLe, jeśli chodzi o zapytania GET. Są na to jakieś ciekawe exploity? Taki URL może zawierać np dane wyciągnięte z bazy.

0

@Shalom:

To teraz pytanie

Czy na całą aplikacje webową nakładacie jakiś globalny filtr, który escapuje wam każdego stringa?

A później te escapnięte stringi trzymacie bazie? np San José => San Jos\u00E9?

Przecież takie dane są mega problematyczne do działania na.

0

Zamiast dodatkowego escape'owania można zrobić whitelistę znaków.

0

@Wibowit:

I w każdym miejscu, dla każdego inputu robisz coś takiego?

Ewentualnie jakiś global http request filter?

@Controller
@RequestMapping("/kontroler")
public class KotyController {

	@RequestMapping("/metoda")
	public String metoda(Input data) {
		if (!WhiteListCheck(data))
		{
			return err;
		}
	}
	
	public bool WhiteListCheck(object something){
		// pseudo code i to bardzo
		
		foreach property in something
			if typeof(property) == string
				if (!WhiteListValueCheck(property.Value))
					return false

		return true;
	}
	
	private bool WhiteListValueCheck(string value){
		char[] allowedChars = new char[]{'a', 'b');
		
		foreach char in value
			if char not in allowedChars
				return false;

		return true;			
	}	
}

public class Input{
	public string FirstName { get; set; }
	public string Address { get; set; }
	public string PhoneNumber { get; set; }
	public string Description { get; set; }
}


2

@WeiXiao o panie z unikodem to nie ma żartów, widziałem kiedyś wybuch bazy na produkcji z tym związany, bo tabela miała ustawione chyba to śmieszne 3bajtowe kodowanie unicode w mysqlu/mariadb (które się nazywa mylnie utf8) a aplikacja w konektorze mówiła że jest utf-8 no i ktoś wrzucił sobie emoji gdzieś a takie emoji to 4 bajtowy unicode... ;]

0

@Shalom:

Co do tego XSSa

Masz jakieś api, które z bazy zwraca ten nasz niefortunny <noscript><p title="</noscript><img src=x onerror=alert(1)>">, który normalnie się wykona i walnie alert

(nawet z tym escapem taki kod <noscript><p title=\"</noscript><img src=x onerror=alert(1)>\"> się wykona, ale mniejsza z tym)

no i zazwyczaj takie dane są wyrzucane do użytkownika jakimś np. Angularem i rozważmy taki kod:

<!doctype html>
<html ng-app>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.min.js"></script>
  </head>
  <body>
    <div>
      <label>Name:</label>
      <input type="text" ng-model="yourName" placeholder="Enter a name here">
      <hr>
      <h1>Hello {{yourName}}!</h1>
    </div>
  </body>
</html>

https://jsfiddle.net/d2evhorb/

I jeżeli wrzucisz tam ten swój xss <noscript><p title="</noscript><img src=x onerror=alert(1)>">, to wyświetli się on jako napis bo Angular też escapuje https://docs.angularjs.org/api/ngSanitize/service/$sanitize

więc gdzie gdzie problem przy takim współczesnym stacku?

edit: OPS, przecież jsa i tak by nie wykonał przy takim wstrzyknięciu (bo to nie refresh strony), nawet bez escape, ale z drugiej strony można przetestować na <i> test </i>, który i tak nie zostanie wyrenderowany w w/w Angularowym kodzie, a tu zostanie:

<div id="1">

</div>

<button onclick="html_inject()">

</button>

<script>
function html_inject()
{
	document.getElementById("1").innerHTML = "<i> test </i>";
}
</script>
0

@WeiXiao: nawet jak masz prepared statements to jesteś w stanie zrobić kiszkę bardzo łatwo - SELECT id FROM foos WHERE name ILIKE ? gdzie ktoś Ci poda jako parametr %%du%pa%% i potrafi to całkiem brutalnie zarżnąć DB. Więc w ogólności to nie jest takie proste by zabezpieczyć się przed wszystkim przy pomocy samej tylko sanityzacji(?) wejścia. Injection attacks to nie jedyne problemy jakie można napotkać jak "ślepo" akceptujemy dane od użyszkodników, może być DoS (jak pokazane wyżej) lub przejęcie kont.

0

Można tworzyć różne mechanizmy które np. mierzą czas wykonania zapytania i

a) logują

b) powyżej jakiegoś threshold banują usera.

1
WeiXiao napisał(a):

Można tworzyć różne mechanizmy które np. mierzą czas wykonania zapytania i

a) logują

b) powyżej jakiegoś threshold banują usera.

Piszesz tak jakbyś nigdy włamu na swoją stronę nie doświadczył.

1
WeiXiao napisał(a):

Można tworzyć różne mechanizmy które np. mierzą czas wykonania zapytania i

a) logują

b) powyżej jakiegoś threshold banują usera.

A co to da w sytuacji, gdy ktoś już narobi dziadostwa? Zbanować możesz, ale jak już ktoś zdąży wywrócić Ci bazę i udławić serwer to takim wymierzaniem sprawiedliwości szkód nie naprawisz :P

0

To ja wracam do mojego pytania z poprzedniej strony

Czy w każdym miejscu gdzie przychodzi wam jakiś input z zewnątrz robicie jakieś input.FirstName = Escape(input.FirstName)?

Czy może jakiś globalny filtr na każdy przesłany string?

0

Ani jedno ani drugie, bo wszystko zależy jak będziesz tego używał. Bo w każdym przypadku sposób użycia będzie inny (a czasem nie musisz tego robić wcale bo np. używasz prepared statement i masz same "bezpieczne" zapytania).

0

Warto też zerknąć na: https://sekurak.pl/czym-jest-xss/

0

O, widzę że ktoś zebrał w końcu definicje co jest czym ;)

Sanitizing vs Validating vs Escaping vs Filtering

https://kevinsmith.io/sanitize-your-inputs/

1

jak już odgrzebujemy to warto wiedzieć.
filtrowanie inputu można robić

ale to filtrowanie/eskejpowanie outputu jest konieczne

https://benhoyt.com/writings/dont-sanitize-do-escape/

0

@jarekr000000:

poza przykładem z parsowaniem markdownu, to coś tam jeszcze doszło?

i to właśnie parsowanie markdowna rozumiesz jako filtrowanie outputu?

eskejpowanie outputu to też jest niezbyt precyzyjne, bo ktoś może zrozumieć że ten kto wyrzuca dane ma to zrobić, a to ma client zrobić.

bo przecież backend zazwyczaj nie wie czy to e.g appka desktopowa wysyła żądanie, która ma wywalone na jakiegoś jsa czy htmla, czy stronka.

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