Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Uutiset tietyille jäsenryhmille

Sivun loppuun

Olli [21.04.2013 11:53:07]

#

Tietokannassa minulla on neljä eri jäsentasoa (1, 2, 3, 4). Uutisilla on kolme eri tasoa (A, B, C). Haluaisin, että kirjautumattomat käyttäjät pääsisivät lukemaan vain tason A uutisia. Tason 1 jäsenet pääsisivät lukemaan A:ta ja B:tä. Taso 2-4 pääsisivät lukemaan A:ta, B:tä ja C:tä. Mikä olisi järkevin tapa tehdä tämä (PHP+PDO) ?

Metabolix [21.04.2013 12:08:19]

#

Helpointa olisi vaihtaa A, B ja C luvuiksi 0, 1 ja 2 ja lisäksi merkitä kirjautumattoman käyttäjän tasoksi 0, jolloin voisit kirjoittaa SELECT-kyselyihin suoraan ehdoksi uutinen.taso <= {$kayttajan_taso}.

Olli [21.04.2013 12:17:00]

#

Hyvä idea, mitenkäs sitten annan virheilmoituksen, jos käyttäjä yrittää hakea uutista, jota hän ei saa lukea?

Metabolix [21.04.2013 12:25:17]

#

En nyt oikein ymmärrä, mikä on ongelmasi. Kai nyt olet ennenkin jotain virheilmoituksia antanut.

// PHP 5.4:
http_response_code(403);
// Vanhemmat versiot:
header('-:', true, 403);
header_remove('-');

