Irbisa · Шпаргалка
Сети и безопасность для бэкенда
TCP и модель OSI, DNS, TLS, HTTP/3 и QUIC, балансировщики и прокси, WebSocket, CORS, хеширование паролей, OAuth 2.0 и JWT, SSRF, mTLS
Какие уровни есть в моделях OSI и TCP/IP и на каком уровне работают IP, TCP, TLS, HTTP и балансировщик нагрузки?
Что происходит шаг за шагом между вводом
https://example.com/ordersв браузере и первым байтом ответа?Чем HTTPS отличается от HTTP, что делает TLS-рукопожатие и когда стоит выбрать UDP вместо TCP?
Что такое CORS, какие запросы вызывают preflight
OPTIONSи почему CORS не защищает API отcurlили другого сервера?Как WebSocket-соединение начинается с HTTP-запроса и что должны поддерживать прокси и балансировщики перед сервисом на Go, чтобы оно не обрывалось?
// Registered as mux.HandleFunc("GET /ws", chat).func chat(w http.ResponseWriter, r *http.Request) { // Checks the Upgrade headers and Origin, then answers 101 Switching Protocols. c, err := websocket.Accept(w, r, &websocket.AcceptOptions{ OriginPatterns: []string{"app.example.com"}, // browsers send Origin; CORS does not apply here })…Как TCP открывает соединение тройным рукопожатием и как закрывает его, и почему у нагруженного клиента копятся сокеты в
TIME_WAIT?Как работает разрешение имён в DNS и почему сервис на Go может ещё минутами слать трафик на старый IP после смены записи?
Как TLS-клиент решает, что сертификат действительно принадлежит
api.example.com, и что делать вместоInsecureSkipVerify, если CA приватный?// The billing API uses a certificate from the company CA, which is not in// the system pool, so calls fail with "certificate signed by unknown authority".func newBillingClient(companyCA []byte) (*http.Client, error) { pool, err := x509.SystemCertPool() if err != nil { return nil, err…Что меняет HTTP/3 поверх QUIC по сравнению с HTTP/2 поверх TCP (рукопожатие, head-of-line blocking, миграция соединения) и нужен ли он API на Go?
Чем балансировщик L4 отличается от L7 и что каждый из них видит в запросе и может с ним сделать?
Чем прямой прокси отличается от обратного и как сервису на Go за прокси узнать настоящий IP клиента, не доверяя подделанному
X-Forwarded-For?// The address ranges of our own load balancers and ingress proxies.var trustedProxies = []netip.Prefix{netip.MustParsePrefix("10.0.0.0/8")} func trusted(ip netip.Addr) bool { return slices.ContainsFunc(trustedProxies, func(p netip.Prefix) bool { return p.Contains(ip) })}…Как сервису на Go хранить пароли пользователей, почему SHA-256 здесь не подходит и чем отличаются
bcryptиargon2idизgolang.org/x/crypto?// bcrypt: the salt and the cost travel inside the result, "$2a$12$<salt><hash>".func hashPassword(pw string) (string, error) { h, err := bcrypt.GenerateFromPassword([]byte(pw), 12) // ErrPasswordTooLong past 72 bytes return string(h), err}…JWT или серверные сессии: в чём компромиссы, где браузеру хранить токен и что такое IDOR?
Найдите баг: JWT, выпущенный тестовым скриптом два года назад, до сих пор проходит аутентификацию в продакшене.
var secret = []byte(os.Getenv("JWT_SECRET")) // userID authenticates every request to the orders API.func userID(raw string) (string, error) { tok, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) { return secret, nil }) if err != nil { return "", err } return tok.Claims.GetSubject()}Как работает OAuth 2.0 authorization code flow с PKCE и что OpenID Connect добавляет поверх OAuth?
var conf = &oauth2.Config{ ClientID: "orders-web", ClientSecret: "from-the-secret-store", // a backend is a confidential client RedirectURL: "https://app.example.com/callback", Scopes: []string{oidc.ScopeOpenID, "email"}, Endpoint: oauth2.Endpoint{AuthURL: "https://id.example.com/authorize", TokenURL: "https://id.example.com/token"},…Эта функция проверяет HMAC-подпись вебхука, прежде чем хендлер доверится телу. Какие две уязвимости в ней есть и как их исправить?
// The provider sends X-Signature: hex(HMAC-SHA256(secret, body)).func verifyWebhook(r *http.Request, secret []byte) ([]byte, error) { body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20)) if err != nil { return nil, err } mac := hmac.New(sha256.New, secret) mac.Write(body) want := hex.EncodeToString(mac.Sum(nil)) if r.Header.Get("X-Signature") != want { return nil, errors.New("bad signature") } return body, nil}Найдите баг: эндпоинт скачивания файлов позволяет любому пользователю прочитать
/etc/passwdи конфиг самого сервиса.// filesDir is "/srv/app/uploads"; the config lives in /srv/app/config.yaml.// Registered as mux.HandleFunc("GET /download", download).func download(w http.ResponseWriter, r *http.Request) { name := r.URL.Query().Get("name") // "report.pdf" http.ServeFile(w, r, filepath.Join(filesDir, name))}Сервис запрашивает URL вебхука, который задал пользователь. Что такое SSRF и как заблокировать
169.254.169.254и внутренние хосты, в том числе через DNS rebinding?var cgnat = netip.MustParsePrefix("100.64.0.0/10") // carrier-grade NAT, not in IsPrivate // Control runs on every dial, after DNS, with the IP about to be connected,// so a rebinding answer or a redirect to 10.0.0.5 is checked as well.func publicOnly(network, address string, _ syscall.RawConn) error { ap, err := netip.ParseAddrPort(address)…Как работает взаимный TLS (mTLS) между двумя сервисами на Go и какие поля
tls.Configдолжна задать каждая сторона, чтобы ни одна не говорила с самозванцем?// Server: only callers with a certificate from our CA, and only the allowed ones.func serverTLS(cert tls.Certificate, clientCAs *x509.CertPool, allowed []string) *tls.Config { return &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tls.RequireAndVerifyClientCert, // RequireAnyClientCert does not verify ClientCAs: clientCAs,…