» »

Inline JS v HTML; varnost, XSS, ...

Inline JS v HTML; varnost, XSS, ...

HotBurek ::

Evo, ideja je, da ko klient naredi HTTP GET request za HTML vsebino, strežnik dinamično doda JS vsebino v sam HTML file. Tako klient naredi samo en request, v keterem dobi HTML+JS.

Zasledil sem sicer opcijo, kjer to omogoča že web strežnik ( https://www.modpagespeed.com/doc/filter... ). Sam bom to sicer rešil programsko.

So pa včeraj na okno prišle sinice (kdo bi si mislil, ane), in so čivkale, da je tako početje (JS inline v HTML) lahko ne najbolj varno v kontekstu varnosti, XSS.

Zanima me, na kaj je potrebno pazit oz. kaj lahko gre narobe?

JS vsebino bi pisal na koncu tik pred /body tag-om.
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

smacker ::

Ne vidim, kak bi lahko bil internal JS kakorkoli manj varen od external JS. Upoštevaj pa, da se JS fajli običajno cachirajo v browserju, torej se posledično nalagajo samo ob prvem obisku strani. Tako da ni nujno da boš s tem ravno zmanjšal server load in page load time.

grimth ::

Temu se reče server side rendering, ne samo da ta inline js ne bo pristal v GET cache shrambi, ampak bo najverjetneje browser moral tudi vsakič parsat in naredit eval kode ob vsakem GET requestu. (odvisno od browserja). Chrome V8 sicer zna povezati inline js kodo z parent dokumentom ampak nastane parsan cache take inline kode samo če se dokument ne spremeni (zaradi hashov) in ta cache ni prenosljiv na druge strani tudi če gre za isto kodo.

Varnost je odvisna od same js kode in ne od tega kje je vključena v dokument.

Zgodovina sprememb…

  • spremenilo: grimth ()

MrStein ::

smacker je izjavil:

Ne vidim, kak bi lahko bil internal JS kakorkoli manj varen od external JS.

Vpiši ime: ==> $ime

Pozdravljen, $ime!


Če imaš enablan interni JS, si s tem dobil XSS.
Če ima dovoljene samo eksterne, pa so taki (in veliko drugih) XSS blokirani.

(dovoliš/ne-dovoliš recimo s Content Security Policy (CSP))
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Zgodovina sprememb…

  • spremenil: MrStein ()

HotBurek ::

MrStein, a lahko napišeš kak simple sample, kako to z $ime deluje?
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

MrStein ::

Kaj a v življenju nisi HTML strani naredil????
To je najosnovnejša stvar (takoj po strogo statičnih straneh).
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

MH0 ::

MITM ne more spremeniti CSP? Sem bos na tem področju.

HotBurek ::

Tega ne vem, kam naj to vpišem?

Vpiši ime: ==> $ime
Pozdravljen, $ime!


<div> ==> $ime</div>

<script> ==> $ime</script>


??
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

smacker ::

Pusti trola. Dolar pa JS... je vse povedal.

Matek ::

Nah, sej ma point, problem je sledeč:

- Velika večina XSS tehnik se zanaša na to, da injectajo inline script tag nekam v stran.
- Proti temu se lahko zaščitiš s CSP-jem, ki preprečuje izvajanje inline JavaScripta.
- Tega varnostnega mehanizma seveda ne moreš uporabiti, če hočeš inlineati svoj legit JS.

Z drugimi besedami - ni problem tvoj inlinan JS, problem je, da sploh omogočaš inline JS.

Se pa absolutno pridružujem komentarjem, da omenjena optimizacija ni veliko vredna. Browser cache je en argument, drugi je HTTP2 - če ga tvoj server podpira, dodaten request praktično ne predstavlja več overheada.


Iz radovednosti - koliko requestov se trenutno zgodi ob nalaganju tvoje strani in koliko je skupna količina prenesenih podatkov?
Bolje ispasti glup nego iz aviona.

smacker ::

Ok, razumem pomislek. Ampak če ti nekdo lahko injecta lastno kodo na tvoj page, maš hud problem nekje drugje in CSP ne preprečuje vseh napadov, ki so v tem primeru možni.

Spura ::

Matek je izjavil:

Nah, sej ma point, problem je sledeč:

- Velika večina XSS tehnik se zanaša na to, da injectajo inline script tag nekam v stran.
- Proti temu se lahko zaščitiš s CSP-jem, ki preprečuje izvajanje inline JavaScripta.
- Tega varnostnega mehanizma seveda ne moreš uporabiti, če hočeš inlineati svoj legit JS.

Z drugimi besedami - ni problem tvoj inlinan JS, problem je, da sploh omogočaš inline JS.

Se pa absolutno pridružujem komentarjem, da omenjena optimizacija ni veliko vredna. Browser cache je en argument, drugi je HTTP2 - če ga tvoj server podpira, dodaten request praktično ne predstavlja več overheada.


Iz radovednosti - koliko requestov se trenutno zgodi ob nalaganju tvoje strani in koliko je skupna količina prenesenih podatkov?

Ni res da ne mores inlineat JS ce uporabljas CSP, med dovoljene origine lahko das inline skrito glede na njen hash.

MrStein ::

smacker je izjavil:

Ok, razumem pomislek. Ampak če ti nekdo lahko injecta lastno kodo na tvoj page, maš hud problem nekje drugje in CSP ne preprečuje vseh napadov, ki so v tem primeru možni.

Nobena tehnika ne preprečuje vseh napadov.
Ene preprečujejo ene, druge pa druge.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

HotBurek ::

Ok, sem poizkusil z CSP-jem in uporabo script-src 'nonce-random...' ter script-src 'sha256-hash...='.

Uspelo mi je postavit do te mere, da ja delal inline CSS, ter inline JS, a le-ta (JS) je delal samo na osnovni strani in mi ni uspelo pogruntat, zakaj ne dela nikjer drugje. Zdej sem šel nazaj, in imam lepo inline CSS in JS, ter sledeč CSP header config v nginx:

add_header Content-Security-Policy "default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; img-src 'self'; connect-src 'self'";

Zdej me pa zanima, kako potestirat XSS za primer elemnta INPUT in TEXTAREA? Kaj naj notri vnesem, da ko bo browser to prebral, da bo tretiral vnešen string kot kodo (in jo izvedel)?

Sem na hitro postavil tale filter:

input = input.replace("<", "&lt;");
input = input.replace("%3C", "&lt;");
input = input.replace("%3c", "&lt;");
input = input.replace(">", "&gt;");
input = input.replace("%3E", "&gt;");
input = input.replace("%3e", "&gt;");
input = input.replace("&", "&amp;");
input = input.replace("%26", "&amp;");
input = input.replace("\"", "&quot;");
input = input.replace("%22", "&quot;");
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

Zgodovina sprememb…

  • spremenilo: HotBurek ()

MrStein ::

Pivo tistemu, ki opazi napako.

PS: tista beseda "unsafe" je tam z razlogom
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Zgodovina sprememb…

  • spremenil: MrStein ()

MrStein ::

HotBurek je izjavil:

Ok, sem poizkusil z CSP-jem in uporabo ...


Če se tvoje celotno sporočilo citira, ga ni mogoče oddati.
Torej tudi izkušeni programerji pri tem delajo napake.
Tako da ne gre tu za hece in "teoretične" zadeve.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Zgodovina sprememb…

  • spremenil: MrStein ()

smacker ::

Slo-tech zazna illegal character => zavrne submit. Ni user friendly, je pa učinkovito.
@HotBurek: Takih filtrov ne piši sam, uporabi vgrajene knjižnice (išči html escape/encode). V tvojem filtru si pozabil kup znakov + dodal bug - replace "&" v "&" ti bo replacal tudi '&' v prejšnjih escapanih kodah.

jernejl ::

smacker je izjavil:

replace "&" v "&" ti bo replacal tudi '&' v prejšnjih escapanih kodah.
Ne bo tako hudo, zamenjala se bo zgolj prva pojavitev :))

