Guidelines

Mettiamola così: chi scrive i commenti nei wiki metterà nel codice l’url
che punta alla pagina del wiki.
In fondo lo faccio anch’io. Uso redmine e ogni tanto nel codice ci sono
i riferimenti alle issue risolte da certe linee o alle feature
implementate. Lì dentro poi ci sono le spiegazioni più complete.

Ho appena fatto un find|xargs grep ‘#’ sull’ultimo progetto a cui sto
lavorando e non ci sono molti commenti in effetti, ma alcuni promemoria
penso sia bene che restino lì.

Paolo

Il giorno 12 ottobre 2012 18:27, Paolo M.
[email protected]ha scritto:

In fondo lo faccio anch’io. Uso redmine e ogni tanto nel codice ci sono
i riferimenti alle issue risolte da certe linee o alle feature
implementate. L dentro poi ci sono le spiegazioni pi complete.

+1
I riferimenti a bug fix # e feature # servono anche a me :slight_smile:

S.

On Fri, Oct 12, 2012 at 10:00 AM, Paolo P. [email protected]
wrote:

Avoid comments.
Don’t program defensively.
Avoid meta-programming.
Aim for skinny models and skinny controllers.

???
Seriamente, dopo il “don’t program defensively” ho smesso di
considerarle roba seria.

perch? Dipendentemente dal codice io condivido abbastanza che
“programming defensively” sia sbagliato.
Esempio:

def read_row(key)
raise “use a small integer as key” unless key.is_a?(Fixnum)
#do reading
end

nel 90% dei casi inutile (e quindi dannoso :slight_smile: )


twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: circleme.com

2012/10/13 gabriele renzi [email protected]

perch? Dipendentemente dal codice io condivido abbastanza che
“programming defensively” sia sbagliato.
Esempio:

def read_row(key)
raise “use a small integer as key” unless key.is_a?(Fixnum)
#do reading
end

nel 90% dei casi inutile (e quindi dannoso :slight_smile: )

Forse Paolo parla di cose diverse (vedi
Defensive programming - Wikipedia)

S.

p.s. in effetti design by contract ed assert sparse in giro nel codice
mi
capitato raramente di usarli :slight_smile:

Il giorno 12 ottobre 2012 16:36, Nicholas W. [email protected] ha
scritto:

Seriamente, e’ necessario discutere del design di un software all’interno
del software stesso, o discutere di una scelta presa all’interno del file
in cui la
si e’ presa? Boh, de gustibus, io li uso poco

Commenti alla rdoc ?
Che poi sono simili a javadoc, .net code doc, valadoc, ecc…
Potrebbero essere utili.
Ma la migliore documentazione codice dei test e codice
dell’applicazione.
Ben scritto, facilmente leggibile da altri devs :slight_smile:

Se vai a leggerti i motivi per cui commentare e per cui usare i commenti
per esempio
qui:

http://www.amazon.com/Practice-Programming-Addison-Wesley-Professional-Computing/dp/020161586X

ti accorgi che tutte le argomentazioni portate sono rovinosamente
anacronistiche

Va b.
Mi citi un libro del 1999.
Sono passati pi di 10 anni (una vita nel ICT :wink:

S.

p.s. e Linus magari pensa a codice in termini di funzioni C in sistemi
unix.
E l i commenti forse servono :-))

Il giorno 13 ottobre 2012 17:38, gabriele renzi [email protected] ha
scritto:

Ni, per quello scrivevo che dipende dal codice.

Yep :slight_smile:

 return []

end

(imvho) pessimo, perch invece di fallire perch c’ codice
altrove che invoca la funzione in modo sbagliato, va avanti come se
niente fosse.

Ma ripeto, dipende dal codice imo.

+1
Cmq di solito (non sempre) te lo dicono anche i test (fallendo) che c’
qualcosa che non va nel codice dell’applicazione.
Si spera :wink:

S.

2012/10/13 Sergio B. [email protected]:

nel 90% dei casi inutile (e quindi dannoso :slight_smile: )

Forse Paolo parla di cose diverse (vedi
Defensive programming - Wikipedia)

Ni, per quello scrivevo che dipende dal codice.
Codice che ha a che fare con input utente ha una ragione per essere
scritto in modo difensivo, perch parte della funzionalit del metodo
la validazione dell’input.

Se la stessa validazione si finisce a farla dentro una
#top_employees_by_salary(enumerable, limit), perch “non si sa mai”
significa che nel sistema le responsabilit sono mischiate.

Ma ancora te lo passo se per esempio “limit” finisce in una query al
db e c’ un “limit = limit.to_i” (per quanto il check non dovrebbe
stare qui, e dovrebbe fallire senza che sia questo metodo a
controllarlo)

Quello che non ha senso e se invece dentro #sort_employees_by_salary
fai un check del tipo:

unless enumerable.is_a?(Enumerable) && enumerable.any?
raise “invalid”
end

che codice non necessario, perch fallirebbe lo stesso, mentre

unless enumerable.is_a?(Enumerable) && enumerable.any?
return []
end

(imvho) pessimo, perch invece di fallire perch c’ codice
altrove che invoca la funzione in modo sbagliato, va avanti come se
niente fosse.

Ma ripeto, dipende dal codice imo.


twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: circleme.com

Appunto quella linea guida non dice “dipende dal codice” dice di nn fare
defensive programming senza se senza ma e questo imho senza senso.

