[BEZPIECZEŃSTWO] Najlepsze praktyki bezpieczeństwa Base64
Ważne kwestie bezpieczeństwa przy pracy z kodowaniem Base64 w aplikacjach webowych.
// BASE64 TO NIE SZYFROWANIE
Najkrytyczniejszym błędnym wyobrażeniem o bezpieczeństwie jest traktowanie Base64 jako szyfrowania. Base64 to tylko kodowanie - jest całkowicie odwracalny bez żadnego klucza czy hasła.
Każdy może natychmiast dekodować dane Base64. Nigdy nie polegaj na Base64 dla bezpieczeństwa lub ochrony danych.
// ❌ ŹLE: Używanie Base64 jako 'bezpieczeństwa'
const password = 'secret123';
const encoded = btoa(password); // cGFzc3dvcmQ=
// Każdy może to natychmiast odkodować!
// ✅ DOBRZE: Odpowiednie hashowanie hasła
import bcrypt from 'bcrypt';
const password = 'secret123';
const hashedPassword = await bcrypt.hash(password, 12);
// To jest rzeczywiście bezpieczne
// WALIDACJA WEJŚCIA
Zawsze waliduj wejście Base64 aby zapobiec atakom iniekcji i błędom aplikacji:
Odpowiednia walidacja zapobiega złośliwemu wejściu powodującemu problemy bezpieczeństwa lub awarie aplikacji.
// Waliduj format Base64
function isValidBase64(str) {
// Sprawdź format: tylko prawidłowe znaki Base64
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
if (!base64Regex.test(str)) {
return false;
}
// Sprawdź długość (musi być wielokrotnością 4)
if (str.length % 4 !== 0) {
return false;
}
// Test dekodowania
try {
atob(str);
return true;
} catch (e) {
return false;
}
}
// Bezpieczne dekodowanie z walidacją
function safeBase64Decode(input, maxLength = 10000) {
if (typeof input !== 'string') {
throw new Error('Wejście musi być ciągiem znaków');
}
if (input.length > maxLength) {
throw new Error('Wejście zbyt długie');
}
if (!isValidBase64(input)) {
throw new Error('Nieprawidłowy Base64');
}
return atob(input);
}
// ZAPOBIEGANIE XSS
Dane Base64 mogą zawierać złośliwe skrypty po dekodowaniu. Zawsze oczyszczaj wyjście przy wyświetlaniu zdekodowanej zawartości:
Nigdy nie ufaj wejściu Base64 od użytkowników. Zawsze oczyszczaj przed renderowaniem w HTML.
// ❌ NIEBEZPIECZNE: Bezpośrednie wstrzykiwanie HTML
function displayDecodedData(base64) {
const decoded = atob(base64);
document.innerHTML = decoded; // Podatność XSS!
}
// ✅ BEZPIECZNE: Oczyszczaj wyjście
function safeDisplayDecodedData(base64) {
const decoded = atob(base64);
// Utwórz węzeł tekstowy (bez wykonywania HTML)
const textNode = document.createTextNode(decoded);
container.appendChild(textNode);
// Lub escapuj jednostki HTML
const escaped = decoded
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
container.innerHTML = escaped;
}
// LIMITY ROZMIARU
Kodowanie Base64 zwiększa rozmiar danych o ~33%. Implementuj limity rozmiaru aby zapobiec atakom DoS:
Nieograniczone wejście Base64 może zużywać nadmierną pamięć i moc obliczeniową.
- > Ustaw maksymalne limity długości wejścia
- > Monitoruj użycie pamięci podczas przetwarzania
- > Implementuj timeouty dla długich operacji
- > Używaj strumieniowania dla dużych zbiorów danych
- > Rozważ kompresję przed kodowaniem
- > Ogranicz szybkość operacji Base64
// BEZPIECZNA OBSŁUGA TOKENÓW
Przy używaniu Base64 dla tokenów lub wrażliwych ID, przestrzegaj najlepszych praktyk bezpieczeństwa:
Odpowiednia obsługa tokenów zapobiega nieautoryzowanemu dostępowi i atakom opartym na tokenach.
// Tworzenie bezpiecznego tokenu
function createSecureToken() {
// Używaj kryptograficznie bezpiecznych wartości losowych
const array = new Uint8Array(32);
crypto.getRandomValues(array);
// Konwertuj do Base64 i zrób URL-safe
const base64 = btoa(String.fromCharCode(...array))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
return base64;
}
// Bezpieczna walidacja tokenu
function validateToken(token, expectedLength = 43) {
if (typeof token !== 'string') {
return false;
}
// Sprawdź długość
if (token.length !== expectedLength) {
return false;
}
// Sprawdź format URL-safe Base64
const urlSafeBase64Regex = /^[A-Za-z0-9_-]+$/;
return urlSafeBase64Regex.test(token);
}
// BEZPIECZEŃSTWO DATA URI
Base64 data URI mogą zawierać złośliwą zawartość. Zawsze waliduj i oczyszczaj data URI:
Złośliwe data URI mogą wykonywać skrypty, ładować zewnętrzne zasoby lub zawierać nieodpowiednią zawartość.
// Waliduj data URI
function validateDataURI(dataUri, allowedTypes = ['image/png', 'image/jpeg']) {
const dataUriRegex = /^data:([a-zA-Z0-9][a-zA-Z0-9\/+]*);base64,(.+)$/;
const match = dataUri.match(dataUriRegex);
if (!match) {
throw new Error('Nieprawidłowy format data URI');
}
const [, mimeType, base64Data] = match;
// Waliduj typ MIME
if (!allowedTypes.includes(mimeType)) {
throw new Error(`Nieobsługiwany typ MIME: ${mimeType}`);
}
// Waliduj dane Base64
if (!isValidBase64(base64Data)) {
throw new Error('Nieprawidłowy Base64 w data URI');
}
// Sprawdź rozmiar
const sizeEstimate = (base64Data.length * 3) / 4;
if (sizeEstimate > 1024 * 1024) { // limit 1MB
throw new Error('Data URI zbyt duży');
}
return { mimeType, base64Data };
}
// LISTA KONTROLNA BEZPIECZNEJ IMPLEMENTACJI
- > Nigdy nie używaj Base64 jako szyfrowania lub środka bezpieczeństwa
- > Zawsze waliduj format i długość wejścia Base64
- > Oczyszczaj zdekodowane wyjście przed wyświetlaniem
- > Implementuj limity rozmiaru i timeouty
- > Używaj URL-safe Base64 dla aplikacji webowych
- > Waliduj typy MIME dla data URI
- > Używaj kryptograficznie bezpiecznych wartości losowych dla tokenów
- > Implementuj odpowiednią obsługę błędów
- > Monitoruj potencjalne ataki DoS
- > Regularne audyty bezpieczeństwa kodu obsługi Base64