HotBurek ::

Evo, sem porihtal in je sedaj tako.

JS na client strani naredi POST s tekstom:
xhr.send("tekst=" + encodeURIComponent(tekst));


Na serverju Python naredi replace (tu sem popravil, da je replace za & na prvem mestu):
# simple fix
input = input.replace("&", "&amp;");
input = input.replace("%26", "&amp;");
input = input.replace("<", "&lt;");
input = input.replace("%3C", "&lt;");
input = input.replace("%3c", "&lt;");
input = input.replace(">", "&gt;");
input = input.replace("%3E", "&gt;");
input = input.replace("%3e", "&gt;");
input = input.replace("\"", "&quot;");
input = input.replace("%22", "&quot;");
input = input.replace("'", "&apos;");
input = input.replace("%27", "&apos;");


Vsebina je shranjena v MongoDB:
"tekst" : "&lt;%0A&gt;%0A&apos;%0A&quot;%0A&amp;%0A%C3%A4%C3%B6%C3%BC%C3%9F%C3%A1%C3%A0"


Pri branju Python naredi unquote:
tekst = urllib.parse.unquote(mongoitem["tekst"]);


Za vnešeni tekst v brskalniku:
< > ' " & ä ö ü ß á a


Je potem pri branju response:
&lt; &gt; &apos; &quot; &amp; ä ö ü ß á a
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

Zgodovina sprememb…

  • spremenilo: HotBurek ()

Matek ::

Kot ti je rekel smacker - ne sam pisat tovrstnih replaceov, uporabi dobro vzdrževano eksterno knjižnico.
Bolje ispasti glup nego iz aviona.

smacker ::

Najprej naredi url decode, potem pa stripaj html tage . Ne pozabi na NoSQL injection.

Zgodovina sprememb…

  • spremenil: smacker ()

MrStein ::

&apos; ni HTML entiteta.*

Bi opazil, če bi ga testiral. Zato pa:

1) uporabi že preverjeno delujoči knjižnico za to

Drugič: glej točko 1


* - so ga dodali v HTML5, torej ponekod bo delal, ponekod ne
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Zgodovina sprememb…

  • spremenil: MrStein ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Davčne blagajne (strani: 1 2 3 424 25 26 27 )

Oddelek: Programiranje
1344319102 (59105) Macketina
»

Javascript DOM based XSS vulnerability

Oddelek: Programiranje
152478 (1900) MrStein
»

Content-Security-Policy problem

Oddelek: Izdelava spletišč
51448 (1265) poweroff
»

[PHP][HTML]Pošiljanje maila iz PHP - TextBoxForm, SubmitButton, mail() v php

Oddelek: Programiranje
10695 (431) Excavator
»

Dev-C++ in napaka pri prevajanju funkcij

Oddelek: Programiranje
181042 (891) MartnKrp

Več podobnih tem