Niewłaściwy encoding #2

Po pierwszym przykładzie niewłaściwego encodingu, pora na drugi. Dla analogicznego jak w pierwszym przypadku zestawu znaków:

!“#$%25&'()*+,–./:;<=>?@[]^_`{|}~

na wyjściu otrzymuje się:

demo 2

Jak łatwo zauważyć, jedyną różnicą w stosunku do poprzedniego przypadku jest dodatkowe kodowanie znaku “. Dobrze to widać, jeśli oba przypadki zestawi się ze sobą:

demo 1
demo 2

Można się domyślić, że problemu z XSS w tym kontekście ta zmiana raczej nie rozwiązuje.

Co wynika z tej różnicy? Głównie to, że nie można już uciec z kontekstu atrybutu, ponieważ potrzebny do tego znak “ jest kodowany do postaci ". Kodowanie znaku “ w takim kontekście jest w zasadzie skuteczne, choć Mario Heiderich pokazywał przypadki, w których ucieczka z kontekstu atrybutu była możliwa.

W tym przypadku istotne jest głównie to, że wewnątrz atrybutu HTML mamy kod JavaScript. A to oznacza, że dla najbardziej trywialnego payloadu:

'+alert(/xss/)+'

na wyjściu otrzymuje się:

demo 2

W tym przypadku znak ' nie jest kodowany. Nawet jeśli byłby zamieniany na encję HTML, w tym przypadku ', to i tak nie zmieniłoby to niczego. Można posłużyć się takim przykładem (zamiast encji HTML jeszcze inny, prawidłowy w kontekście HTML encoding):

Click!

Dokładnie ten kod znajduje się poniżej, co się stanie po kliknięciu każdy może sprawdzić sam (swoją drogą ciekawe, czy przez Google Reader ten przykład przejdzie, spodziewam się, że nie):

Click!

Dlaczego to działa? Mówiąc najbardziej ogólnie – dlatego, że encoding HTML jest “ściągany” przez przeglądarkę, w związku z tym coś, co w kodzie strony wygląda tak:

przez przeglądarkę (po sparsowaniu) jest widziane tak:

Jak widać encoding, który nie pozwala na “ucieczkę” z atrybutu HTML wcale nie gwarantuje tego, że wewnątrz tego atrybutu czegoś złego nie uda się umieścić.

Oryginał tego wpisu dostępny jest pod adresem Niewłaściwy encoding #2

Autor: Paweł Goleń