tulosta_sivu('
	<h1>Ei oikeutta!</h1>
	<p>Sinulla ei ole oikeutta lukea tätä uutista.</p>
');

Olli [21.04.2013 21:17:29]

#

Tarkoitin lähinnä seuraavaa tilannetta

// haetaan data kannasta

if( käyttäjällä oikeus avata uutinen ) {
// näytetään uutinen

} else {
// näytetään virhe
}

Mitä pitäisi laittaa tuohon if-lausekkeen ehdoksi?

Grez [21.04.2013 21:40:38]

#

if ($uutinen['taso'] <= $kayttajan_taso) {

Itse tosin tyypillisesti laittasin tarkistuksen jo SQL-kyselyyn jolla uutinen haetaan:
.. WHERE id={0} and taso<={1}', $id, $kayttajan_taso
Ja annan virheilmoituksen että uutista ei ole jos kysely palauttaa 0 riviä.

Mielestäni käyttäjien ei välttämättä kuulu tietää, että järjestelmässä ylipäätään on uutinen, jos ko. käyttäjällä ei ole oikeus sitä lukea.

Olli [21.04.2013 21:42:15]

#

Kiitos tästä, en tajunnut noin simppeliä :)

Olli [27.04.2013 18:58:01]

#

Eli nyt on
- uutistasot 0, 1, 2
- jäsentasot 0, 1, 2, 3, 4

Uutisten lukemisoikeuden tarkistuksen olen toteuttanut Grezin ja Metabolixin vinkkien avulla, mutta nyt olisi tarkoitus toteuttaa muokkaus. Eli vain käyttäjätasot 3 ja 4 voivat muokata uutisia. Onko tämä järkevä tapa:

$query = $db->prepare("SELECT * FROM news WHERE id = ? AND 3 <= ? LIMIT 1");
$query->execute(array($id, $userLevel));

$article = $query->fetch();

if(empty($article)){
	// estä muokkaus
} else {
	// salli muokkaus
}

Metabolix [27.04.2013 19:14:07]

#

On aivan turha kierrättää vakioita SQL:n kautta, kun voit saman tien kirjoittaa ehdon PHP:llä sivun alkuun eikä tarvitse sitten enää tarkistella kyselyn tuloksia. Silloin saat myös erikseen statukset 403 Forbidden (ei oikeutta) ja 404 Not Found (väärä id, ei muokattavaa uutista).

Olli [27.04.2013 19:56:01]

#

Onko ko. statuksilla tarvetta? Voinhan vain näyttää käyttäjälle virheilmoituksen.

Metabolix [27.04.2013 20:03:26]

#

Onko mielessäsi jokin syy jättää status asettamatta? Aina on järkevää ja loogista antaa virheilmoituksen mukana myös oikea status. Eräs olennainen syy on, että myös ohjelmat silloin tietävät, mistä on kysymys, ja esimerkiksi hakukoneet osaavat jättää sivut indeksoimatta.

Olli [27.04.2013 20:14:08]

#

No esimerkiksi se, että status pitäisi asettaa ennen sisällön näyttämistä, joka on hyvin vaikeaa. Vai onko järkevämpää tapaa ?

Metabolix [27.04.2013 20:26:50]

#

On järkevämpi tapa: ohjelmoi kunnolla! Hae ensin kaikki tarvittavat tiedot ja vasta sitten aseta status ja aloita tulostus. En ole kuullut vielä yhtäkään järkevää syytä tulostaa ennen tietojen hakemista. Sen sijaan on koko joukko näitä tilanteita, joissa väärään paikkaan tungettu tulostus aiheuttaa ihan tarpeettomia ongelmia. Myös koodi selvenee, kun täysin eri asiat (tietojen haku ja tulostus) tehdään selvästi erikseen.

Olli [27.04.2013 20:39:36]

#

No olen tehnyt niin, että sivun yläosa (sisältäen tietokannan alustuksen ja HTML-aloituksen) on toisessa ja alaosa toisessa tiedostossa. Sitten käytän include-funktiota aina jokaisen sivun alussa ja lopussa. Mikä olisi järkevämpi tapa?

Metabolix [27.04.2013 21:29:03]

#

Ongelmasi ei johdu includen käytöstä vaan include-rivien sijoittelusta. Voit yksinkertaisesti siirtää includen eri kohtaan:

<?php
include "funktiot.php";
// TODO: Tässä välissä hae tiedot ja laita ne muuttujiin.
// TODO: Jos tarvitsee, aseta status tai ohjaa käyttäjä toiselle sivulle.
include "tulosta_yla.php";
// TODO: Tulosta sivun sisältö.
include "tulosta_ala.php";

Järkevämpiä tapoja on monta, mm. yläosan ja alaosan laittaminen funktioihin tai sivupohjaa kuvaavaan luokkaan, jotta eri tiedostoissa käytettävä muuttujat eivät mene vahingossa sekaisin. Tämä valinta ei suoranaisesti liity nykyiseen ongelmaasi, vaan ihan saman ongelman voi aiheuttaa muillakin toteutustavoilla, jos törttöilee koodin järjestyksen kanssa.

Olli [27.04.2013 22:15:00]

#

Tuo antamasi koodiesimerkki on kyllä ihan järkevä. Täytyy harkita sitä.

EDIT: Miten muuten täällä Ohjelmointiputkassa tuo on toteutettu?

qeijo [28.04.2013 09:08:51]

#

En ymmärrä miksi aloittavia kehittäjiä neuvotaan rakentamaan sivustoa tuolla tavalla.

Eli hyvin primiviitillä, rajoittavalla ja haavoittuvalla tavalla. Sitten jossakin vaiheessa huomaavat että hei, tämähän tapa on paska tapa, miksi olen tehnyt asiat näin, voi ei.

Tässäkin tapauksessa olisi parampi jos Olli lataisi jonkun PHP - ohjelmistokehyksen, harjoittelisi sillä, ja alkaisi alusta asti tekemään asiat hyväksi todetulla tavalla.

Olli [28.04.2013 10:28:30]

#

No mikä olisi sitten parempi tapa tehdä se?

Metabolix [28.04.2013 12:20:51]

#

Kuten jo sanoin, voisi olla hyvä käyttää edes funktioita (tulosta_yla() ja tulosta_ala()) tai luokkaa ($pohja = new Pohja(); $pohja->ylaosa() ja $pohja->alaosa()), ettei tule sählättyä globaaleilla muuttujilla. Jos sitten vielä hienompiin ratkaisuihin haluaa mennä, voi käyttää erilaisia templaattimoottoreita (template engine) tai XSLT:tä (Extensible Stylesheet Language Transformations).

Mielestäni on typerää käyttää liian mutkikkaita ratkaisuja yksinkertaisiin asioihin, kun ei tarvitse niitä. Toisten mielestä taas on typerää käyttää yksinkertaista ratkaisua, kun voi käyttää hienoja, massiivisia, jonkin ideologian mukaan ”oikein” tehtyjä kirjastoja, joilla onnistuvat tarvittaessa myös asiat X, Y ja Z. Valitse siitä sitten. Hyvä tapa on joka tapauksessa sellainen, jolla saat sivusi tehtyä kätevästi, toimivasti, myös tulevaisuudessa ymmärrettävästi ja ilman purkkaviritelmiä. Ei nyt aleta eri tapojen paremmuudesta tai filosofiasta vängätä, se on jo tehty melko lailla tuloksetta.

Olli [28.04.2013 12:40:51]

#

Joo, totta. Taidan kuitenkin jatkaa tuolla mallilla, tuntuu jotenkin selkeämmältä.

Olisiko muuten tähän mitään muutosehdotuksia, järkevämpiä tapoja tehdä sama asia:

<?php
$title = "Artikkelilomake";
include("../inc/functions.php");

	if($userLevel >= 3){
		$action			= $_GET["action"];
		$id				= $_GET["id"];		if(empty($id)){ $id = $_POST["id"]; }
		$from			= $_GET["from"];

		$formTitle		= stripTags(htmlspecialchars($_POST["title"]));
		$formContent	= stripTags($_POST["content"]);
		$formType		= stripTags($_POST["type"]);

		if($action == "edit"){
			$intTitle 		= "Muokkaa uutista";
			$intButtonText	= "Tallenna muutokset";
		} elseif($action == "add"){
			$intTitle 		= "Lisää uutinen";
			$intButtonText 	= "Lisää uutinen";
		}

		if($from == "view-news"){
			$cancelLink = siter("news/{$id}");
		} else {
			$cancelLink = siter("admin");
		}

		switch($action){
			case "edit":
			case "add":
				if(!empty($id)){
					$query = $db->prepare("SELECT type, title, content FROM news WHERE id = ? LIMIT 1");
					$query->execute(array($id));
					$article = $query->fetch();

					$defaultTitle 	= $article["title"];
					$defaultContent	= $article["content"];
					$defaultType	= $article["type"];
				}

				$action = "do".$action;
				include("../inc/top.php");
				include("../inc/tpl/articleform.php");
				include("../inc/bottom.php");
				break;

			case "doadd":
				$query = $db->prepare("INSERT INTO news (type, title, seotitle, author, content) VALUES (?, ?, ?, ?, ?)");
				$query->execute(array($formType, $formTitle, urlSEO($formTitle), $userId, $formContent));
				$id = $db->lastInsertId();
				header("location:".siter('news/'.$id));
				break;

			case "doedit":
				$query = $db->prepare("UPDATE news SET type = ?, title = ?, seotitle = ?, content = ? WHERE id = ?");
				$query->execute(array($formType, $formTitle, urlSEO($formTitle), $formContent, $id));
				header("location:".siter('news/'.$id));
				break;

			case "doremove":
				$query = $db->prepare("DELETE FROM news WHERE id = ? LIMIT 1");
				$query->execute(array($id));
				header("location:".siter('admin?msg=Artikkelin poisto onnistui.'));
				break;

		}

	} else {
		header('-:', true, 403);
		header_remove('-');
		include("../inc/top.php");
		accessDenied();
		include("../inc/bottom.php");
	}
?>

qeijo [28.04.2013 13:35:15]

#

Metabolix kirjoitti:

Ei nyt aleta eri tapojen paremmuudesta tai filosofiasta vängätä, se on jo tehty melko lailla tuloksetta.

Kapeakatseista todeta että jokin käyty keskustelu, jossa ihmiset ovat esittäneet omia mielipiteitä ja toisista eriäviä toteutustapoja asiasta, olisi ollut tulokseton.

Miten päädyit tähän johtopäätökseen? Onko keskustelu käyty turhaan, koska kaikki ei ollut samaa mieltä? Mielestäni juuri sellainen keskustelu on tärkeä ja avartaa.

Löydätkö täältä foorumilta ainuttakaan oikeasti web kehityksen parissa työskentelevää, joka puoltaisi tuota sinun lobbaamaa include - vetoista viritelmää.

Vai onko asia niin, että juuri tämä täytyy olla oikea ratkaisu, koska olet itse sitä käyttänyt ja ehkä jopa käytät edelleen?

Miksi yhdistät "ison ja monimutkaisen" "järkevään"? Ei sen tarvitse olla laaja ja monimutkainen, jotta se olisi jonkun laajennettavissa olevan rakenteellisesti järkevän suunnitelman mukaisesti toteutettu.

Metabolix [28.04.2013 14:22:53]

#

qeijo kirjoitti:

Kapeakatseista todeta että jokin käyty keskustelu, jossa ihmiset ovat esittäneet omia mielipiteitä ja toisista eriäviä toteutustapoja asiasta, olisi ollut tulokseton.

Yleensä keskustelua sanotaan tuloksettomaksi, jos siitä ei synny mitään ilmeistä tulosta. Esimerkiksi hallitusneuvottelut ovat tuloksettomat, kun hallitusta ei saada muodostettua, ja turkistarhauskeskustelu on tuloksetonta, kun kannattajat ja vastustajat pysyvät omilla kannoillaan eikä mikään muutu. Tässä suhteessa myös tuon keskustelun väittelyosuus oli mielestäni tulokseton: ei päädytty mihinkään ratkaisuun siitä, mikä on universaalisti paras mahdollinen toteutustapa, jonka latenleffahyllyn tuleva web 3.0 -unioni voi määrätä kaikkien käytettäväksi standardiksi.

qeijo kirjoitti:

– – tuota sinun lobbamaa include - vetoista viritelmää – –

Vai onko asia niin, että juuri tämä täytyy olla oikea ratkaisu, koska olet itse sitä käyttänyt ja ehkä jopa käytät edelleen?

En ole missään vaiheessa lobannut mitään include-vetoista viritelmää. En myöskään ole itse käyttänyt tuon toisen keskustelun lopussa esittämääni tapaa (jossa on tasan yhtä monta includea kuin vastapuolen moottorissakin) enkä missään vaiheessa ole väittänytkään niin. Keskustelu lähti vauhtiin väitteistä, että jotkin asiat olisivat funktioilla äärimmäisen vaikeita tai mahdottomia ja että toisenlaisessa moottorissa taas ei olisi mitään näistä puutteista missään tapauksessa. Omien viestieni keskeinen tarkoitus oli osoittaa nuo väitteet vääriksi näyttämällä, että ratkaisutavoilla ei ole suurta eroa ja että funktioillakin on mahdollista kaikki hyvä ja vielä enempikin. En ole missään vaiheessa sanonut mitään oikeasta tai parhaasta ratkaisusta, kyllä sitä puolta kuultiin jo tarpeeksi toiselta puolelta – höystettynä tahallaan huonosti tehdyillä vastaesimerkeillä.

Oliko vielä lisää ymmärrysvaikeuksia selvitettäväksi?

qeijo kirjoitti:

Miksi yhdistät "ison ja monimutkaisen" "järkevään"?

Osoitapa nyt keskustelusta kohta, jossa olen nämä asiat yhdistänyt, kun itse en löydä sellaista. Yhdistin kyllä tarpeettoman ison ja typerän. Kannattaa miettiä, mitä oikeasti tarvitsee, mitä ehkä tarvitsee, mitä ei varmasti tarvitse ja millä välineillä nämä vaatimukset helpoiten täyttyvät.

qeijo [28.04.2013 15:17:40]

#

Metabolix kirjoitti:

Yleensä keskustelua sanotaan tuloksettomaksi, jos siitä ei synny mitään ilmeistä tulosta.

Yleensä keskustelussa (ei kysymyksessä) ei edes ole mitään ilmeistä tulosta saavutettavissa. Hallitusneuvotteluissa toki on, koska siinä pyritään saamaan asioita konkreettisesti sovittua, neuvottelu siis, ei keskustelu.

Metabolix kirjoitti:

turkistarhauskeskustelu on tuloksetonta, kun kannattajat ja vastustajat pysyvät omilla kannoillaan eikä mikään muutu.

Onpas harvinaisen typerä esimerkki, mielestäsi vaaliväittelytkin ovat varmaan aina tuloksettomia.

Metabolix kirjoitti:

En ole missään vaiheessa lobannut mitään include-vetoista viritelmää

Mielestäni asetut aina vastaavanlaisten viritelmien puolelle, kun aiheesta käydään "tuloksetonta" keskustelu.

Metabolix kirjoitti:

Osoitapa nyt keskustelusta kohta, jossa olen nämä asiat yhdistänyt, kun itse en löydä sellaista. Yhdistin kyllä tarpeettoman ison ja typerän. Kannattaa miettiä, mitä oikeasti tarvitsee, mitä ehkä tarvitsee, mitä ei varmasti tarvitse ja millä välineillä nämä vaatimukset helpoiten täyttyvät.

Mielestäsi oli typerää käyttää liian mutkikaita ratkaisuja yksinkertaisiin asioihin.
Olen tietenkin samaa mieltä, mutta ei liian monimutkainen korreloi järkevän kanssa, järkevän ei siis tarvitse olla monimutkainen. Yleensä juuri huonot toteutukset ovat kaiken lisäksi myös monimutkaisia.

dartvaneri [28.04.2013 15:34:06]

#

olli: Otappa ainakin nuo miljoonat turhat välit muuttujien ja sijoitusoperaatio merkkien väliltä pois. Tähän tyyliin:

 muuttuja = arvo;

Yksi väli sijoitusoperaattorin molemmille puolin.

Grez [28.04.2013 15:34:16]

#

qeijo kirjoitti:

Onpas harvinaisen typerä esimerkki, mielestäsi vaaliväittelytkin ovat varmaan aina tuloksettomia.

Et varmaan itsekään usko siihen, että ne aina olisivat. Eli kyllähän vaaliväittelyissä usein saadaan välitettyä tietoa poliitikkojen näkymyksistä äänestäjille ja vaikutetaan äänestyskäyttäytymiseen.

Toki jos tosiaan vaikka pidettäisiin vaaliväittely jota kukaan ei seuraisi niin se voisi hyvinkin olla tulokseton.

Eihän tuloksettomassa keskustelussa sinänsä mitään pahaa ole. Ihmiset harrastaa sitä päivittäin.

qeijo [28.04.2013 15:39:07]

#

Grez kirjoitti:

qeijo kirjoitti:

Onpas harvinaisen typerä esimerkki, mielestäsi vaaliväittelytkin ovat varmaan aina tuloksettomia.

Et varmaan itsekään usko siihen, että ne aina olisivat. Eli kyllähän vaaliväittelyissä usein saadaan välitettyä tietoa poliitikkojen näkymyksistä äänestäjille ja vaikutetaan äänestyskäyttäytymiseen.

Toki jos tosiaan vaikka pidettäisiin vaaliväittely jota kukaan ei seuraisi niin se voisi hyvinkin olla tulokseton.

Eihän tuloksettomassa keskustelussa sinänsä mitään pahaa ole. Ihmiset harrastaa sitä päivittäin.

Jos tämä oli osoitettu minulle, niin lue viestini uudestaan. Olen siis sitä mieltä että vaaliväittelyt eivät ole tuloksettomia, vaikka niissä ei mitään ilmeistä tulosta saadakaan aikaseksi.

Metabolix [28.04.2013 15:40:07]

#

qeijo kirjoitti:

Yleensä keskustelussa (ei kysymyksessä) ei edes ole mitään ilmeistä tulosta saavutettavissa. – – Mielestäsi vaaliväittelytkin ovat varmaan aina tuloksettomia.

Tuloksen voi toki määritellä monella tavalla. Mielestäni kuitenkaan ajatusten välittäminen seuraajille ei ole olennaisesti keskustelun tulos, jos sitä ei ole suunniteltu keskustelun tarkoitukseksi (kuten vaaliväittelyssä on). Eihän jääkiekkopelissäkään sanota tulokseksi sitä, että katsojilla on hauskaa.

qeijo kirjoitti:

Mielestäni asetut aina vastaavanlaisten [include-]viritelmien puolelle, kun aiheesta käydään "tuloksetonta" keskustelu.

Mielestäni en ole ikinä suositellut includen tai muunkaan ”viritelmän” käyttöä, jos vaihtoehtona on ollut jokin kunnollinen ja tilanteeseen nähden kohtuullinen ratkaisu. Joskus olen suositellut tuota Ollin tapaa, kun vaihtoehtona on ollut täysin idioottimainen GET-parametri-include tai saman koodin kopiointi jokaiselle sivulle ja olen arvioinut, ettei kysyjälle kannata yrittää selittää mitään hienompaa.

Olli kirjoitti:

Olisiko muuten tähän mitään muutosehdotuksia, järkevämpiä tapoja tehdä sama asia: – –

Ainakin ottaisin turhan sisennyksen pois, kääntäisin if-lauseen vastakkaiseksi ja laittaisin bottom.php:n jälkeen die-rivin, jolloin else-lohko olisi turha ja toinenkin sisennys voitaisiin poistaa.

if ($plaa < 3) {
	accessDenied();
	die();
}
// ...

Lisäksi on aika sekavaa tarkistaa $action sekä if-lauseella että switch-lauseella, yhdistäisin nuo. En ymmärrä striptags-funktion tarkoitusta koodissasi. Et ole alustanut kaikkia muuttujia (esim. $defaultTitle, jos juuri tuohon if-lauseeseen ei mennä), ja tämä altistaa virheille, jos samanlainen muuttuja on toisessakin kohdassa, tai jopa tietoturva-aukoille, jos vanhentunut Register Globals -asetus on jostain syystä vielä päällä.

Olli [28.04.2013 18:29:01]

#

dartvaneri kirjoitti:

olli: Otappa ainakin nuo miljoonat turhat välit muuttujien ja sijoitusoperaatio merkkien väliltä pois. Tähän tyyliin:

 muuttuja = arvo;

Yksi väli sijoitusoperaattorin molemmille puolin.

Ne välit on tabeja.

Metabolix kirjoitti:

Lisäksi on aika sekavaa tarkistaa $action sekä if-lauseella että switch-lauseella, yhdistäisin nuo.

Ne on melko vaikea yhdistää, itse en ainakaan keksi järkevää tapaa, sillä add&edit ovat saman casen alla.

Metabolix kirjoitti:

En ymmärrä striptags-funktion tarkoitusta koodissasi.

Olen määritellyt sen toisaalla jottei tarvitse toistaa sallittuja tageja useaan kertaan.

Metabolix kirjoitti:

Et ole alustanut kaikkia muuttujia (esim. $defaultTitle, jos juuri tuohon if-lauseeseen ei mennä), ja tämä altistaa virheille, jos samanlainen muuttuja on toisessakin kohdassa, tai jopa tietoturva-aukoille, jos vanhentunut Register Globals -asetus on jostain syystä vielä päällä.

Laitoin nyt muuttujille alustuksen, Suncometilla ei näytä register globals onneksi olevan päällä.

dartvaneri [28.04.2013 18:54:43]

#

Olli kirjoitti:

dartvaneri kirjoitti:

olli: Otappa ainakin nuo miljoonat turhat välit muuttujien ja sijoitusoperaatio merkkien väliltä pois. Tähän tyyliin:

 muuttuja = arvo;

Yksi väli sijoitusoperaattorin molemmille puolin.

Ne välit on tabeja.

No olkoot vaikka entereitä, mutta turha ero muuttujan ja operaattorin välillä heikentää koodin luettavuutta.

Metabolix [28.04.2013 20:47:15]

#

Olli kirjoitti:

Metabolix kirjoitti:

En ymmärrä striptags-funktion tarkoitusta koodissasi.

Olen määritellyt sen toisaalla jottei tarvitse toistaa sallittuja tageja useaan kertaan.

Ei ole siitä kysymys. Miksi ylipäänsä käytät sitä?

Tagien valikoivalla poistolla ei tehdä tietoturvaa. Jos vaikka ajattelit sallia <b>-tagin tyylikeinona, käyttäjä voi edelleen kirjoittaa näin:

<b style="display: block; position: fixed; left: 0; top: 0; width: 100%; height: 100%;" onmousemove="alert('hähää')">Ihan turvallista!</b>

Tagien poisto aiheuttaa täysin järjettömiä ongelmia.

echo strip_tags("Oletetaan, että a<b ja c>d.");
// Oletetaan, että ad.
// Häh?

Pelkän tagien poiston ainoa järkevä käyttötarkoitus on HTML-koodin muuttaminen tekstiksi esimerkiksi sellaisessa tilanteessa, että haluaa hakea netistä toisen sivun ja käsitellä sitten sen sisältöä tekstinä. Muihin tarkoituksiin valikoivaa poistoa voi käyttää silloin, kun data on varmasti HTML-muodossa (eli tulee HTML-editorilta eikä käsin kirjoitettuna), mutta silloin pitää ehdottomasti huomioida, että myös turvallisilla tageilla voi olla vaarallisia attribuutteja.

Kun haluat, että syötetty teksti näkyy sivulla tekstinä eikä HTML-koodina, oikea ratkaisu on käyttää tulostusvaiheessa funktiota htmlspecialchars. Älä käytä sitäkään ennen tiedon tallennusta, koska muokattua tietoa on taas turhaan hankala käsitellä tietokannassa (ja se vie enemmän tilaakin) ja koska silloin on vaikeampi tietää tulostusvaiheessa, mikä tieto on jo käsitelty ja mitä ei.

Vilkaisin nyt koodiasi vielä uudestaan, ja näyttää, että yrität mm. hakea POST-muuttujien arvoja silloinkin, kun lomaketta ei ole edes lähetetty. Koodissasi lienee muutenkin koko joukko erilaisia alkeellisia virheitä, jotka löydät, kun laitat virheilmoitukset käyttöön.

Olli [29.04.2013 14:24:29]

#

Haluan, että käyttäjä pystyy käyttämään tiettyjä rajoitettuja muotoiluita (mm. linkit, lihavointi ja kursivointi). Tämän takia en voi käyttää htmlspecialchars-funktiota, vaan käytän strip_tags-funktiota. Onko joku parempi ratkaisu tarjolla?

Täytyy tutkia nuita muita virheitä vielä. Tosin, onko POST-muuttujien arvojen hakemisesta mitään haittaa, jos niitä ei ole lähetetty?

qeijo [29.04.2013 14:44:40]

#

Olli kirjoitti:

Haluan, että käyttäjä pystyy käyttämään tiettyjä rajoitettuja muotoiluita (mm. linkit, lihavointi ja kursivointi). Tämän takia en voi käyttää htmlspecialchars-funktiota, vaan käytän strip_tags-funktiota. Onko joku parempi ratkaisu tarjolla?

Käyttää yksinkertaistettua versiota BBCode kaltaisesta ratkaisusta.

Olli [29.04.2013 14:46:30]

#

Käytössä ckeditor, kuinkahan vaikeaksi BBCodeen vaihto menisi.

timoh [29.04.2013 15:08:56]

#

Älä missään nimessä vaihda BBCodeen, vaan aja ckeditorin tuotos sopivasti konfiguroidun HTML Purifier -instanssin läpi ja pukkaa tulos ruudulle.

qeijo [29.04.2013 15:21:39]

#

timoh kirjoitti:

Älä missään nimessä vaihda BBCodeen, vaan aja ckeditorin tuotos sopivasti konfiguroidun HTML Purifier -instanssin läpi ja pukkaa tulos ruudulle.

Jos kyseessä on vain pari kolme yksinkertaista muotoilusääntöä sekä linkit, niin miksi ei?

timoh [29.04.2013 15:48:48]

#

Lihavointi ja kursivointi vielä menee yksinkertaisina operaatioina (XSS:n puolesta), mutta linkit ei. Ja koska käytössä on täysverinen html-editori, niin hölmöltä se kuullostaa vaihtaa BB-purkkaan.

BB:n kanssa on äkkiä makkarat suussa ja perunat takilla kun haluaa lisätä viestiin uusia muotoiluja. Ckeditor + HTML Purifier combolla ei.

Ja se että HTML pysyy validina vihamielisen syötteen alla, painaa aika paljon kupissa HTML Purifierin suuntaan (verrattuna siihen omaan BB-parserin tuotokseen). Se ei enää ole aivan yksinkertainen operaatio kun tageja suolletaan sikin sokin sinne tänne.

HTML Purifier on mature ja industry standard näissä hommissa, joten en näe syitä miksi sitä ei käyttäisi (kun käyttäjiltä tulee syötettä mihin halutaan sisällyttää jonkinlaista, enemmän tai vähemmän, muotoilua).

Olli [30.04.2013 18:00:12]

#

Tuo HTML Purifier on oikein hyvä, otin sen käyttöön. Järkevää varmaan on tallentaa data kantaan koskematta siihen ja ajaa data purifierin läpi vasta siinä vaiheessa kun se näytetään käyttäjälle, kuten Metabolix sanoi?

Kannattaako muuten tuon asetuksiin koskea, vai onko oletusasetukset hyvät?

timoh [30.04.2013 19:24:55]

#

Aja data HTML Purifierin läpi jo ennen kantaan tallennusta. Tämä on OK valtaosassa tapauksia. Jos tarvetta jostain syystä tulee, niin voit ajaa matskun vielä ennen tulostustakin Purifierin läpi. Muuten riittää että läväytät tekstin selaimelle suoraan kannasta ilman Purifieriä.

Tarkista että merkistökoodaus ja doctype täsmää. Jos ei, säädä ne kohdalleen.

Sekä conffaa vielä sallitut tagit ja attribuutit vastaamaan ckeditorin asetuksia.

http://htmlpurifier.org/live/INSTALL

dartvaneri [30.04.2013 19:47:08]

#

timoh kirjoitti:

Aja data HTML Purifierin läpi jo ennen kantaan tallennusta. Tämä on OK valtaosassa tapauksia. Jos tarvetta jostain syystä tulee, niin voit ajaa matskun vielä ennen tulostustakin Purifierin läpi. Muuten riittää että läväytät tekstin selaimelle suoraan kannasta ilman Purifieriä.

Nyt taisi mennä vähän väärinpäin. Tieto kannatta tallentaa sellaisenaan kantaan, toki asiaa kuuluvien funktioiden kautta. Vasta tulostaessa HTML Purifierin läpi.

Tämä, jos tajusin oikein, että tuo HTML Purifier on saman tyyppinen, kuin htmlspecialchars-funktio.

Edit. Tarkoitan asiaan kuuluvilla funktiolla esim. PDO:n execute-funtiota.

Metabolix [30.04.2013 19:58:24]

#

dartvaneri kirjoitti:

Tieto kannatta tallentaa sellaisenaan kantaan, toki asiaa kuuluvien funktioiden kautta. Vasta tulostaessa HTML Purifierin läpi.

Tämä, jos tajusin oikein, että tuo HTML Purifier on saman tyyppinen, kuin htmlspecialchars-funktio.

Sitten kannattaisi varmaan selvittää ensin, mikä HTML Purifier on. Itse asiassa jo keskustelusta kävi ilmi, että se on enemmänkin strip_tags-funktiota vastaava rakennelma. Se on siis hyvä ajaa jo ennen tallennusta, koska sen tarkoitus on huolehtia, että datan muoto on oikea. Sitä voi verrata vaikka intval-funktion käyttöön tai päivämäärän muodon tarkistukseen.

Olli kirjoitti:

Tosin, onko POST-muuttujien arvojen hakemisesta mitään haittaa, jos niitä ei ole lähetetty?

Ei ole väliä koodin toiminnan kannalta, mutta kysyn taas samaa kuin statuksesta puhuttaessa: onko jotain järkeä tehdä väärin, kun voi tehdä oikeinkin?

Asialla on myös merkitystä PHP:n ilmoitusten kannalta. Virheilmoitusten ja huomautusten pitäminen näkyvissä kehitysvaiheessa on hyödyllistä ja voi ehkäistä vakaviakin virheitä. Jos koodissasi on monta tuollaista merkityksetöntä vikaa, saat suuren määrän ilmoituksia etkä pysty etsimään joukosta olennaisia. Sen sijaan jos ilmoituksia ei normaalisti tule lainkaan, huomaat helposti jokaisen uuden ilmoituksen.

qeijo [30.04.2013 21:25:02]

#

Miksi ihmeessä tiedot pitäisi ajaa purifierin läpi jo ennen tallennusta?

Parempi säilyttää data alkuperäisessä muodossa, ja turvata tieto/validoida data esitysvaiheessa, ei siis tallennusvaiheessa.

timoh kirjoitti:

Aja data HTML Purifierin läpi jo ennen kantaan tallennusta. Tämä on OK valtaosassa tapauksia. Jos tarvetta jostain syystä tulee, niin voit ajaa matskun vielä ennen tulostustakin Purifierin läpi. Muuten riittää että läväytät tekstin selaimelle suoraan kannasta ilman Purifieriä.

Just joo, aja kahdesti..

Tiedon alkuperä voi olla monesta eri versioista ja sen hetkisistä tarpeista, eli et voi tietää mitä kannassa on. Ja kun tulee spekseihin muutkosia, muutat vain esitysvaiheen toteutuksen.

Eli ehdottomasti validointi/puhdistus esitysvaiheessa, ei kannata luottaa siihen mitä kannassa on tai mitä on joskus tehty tai ei tehty datalle. Vai onko teillä päteviä syitä miksi ei toimia näin?

The Alchemist [30.04.2013 22:46:12]

#

qeijo kirjoitti:

Miksi ihmeessä tiedot pitäisi ajaa purifierin läpi jo ennen tallennusta?
--
Eli ehdottomasti validointi/puhdistus esitysvaiheessa, ei kannata luottaa siihen mitä kannassa on tai mitä on joskus tehty tai ei tehty datalle. Vai onko teillä päteviä syitä miksi ei toimia näin?

"Purifiointi" ei ole näyttömuodon valmistelua vaan syötteiden validointia/sanitointia. Siis se kuuluu tehdä ennen kantaan tallennusta. Lisäksi se on ilmeisesti aika raskas, mutta tämä on vain sivuseikka.

Olisi yhtälailla väärin se, että jos kenttään saa syöttää vain numeroita, niin kantaan kirjoitettaisiin kuitenkin mikä tahansa syöte ("45x") ja aina tulostusvaiheessa parsittaisiin siitä numerot pihalle.

qeijo [01.05.2013 08:33:12]

#

Tämän ymmärrän, tietenkin käyttäjälle voidaan esittää virheilmoitus, että tieto ei täytä rajoituksia ja pakottaa käyttäjä muuttamaan syöte ennen sen tallennusta.

Pointtini oli että esitysvaiheessa on silti ajettava tieto purifierin läpi mm. viime viestissä mainitsemastani syistä.

The Alchemist kirjoitti:

Olisi yhtälailla väärin se, että jos kenttään saa syöttää vain numeroita, niin kantaan kirjoitettaisiin kuitenkin mikä tahansa syöte ("45x") ja aina tulostusvaiheessa parsittaisiin siitä numerot pihalle.

Tässä tietenkin toimittaisi eri tavalla, eli validointi sekä tiedon esitysmuodon valmistelu tulostuksessa.

Eli onko tässä tapauksessa purifierin tarkoitus estää tallennus jos tieto ei täytä vatimuksia, vai muklata syntaksia lennossa ennen sen esittämistä?

Käyttäjän näkökulmasta ei ole väliä milloin se tehdään jos siis kaikki menee alustavasti läpi?

The Alchemist [01.05.2013 10:08:46]

#

Minusta ei ole mitään tarvetta (eikä järkeäkään) ajaa kannasta haettua dataa purifierin läpi enää tulostusvaiheessa. Tässä tapauksessa käyttötarkoituksena on vain varmistaa, että rikastekstieditorilla tuotettu teksti on turvallista ja ettei siihen ole yritetty upottaa ylimääräistä ja potentiaalisesti vaarallista merkkausta mukaan. Kantaan tallennettava html on siis vain leipätekstiä (+ kuvia ja taulukoita yms.), jossa on kovakoodattuna ulkoasullisia määrityksiä kuten tekstin väri tai fontin tyyli. Jos käyttäjä itse haluaa tehdä sinistä tekstiä Comis Sans -fontilla, niin sitä ei jälkeenpäin ole tarve muuttaa ajonaikaisesti. Purifiointi on siis vain syötteen sanitointia ja siten se kuuluu tehdä ennen tallennusta.

qeijo kirjoitti:

Tiedon alkuperä voi olla monesta eri versioista ja sen hetkisistä tarpeista, eli et voi tietää mitä kannassa on.

Jos kantaan ilmestyy dataa, josta ei tiedetä, mitä se on tai miksi se on siellä, niin kyse on tietoturvan pettämisestä. Yleisesti ottaen täytyy voida olla varma, että kun kannassa on jotain dataa, niin sitä on silloin varmasti myös turvallista käyttää.

Mikäli määritykset muuttuvat sovelluksen elinkaaren myöhemmässä vaiheessa, niin kannassa oleva vanha data täytyy muuntaa uusien speksien mukaiseen muotoon (tietokantatasolla). Ei voida vain mergeä vanhaa ja uutta dataa ja lisätä tauhkaa tulostuspäähän ja toivoa, että yhteensopivuusongelmat kuitataan sillä.

dartvaneri [01.05.2013 10:26:25]

#

The Alchemist kirjoitti:

qeijo kirjoitti:

Tiedon alkuperä voi olla monesta eri versioista ja sen hetkisistä tarpeista, eli et voi tietää mitä kannassa on.

Jos kantaan ilmestyy dataa, josta ei tiedetä, mitä se on tai miksi se on siellä, niin kyse on tietoturvan pettämisestä. Yleisesti ottaen täytyy voida olla varma, että kun kannassa on jotain dataa, niin sitä on silloin varmasti myös turvallista käyttää.

Itse oletusarvoisesti lähden aina liikkeelle siitä, että kannassa olevaan dataan tai sen turvallisuuteen ei voi luottaa. Eihän se data sielä kannassa mitään pahaa tee, vaan vasta tulostus väiheessa.

Grez [01.05.2013 10:32:07]

#

dartvaneri kirjoitti:

Itse oletusarvoisesti lähden aina liikkeelle siitä, että kannassa olevaan dataan tai sen turvallisuuteen ei voi luottaa. Eihän se data sielä kannassa mitään pahaa tee, vaan vasta tulostus väiheessa.

Missä sitten säilytät esim. järjestelmän käyttäjä- ja käyttöoikeustiedot yms.? Jos ne on kannassa, eikä kannassa olevaan tietoon voi luottaa, niin millä tavalla sitten validoit ko. epäluotettavat tiedot esim. käyttäjän kirjautuessa sisään?

The Alchemist [01.05.2013 10:54:35]

#

dartvaneri kirjoitti:

The Alchemist kirjoitti:

qeijo kirjoitti:

Tiedon alkuperä voi olla monesta eri versioista ja sen hetkisistä tarpeista, eli et voi tietää mitä kannassa on.

Jos kantaan ilmestyy dataa, josta ei tiedetä, mitä se on tai miksi se on siellä, niin kyse on tietoturvan pettämisestä. Yleisesti ottaen täytyy voida olla varma, että kun kannassa on jotain dataa, niin sitä on silloin varmasti myös turvallista käyttää.

Itse oletusarvoisesti lähden aina liikkeelle siitä, että kannassa olevaan dataan tai sen turvallisuuteen ei voi luottaa. Eihän se data sielä kannassa mitään pahaa tee, vaan vasta tulostus väiheessa.

Järjestelmän täytyy olla eheä kokonaisuus. Ei voida tehdä sellaista lähtöoletusta, että moduuli X voi olla vihamielinen moduulia Y kohtaan, ja että nämä kaksi vihollista joutuvat suojautumaan toistensa hyökkäyksiltä. Jos järjestelmä päästää dataa muuriensa sisäpuolelle, niin sen datan täytyy olla ehdottoman turvallista ja kontrolloitua.

Jos myönnät tietokantasi voivan olla vaarallinen, niin myönnät koko järjestelmäsi olevan vaarallinen. Tulostuksella ei ole yhtään mitään väliä. Tietoja ei välttämättä tulosteta koskaan, mutta silti hyökkääjä voi päästä sisälle järjestelmään ja varastaa tiedot.

qeijo [01.05.2013 10:56:03]

#

The Alchemist kirjoitti:

Yleisesti ottaen täytyy voida olla varma, että kun kannassa on jotain dataa, niin sitä on silloin varmasti myös turvallista käyttää.

Et itsekään usko tota.

The Alchemist kirjoitti:

Mikäli määritykset muuttuvat sovelluksen elinkaaren myöhemmässä vaiheessa, niin kannassa oleva vanha data täytyy muuntaa uusien speksien mukaiseen muotoon (tietokantatasolla).

Joka on tietyissä tapauksissa mahdotonta (purifioidulle datalle), ajassa kun ei voi mennä taaksepäin.
Eli inbound suodatuksella voidaan menettää dataa.

Lisäys:

The Alchemist kirjoitti:

Järjestelmän täytyy olla eheä kokonaisuus. Ei voida tehdä sellaista lähtöoletusta, että moduuli X voi olla vihamielinen moduulia Y kohtaan, ja että nämä kaksi vihollista joutuvat suojautumaan toistensa hyökkäyksiltä. Jos järjestelmä päästää dataa muuriensa sisäpuolelle, niin sen datan täytyy olla ehdottoman turvallista ja kontrolloitua.

Jos myönnät tietokantasi voivan olla vaarallinen, niin myönnät koko järjestelmäsi olevan vaarallinen. Tulostuksella ei ole yhtään mitään väliä. Tietoja ei välttämättä tulosteta koskaan, mutta silti hyökkääjä voi päästä sisälle järjestelmään ja varastaa tiedot.

Taas lähti mopo lapasesta, tässä kun ei puhuta mistää järjestelmän moduuleista. Ei se data ole vaarallinen kannassa, se on vaarallista uskoa sokeasti siihen että jokin data on täysin turvallista ja tulostaa se ilman tarkistusta tai valmistelua.

Ainoa rajoittava tekijä on purifierin hitaus, mutta vähintäänkin säilyttäisin myös kopion alkuperäisestä datasta, jota voisi tarvittaessa hyödyntää.

timoh [01.05.2013 11:43:25]

#

Se että filtteröinti on tarvetta ajaa kahteen kertaan (myös ennen tulostusta) voi johtua mm. siitä, että sisään on päässyt, syystä tai toisesta, haittakoodia. Nyt kun filtteröinti otetaan käyttöön ennen tulostusta, voi olla että et joudu lyömään lappua luukulle siihen saakka että saat systeemin siivottua puhtaaksi. Voit rauhassa fixata ongelman (en ota tässä kantaa ongelman perimmäiseen syyhyn).

Toinen mahdollinen syy on defense in depth.

Se miksi se yleensä ajetaan jo ennen tallennusta on tullut yllä jo ilmi - syötteen filtteröinnin takia (miksi tallentaa virheellistä/haitallista syötettä?). Tätä voisi ehkä omalla tavallaan verrata siihen, että ei tulostusvaiheessa yleensä filtteröidä omaa etusivun html-contenttiakaan.

Jos filtteröintiasetukset myöhemmin muuttuvat, päivität vanhan datan tarvittaessa tausta-ajona tjms. Jos siis ylipäänsä on todellista tarvetta päivittää.

The Alchemist [02.05.2013 09:06:35]

#

qeijo kirjoitti:

The Alchemist kirjoitti:

Yleisesti ottaen täytyy voida olla varma, että kun kannassa on jotain dataa, niin sitä on silloin varmasti myös turvallista käyttää.

Et itsekään usko tota.

Totta kai "uskon", kun ymmärrän mistä puhun.

qeijo kirjoitti:

The Alchemist kirjoitti:

Mikäli määritykset muuttuvat sovelluksen elinkaaren myöhemmässä vaiheessa, niin kannassa oleva vanha data täytyy muuntaa uusien speksien mukaiseen muotoon (tietokantatasolla).

Joka on tietyissä tapauksissa mahdotonta (purifioidulle datalle), ajassa kun ei voi mennä taaksepäin.
Eli inbound suodatuksella voidaan menettää dataa.

Et taida vieläkään ymmärtää, mihin tuota purifieria on oikeasti tarkoitus käyttää tässä yhteydessä. Sillä on tarkoitus suotia pois hyökkäysyritykset, jotka kohdistuvat erityisesti sellaisiin syötteisiin, joihin käyttäjä saa luvan kanssa syöttää jotain html:ää. Jos käyttäjä on saanut syöttää span-tageja tekstin tyylin hallintaan tai table-rakenteita taulukoiden luomiseksi, niin ei ole mitään syytä ikinä tallentaa mitään muuta syötteeseen tungettua roskaa kantaan "varmuuden vuoksi".

Mikäli käyttäjä käyttäisi vain syötteen tuottamiseen tarkoitettua widgettiä (Ckeditor tms.), niin hän ei koskaan voisi tuottaa vääriä muotoiluja vahingossa, vaan kyse on käytännössä aina hyökkäysyrityksestä. Tietysti syötteitä voidaan myös haluta normalisoida joiltain osin, mutta tämänkin pitäisi olla haluttu tulos eikä vain hetken mielijohteesta tapahtuvaa hässäköintiä. Tarvittaessa suotimisen voi vaikka jakaa kahteen vaiheeseen: ensin poistetaan selkeästi turha roska ja tallennetaan välitulos "alkuperäisenä", jonka jälkeen suoritetaan normalisointi ja sen tulos tallennetaan "valmiina".

Jos jostain syystä halutaan vielä arkistoida raakaversio datasta, niin sitten senkin voi tehdä, mutta sille tuskin on päivittäistä käyttöä järjestelmässä.

qeijo kirjoitti:

The Alchemist kirjoitti:

Järjestelmän täytyy olla eheä kokonaisuus. Ei voida tehdä sellaista lähtöoletusta, että moduuli X voi olla vihamielinen moduulia Y kohtaan, ja että nämä kaksi vihollista joutuvat suojautumaan toistensa hyökkäyksiltä. Jos järjestelmä päästää dataa muuriensa sisäpuolelle, niin sen datan täytyy olla ehdottoman turvallista ja kontrolloitua.

Jos myönnät tietokantasi voivan olla vaarallinen, niin myönnät koko järjestelmäsi olevan vaarallinen. Tulostuksella ei ole yhtään mitään väliä. Tietoja ei välttämättä tulosteta koskaan, mutta silti hyökkääjä voi päästä sisälle järjestelmään ja varastaa tiedot.

Taas lähti mopo lapasesta, tässä kun ei puhuta mistää järjestelmän moduuleista. Ei se data ole vaarallinen kannassa, se on vaarallista uskoa sokeasti siihen että jokin data on täysin turvallista ja tulostaa se ilman tarkistusta tai valmistelua.

Suotta ymmärrät sanan "moduuli" jotenkin väärin. Hyvä järjestelmä on jaettu palasiin ja yleensä tietokanta on varsin erillinen palanen esimerkiksi datan käsittely- tai tulostuskerroksesta.

timoh kirjoitti:

Se että filtteröinti on tarvetta ajaa kahteen kertaan (myös ennen tulostusta) voi johtua mm. siitä, että sisään on päässyt, syystä tai toisesta, haittakoodia. Nyt kun filtteröinti otetaan käyttöön ennen tulostusta, voi olla että et joudu lyömään lappua luukulle siihen saakka että saat systeemin siivottua puhtaaksi. Voit rauhassa fixata ongelman (en ota tässä kantaa ongelman perimmäiseen syyhyn).

Sitten kun järjestelmän tietoturva pettää, niin vasta sitten toimitaan tilanteen vaatimalla tavalla. Ei ole mitään järkeä heitellä purkkaa satunnaisiin kohtiin koodia siltä varalta, että se saattaa ehkä joskus torjua yhden sadasta miljoonasta erilaisesta hyökkäyksestä. Jos sinun tarvitsee kyseenalaistaa järjestelmäsi tietoturvallisuus jossain tietyssä kohtaa, niin silloin korjaa se kohta HETI.

Nyt kyse on vielä siitä, että erityisesti suosittelet käyttämään purkkaa, jolla saadaan peitettyä mahdollinen tietoturvan pettäminen muilta käyttäjiltä. Tällä ei ole oikeastaan mitään tekemistä tietoturvan parantamisen kanssa vaan juuri vuotojen peittelyn. Melkoinen kamikaze-liike.

timoh [02.05.2013 11:06:13]

#

The Alchemist kirjoitti:

Sitten kun järjestelmän tietoturva pettää, niin vasta sitten toimitaan tilanteen vaatimalla tavalla. Ei ole mitään järkeä heitellä purkkaa satunnaisiin kohtiin koodia siltä varalta, että se saattaa ehkä joskus torjua yhden sadasta miljoonasta erilaisesta hyökkäyksestä. Jos sinun tarvitsee kyseenalaistaa järjestelmäsi tietoturvallisuus jossain tietyssä kohtaa, niin silloin korjaa se kohta HETI.

Meinasin juuri tuota että otetaan output filtteröinti lisänä siinä tilanteessa käyttöön kun systeemissä on jo vihamielistä koodia.

Mutta tosiaan se, että "tuplafiltteröintiä" ei ikinä olisi syytä käyttää on harhaan johtavaa. Alkujaan puhuin valtaosasta tilanteita missä input filtteröinti pelkästään on OK.

Systeemit voi koostua esim. monista osista ja se että vaikka sisääntuleva syöte jo filtteröidään, niin tuloste voi olla hyvä filtteröidä juuri mainitsemani "defense in depth" ajattelumallin mukaisesti.

Viestit tulevat esim. eri järjestelmästä (vaikka ne sinne sisään otettaessa tiettävästi ajetaankin filtteröinnin läpi), niin en näe kamikazena tai purkkana ajaa toisessa systeemissä vielä matskua filtterin läpi tulostettaessa.

Korostan vielä että missään nimessä purkkaa ei pidä liimata satunnaisiin kohtiin sinne tänne vailla suunnitelmaa. Suunnitelmat ovat kuitenkin systeemikohtaisia ja en kehtaa yleistää että joku tietty tapa on se ainoa oikea kaikkialla. Pahoittelut jos alkuperäisestä viestistäni sai tällaisen kuvan.

The Alchemist kirjoitti:

Nyt kyse on vielä siitä, että erityisesti suosittelet käyttämään purkkaa, jolla saadaan peitettyä mahdollinen tietoturvan pettäminen muilta käyttäjiltä. Tällä ei ole oikeastaan mitään tekemistä tietoturvan parantamisen kanssa vaan juuri vuotojen peittelyn. Melkoinen kamikaze-liike.

Ajoin sitä takaa, että jos output filtteröinti otetaan käyttöön hyökkäyksen jälkeen (ja sillä estetään vaikka haittakoodin leviäminen), niin se on ainoa järkevä vaihtoehto sen lisäksi että koko systeemi suljetaan. Toki systeemi voi olla pakko sulkea muutenkin, mutta ei välttämättä, ja tällä saadaan pidettyä systeemi auki ja rauhassa siivota roskat yms. palautumistoimet. Se totta vie parantaa tietoturvaa jos systeemi ei suolla haittakoodia.

qeijo [02.05.2013 12:06:01]

#

Myönnän että en ole koskaan koko HTML Purifieria käyttänyt tai vastaavanlaisia, joten kai se on uskottava tätä hysteeristä fundamentalistia.

Löysin kuitenkin HTML Purifierin dokumentaatiosta kaksi enemmän tai vähemmän suositeltua tapaa, josta "Caching the filtered output" vaihtoehto tuntuu minusta mielekkäämmältä. Toki siinäkään ei suoranaisesti kehoiteta ajamaan filtteröintiä tulostettaessa, mutta vaihtoehdossa säilytetään silti kopio alkuperäisestä datasta.

Syy miksi haluan ajaa filtteröinti tulostusvaiheessa ei ole se että en ymmärtäisi sen tarkoitusta, vaan että kaiken muun prosessoinnin jälkeen varmistuisin vielä tulostusvaiheessakin että mukana ei ole turvatonta koodia.

Mielestäni tämä ei ole automaattisesti "purkkaa".

Inbound filtering

Perform filtering of HTML when it's submitted by the user. Since the user is already submitting something, an extra half a second tacked on to the load time probably isn't going to be that huge of a problem. Then, displaying the content is a simple a manner of outputting it directly from your database/filesystem. The trouble with this method is that your user loses the original text, and when doing edits, will be handling the filtered text. While this may be a good thing, especially if you're using a WYSIWYG editor, it can also result in data-loss if a user makes a typo.

Caching the filtered output

Accept the submitted text and put it unaltered into the database, but then also generate a filtered version and stash that in the database. Serve the filtered version to readers, and the unaltered version to editors. If need be, you can invalidate the cache and have the cached filtered version be regenerated on the first page view. Pros? Full data retention. Cons? It's more complicated, and opens other editors up to XSS if they are using a WYSIWYG editor (to fix that, they'd have to be able to get their hands on the *really* original text served in plaintext mode).