Poi altra cosa tu dici in un mio metodo interno nn trovo sensato fare
prog difensiva perch nn c’ input dell’utente. Ok ma questo implica che
tu hai valutato tutti i possibili percorsi che i dati che quel metodo
usa fanno e quindi hai detto ok sono al 100% sicuro che in nessun modo
anche agendo in altri punti del codice un attaccante nn possa fare
tampering di qualcosa che alla fine propaga al mio metodo.

Ci sta ne ma valutare tutti i possibili Data flow diagram pi
dispendioso che mettere un raise per rendere robusto un metodo a
prescindere.

Poi ovviamente son gusti. Mettere quel raise tu dici essere inutile, va
bene ma dannoso secondo me proprio no :slight_smile:

“static analysis is fun… again”
Owasp Orizon project leader: http://orizon.sf.net
Owasp Italy R&D director

2012/10/14 Paolo P. [email protected]:

Appunto quella linea guida non dice “dipende dal codice” dice di nn fare
defensive programming senza se senza ma e questo imho senza senso.

Poi altra cosa tu dici in un mio metodo interno nn trovo sensato fare prog
difensiva perch nn c’ input dell’utente. Ok ma questo implica che tu hai valutato
tutti i possibili percorsi che i dati che quel metodo usa fanno e quindi hai detto
ok sono al 100% sicuro che in nessun modo anche agendo in altri punti del codice
un attaccante nn possa fare tampering di qualcosa che alla fine propaga al mio
metodo.

no, basta controllare solamente i boundary del sistema. Non serve una
coverage C2, serve semplicemente che ogni input sia clean Cio, in
teoria basterebbe #taint (ma in ruby passato di moda) o passare da
classi ad hoc che rappresentano i dati (Category, Name, whatever).

Al che l’obiezione me la faccio sa solo “ma non sai dove sono i
confini del sistema”.
E allora il problema che non chiara l’architettura, e quello
garantito che crei problemi :slight_smile:

Ci sta ne ma valutare tutti i possibili Data flow diagram pi dispendioso che
mettere un raise per rendere robusto un metodo a prescindere.

Poi ovviamente son gusti. Mettere quel raise tu dici essere inutile, va bene ma
dannoso secondo me proprio no :slight_smile:

per quello che deve farlo il sistema! La situazione, per come l’ho
vista ia, che se non sono chiari confini e responsabilit, ti trovi
con

#read_input: () ->String che valida l’input
#build_logic: String → Result che valida l’input
#find_data_for_keys: List[String] → Result che valida l’input
dbi,jdbc o che altro che valida l’input

e chiaramente per ogni metodo che ha adesso un doppio
comportamentodevi scriverti un test, perch senn domani lo rompi.
Poi quando cambi una cosa (tipo, l’input viene encodato diversamente o
decidi che la key non deve avere spazi) devi cambiare 9 pezzi di
codice diversi, ed al crescere del sistema garantito che te ne perdi
un pezzo.

A quel punto uno che fa, si tira fuori un metodo
“getValidNameFromString(name)” (che credo sia tipo quello che c’
nelle ESAPI di OWASP) e lo riusa in 3 metodi.

E questo equivalente ad aver fatto una classe di dominio (Name,
Category, etc) ed aver fatto il codice come

#read_input: () → Name che valida
#build_logic: Name → Result
#find_data_for_keys: List[Name] → Result
e dove invoco jdbc/dbi/AR invoco Name.to_key.

Con la differenza che quando aggiungo un pezzo nuovo il sistema mi
aiuta, oppure no.

Comunque si, solo la mia modestissima opinione.


twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: circleme.com

2012/10/15 gabriele renzi [email protected]:
[snip]

no, basta controllare solamente i boundary del sistema. Non serve una
coverage C2, serve semplicemente che ogni input sia clean Cio, in
Eh attenzione Gabriele, tu questo dal punto di vista di application
security non puoi assumerlo.
Tu di devi porre nella condizione che il tuo input sia tainted.

Al che l’obiezione me la faccio sa solo “ma non sai dove sono i
confini del sistema”.
E allora il problema che non chiara l’architettura, e quello
garantito che crei problemi :slight_smile:
Assolutamente no. Se tu conduci un’attivit di Threat modeling su
tutto il tuo sistema allora puoi fare i dovuti alleggerimenti dicendo,
ok il valore qui safe per questi motivi: a, b, c.
Il che vuol dire che hai valutato che il db non pu essere compromesso
e quindi contenere ad esempio codice js per fare un xss di tipo
stored, oppure hai valutato che che un attaccante non possa fare
tampering di quel valore perch hai operato del filtering oppure
perch lo fa il framework che stai usando. Oppure ti assumi il
rischio che il cast di un certo valore fallisca, oppure ti assumi il
rischio di errori applicativi non gestiti.

Io quando mi trovo nella necessit di scrivere del codice, preferisco
sempre considerare il mio codice con le dovute pre e post condizioni
al metodo testando quello che mi arriva e quello che esce.
Cos per gusto personale, per non credo di fare qualcosa di dannoso
se aggiungo validazioni.

decidi che la key non deve avere spazi) devi cambiare 9 pezzi di
codice diversi, ed al crescere del sistema garantito che te ne perdi
un pezzo.
Fare programmazione difensiva non vuol dire replicare lo stesso codice
di validazione n volte. Significa capire dove va messo il codice per
la validazione dell’input e poi ciascun metodo valida il dato secondo
la semantica che lui si aspetta. Per dire, un metodo interno non
rivalider nuovamente l’input per un XSS se gi stato fatto altrove
ma sicuramente dovr verificare che l’input sia un intero perch by
contract si aspetta un intero in input.

HTH

Ci


$ cd /pub
$ more beer

The blog that fills the gap between appsec and developers: