Repository navigation
Bezbednost
Dalibor edited this page Jun 21, 2026
·
1 revision
- bcrypt, cost faktor 12
- Heš se čuva u bazi, nikad u plaintext-u
- Anti-enumeracija:
IzjednaciVremeProvereizvršava bcrypt poređenje i kad korisnik ne postoji — vreme odgovora je identično
// internal/auth/auth.go
const bcryptCost = 12
func HashujLozinku(lozinka string) (string, error) {
return bcrypt.GenerateFromPassword([]byte(lozinka), bcryptCost)
}
func IzjednaciVremeProvere(lozinka string) {
_ = bcrypt.CompareHashAndPassword(dummyHash, []byte(lozinka))
}- TOTP (Time-based One-Time Password) — RFC 6238
- 6-cifreni kodovi, rotiraju na 30 sekundi
- Tajna se šifruje AES-256-GCM pre upisa u bazu
- QR kod za podešavanje u autentifikator aplikaciji
- Rezervni kodovi za oporavak (jednokratni, bcrypt heširani)
-
Server-side — token u HTTP-only kolačiću
ntech_sesija - Token je UUID v4 (
github.com/google/uuid) - Podaci sesije:
korisnik_id,token,created_at,expires_at - Nema osetljivih podataka u kolačiću — samo nasumični token
-
Secureflag u produkciji i demo modu -
HttpOnly— JavaScript ne može da čita kolačić -
SameSite=Lax— zaštita od CSRF-a na nivou brauzera
5 neuspelih pokušaja sa iste IP adrese u 15 minuta → IP se blokira
- Evidencija u tabeli
pokusaji_prijave - Auth log u fail2ban formatu (
/var/log/ntech/auth.log) - Pogodan za integraciju sa spoljnim fail2ban-om
- Double-submit cookie obrazac
- CSRF token se generiše na serveru i ubacuje u svaki
<form> - Token se upoređuje sa kolačićem pri svakoj POST/PUT/DELETE mutaciji
- Implementacija:
internal/middleware/csrf.go
<!-- Automatski ubacuje renderer -->
<form method="post" action="/magacin/novi">
<input type="hidden" name="csrf_token" value="...">
...
</form>| Uloga | Opis |
|---|---|
| superadmin | Pun pristup — sve dozvole + dodela uloga |
| admin | Upravljanje korisnicima, podešavanja, svi moduli |
| radnik | Ograničen pristup — dodeljene dozvole po modulu |
Akcije su granularne: modul.akcija (npr. artikal.dodaj, servis.obrisi, izvestaj.pregled).
Neke rute su namerno javne (bez dozvole):
-
/magacin— pregled magacina -
/podsetnici— svi prijavljeni vide svoje podsetnike -
/prijava,/setup— neautentifikovani pristup
// Mutirajuće rute — vraća 403 na odbijanje
r.With(doz("prodaja.dodaj")).Post("/prodaja/nova", ...)
// GET rute — redirektuje na odbijanje
r.With(doz("nabavka.pregled")).Get("/nabavke", ...)
// Admin rute — po ulozi
r.Group(RequireAdmin) → /admin/korisnici*, /admin/dozvole*
r.Group(RequireSuperAdmin) → /admin/dozvole/uloga/{id}Svaki HTTP odgovor dobija:
| Header | Vrednost |
|---|---|
Content-Security-Policy |
Dinamički: style-src, script-src, img-src, font-src
|
X-Content-Type-Options |
nosniff |
X-Frame-Options |
DENY |
X-XSS-Protection |
0 (zastarelo, CSP preuzima) |
Referrer-Policy |
strict-origin-when-cross-origin |
Strict-Transport-Security |
max-age=63072000 (samo u produkciji) |
-
XSS zaštita —
ntechToastkoristitextContent(neinnerHTML) -
Open redirect — validacija
_nextparametra kroz whitelist -
Limit upload-a —
http.MaxBytesReaderza sve POST zahteve -
Anti-MIME-sniffing —
X-Content-Type-Options: nosniff -
CSP font-src — dozvoljava samo
'self'(rešava problem sa Chart.js fontovima u Operi/Chrome-u) -
Secure kolačići —
Secure=trueu produkciji i demo modu -
OIE zaštita —
SameSite=Laxna svim kolačićima