Summary
In short, inbound filtering is the simple option and caching is the robust option (albeit with bigger storage requirements).

timoh [02.05.2013 14:05:31]

#

qeijo kirjoitti:

Myönnän että en ole koskaan koko HTML Purifieria käyttänyt, joten kai se on uskottava tätä hysteeristä fundamentalistia.

Löysin kuitenkin HTML Purifierin dokumentaatiosta kaksi enemmän tai vähemmän suositeltua tapaa, josta "Caching the filtered output" vaihtoehto tuntuu minusta mielekkäämmältä. Toki siinäkään ei suoranaisesti kehoiteta ajamaan filtteröintiä tulostettaessa, mutta vaihtoehdossa säilytetään silti kopio alkuperäisestä datasta.

Dokumentaatiossa mainittu data-loss ei käytännössä ole ongelma editorien kanssa. Mm. ckeditor nykyään oletuksena jo itsessään filtteröi matskun asetuksia vastaavaksi (vaikka palauttaisit editorille roskamatskun kannasta, se filtteröityy jo tässä vaiheessa pois automaagisesti).

Jos meikäläistä tarkoitit hysteerisenä fundamentalistina, niin tämä ei ole suinkaan tarkoitukseni. Nostin vain esille hyväksi havaittuja ns. industry standard asioita, mitkä mielestäni on hyvä tiedostaa näiden hommien parissa ;)

qeijo [02.05.2013 14:25:07]

#

timoh kirjoitti:

Jos meikäläistä tarkoitit hysteerisenä fundamentalistina, niin tämä ei ole suinkaan tarkoitukseni. Nostin vain esille hyväksi havaittuja ns. industry standard asioita, mitkä mielestäni on hyvä tiedostaa näiden hommien parissa ;)

En takoittanut sinua. Minunkin täytyisi välillä tiedostaa etten kaikkea tiedosta ja kuunnella viisaampia.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta