Newsgroup: it.comp.lang.perl
Titolo: script perl per scrivere un file via web

Ho scritto uno scriptino per gestire il file .htaccess di apache.
Lo "strano" č che se passo la directory dove deve andare a scrivere
questo file come /directory/dove/deve/andare/a/scrivere/ funziona,
mentre se la passo tramite una variabile mi trovo in apache un errore
del tipo "Insecure dependency in open while running setuid".
Lo script č flaggato +s perchč deve scrivere in directory senza il
permesso di scrittura a tutti.
Io DEVO poter passare la directory tramite una variabile...
thanks !
r.p.

Io DEVO poter passare la directory tramite una variabile...
Immagino che tu chiami il perl con il parametro -T: il Perl fa dei
controlli sui comandi esterni che lanci se essi (o parte di essi)
provengono da variabili, in quanto la cosa puo` essere pericolosa.
Se infatti un utente malizioso al posto della directory mette
qualcosa tipo "`rm /* -R`" beh... auguri. ;-)
Per far funzionare tutto basta tu faccia cosi`:
if ($myvar =~ /$(.*)^/) { $myvar = $1; }
Ti consiglio tuttavia di implementare un controllo del formato della
stringa nella regular expression, proprio per evitare i problemi di
cui sopra.
	Michele.
-- 
Michele Beltrame
mi...@io.com
http://www.io.com/~mick/

 
http://www.io.com/~mick/
-- 
-------------------------------------------------------------------------
Hosting professionale a prezzi USA? 
http://www.servitelit.com/prezzi.htm
-------------------------------------------------------------------------

 riuscire ad aggirarlo.
Se e' un sistema di sicurezza, c'e' per proteggerti, non per farsi aggirare.
Ti dice che stai facendo una cosa molto pericolosa, quindi dovresti aver la
premura di evitare il pericolo.
Spero che tu non stia passando ANCHE la directory come hidden input, perche'
e' doppiamente pericoloso.
Pero' se la directory e' in una variabile, il metodo di Michele dovrebbe
'rassicurare' Perl. Non ti funziona?
In ogni caso, NON passare la directory come hidden input. Chiunque puo'
vedere l'hidden input e creare uno script che passi una directory o una cosa
qualunque al suo interno.
Se hai un numero prefissato di directory su cui puoi dover operare, puoi
crearti un vettore di directory predefinite e far passare dallo script (come
hidden) il solo indice in tale vettore.
Naturalemente finche' uno non sa esattamente cosa stai cercando di fare e
che codice stai cercando di scrivere, si possono solo dare consigli a
cavolo. :)
Maurizio
-- 
Maurizio M. Munafo' / 
mmmu...@netscape.net
"Consider Phlebas, who was once handsome and tall as you" (T.S.Eliot)

 permesso di scrittura a tutti.
Per queste cose sarebbe meglio usare il suexec di apache... ad ogni
modo...
Da perldiag:
   Insecure dependency in %s
           (F) You tried to do something that the tainting
           mechanism didn't like.  The tainting mechanism is
           turned on when you're running setuid or setgid, or
           when you specify -T to turn it on explicitly.
perlsec spiega dettagliatamente quali sono le misure precauzionali
determinate dai "taint checks" e come sfruttarle per rendere il
codice più sicuro.
Max

Lo script viene lanciato da una form che è una directory protetta
tramite .htaccess, perciò solo un utente può lanciare questi script.
Tale script serve per proteggere un directory sotto la sua home dir
scrivendoci dentro il file .htaccess. Riporto lo script qui sotto dato
che è molto "stringato".
Lo script si bomba e nell' error_log di apache leggo: Insecure
dependency in open while running setuid
Lo script è flaggato +s perchè il file con nomeutente:password viene
scritto al di fuori della home dir dell'utente
La cosa "strana" è che se passo directory/nomefile per esteso funziona
perfettamente, mentre dà questo messaggio se nell'open metto le
variabili
#!/usr/bin/perl
$buffer="";
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) 
{
 @a = split (/=/,$pair);
 $name=$a[0];
 $value=$a[1];
 $value =~ s/\+/ /g;
 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
 $value =~ s/~!/ ~/g;
 $value =~ s/[\n\r]/ /sg;
 $value =~ s/\[\]//g;
 push (@data,$name);
 push (@data,$value);
 %form=@data;
 %form;
}
$nomefile=".htaccess";
$path = $form{'path'};
$directory=$form{'directory'};
$username =$form{'username'};
$password =$form{'password'};
$url = $form{'url'};
&oops(directory) unless $form{'directory'};
open (FILE,">$path/$directory/$nomefile") || die "Non posso aprire
$path/$directory/$nomefile";
print FILE "AuthName restricted stuff\n";
print FILE "AuthType basic\n";
print FILE "AuthUserFile /usr/local/etc/httpd/$directory\n";
print FILE "require valid-user\n";
close (FILE);
open (FILE,">/usr/local/etc/httpd/$directory");
$enc_password = crypt($password, "Cd");
print FILE "$username:$encpassword\n";
close (FILE);
print "Content-type: text/html\n\n";
print "Directory protetta";
print "<a href=$url>Pannello di Controllo</a>\n";
sub oops {
print "C'e' qualcosa di sbagliato nel campo $_[0]\n";
print "Premi il tasto INDIETRO/BACK per tornare alla form\n";
die;
}

 open (FILE,">/usr/local/etc/httpd/$directory");
Anche qui puoi aver bisogno dell'untainting.
Nel complesso, che succede se fai l'operazione suggerita su ogni stringa in
ingresso? Si blocca ancora?


sì mannaggia !!! si blocca ancora e sempre con lo stesso tipo di errore
"insecure dependency...."
è un giorno che ci sto girando attorno..sarà mica dovuto ad apache ?
il perl è la versione 5.005_03 e apache la 1.3


 è un giorno che ci sto girando attorno..sarà mica dovuto ad apache ?
Non credo.
Pensavo ad un alternativa. L'utente non sa di stare selezionando una
directory, giusto? Quei dati li scrivi tu dentro al file html per averli
quando devi creare l'htaccess.
Una cosa che puoi fare e' mettere questi dati (path e directory, credo) in un 
file esterno, usando il nome con cui si e' autenticato l'utente come chiave
di ricerca.
Ricapitolo:
1) Il tuo form e' protetto da un .htaccess, per cui l'utente deve fornire
username e password per accedervi
2) L'utente riempe il form (con un suo username e password da creare) a
quanto sembra
3) Il CGI chiamato dal form, riceve SOLO i parametri username e password.
4) Il CGI preleva dalla variabile di environment REMOTE_USER il nome con cui
 l'utente si e' autenticato (e dovrebbe esserci, dal momento che il form e'
 protetto da password)
5) Cerchi il nome di REMOTE_USER in un file a parte in cui tieni le 
  relazioni REMOTE_USER -> path -> directory 
6) A questo punto hai ottenuto path e directory da una fonte che dovrebbe
  essere sicura e puoi procedere.
Oppure puoi cercare di fare le stesse cose senza dover usare il suid.
In effetti, se quello ti serve solo per poter scrivere il file di password,
lo potresti far scrivere benissimo al semplice utente sotto il cui nome
viene eseguito il CGI. O almeno credo. Almeno sul mio server ho dei file
scritti e letti solo dall'utente del server httpd, illeggibili a tutti gli
altri.


Il problema basilare è che lo script deve essere standard per i diversi
domini in hosting.
Perciò dalla form devo passare:
login dell'utente che può accedere alla directory protetta
password utente
directory da proteggere
Le ho provate veramente tutte !



Mi spiace non poterti aiutare ulteriormente.
Ma sul singolo dominio l'approccio che ti avevo proposto funziona (intendo
quello del REMOTE_USER)? E che succede se lo script non e' setuid e provi 
a scrivere in una directory un po' meno protetta? 


su qualsiasi directory mi dà errore, a meno che metto la directory in
cui devo scrivere settata come "nobody", ma così non va bene logicamente
per la sicurezza !!!
Mi darò da fare nei due giorni di festa !
Grazie comunque per l'aiuto. Se riesco a risolverlo ti mando una mail
con la "soluzione" !


 per la sicurezza !!!
Scusa, ma perche' nobody non andrebbe bene? 
Se e' in un gruppo separato e i file creati sono 600 in una directory
scrivibile solo da lui, che differenza ci sarebbe con un file posseduto da
root?
L'unica cosa che posso pensare sono i rischi provenienti da altri CGI,
ma tu potrai ben mettere i file critici (ovvero le password) in posti 'poco
frequentati' e sconosciuti agli utenti normali.
Oltretutto e' sempre consigliato che i file .htpasswd siano al di fuori di
qualsiasi directory raggiungibile dal server web.
