Skip to content

PROPERTY BASED TESTING

github-actions[bot] edited this page Feb 23, 2026 · 1 revision

Property-Based and Fuzz Testing Strategy

Overview

This document describes the property-based and fuzz testing strategy for security-critical code in nself-chat. These tests use the fast-check library to generate random inputs and verify security invariants.

Testing Approach

Property-Based Testing

Property-based tests verify that certain properties (invariants) hold true for all possible inputs:

  • Determinism: Same input always produces same output
  • Idempotence: Running operation multiple times has same effect as once
  • Reversibility: Encrypt/decrypt roundtrips preserve original data
  • Boundary Conditions: Edge cases are handled correctly
  • No Exceptions: Functions never throw on valid input types

Fuzz Testing

Fuzz tests use malformed, unexpected, or malicious inputs to find vulnerabilities:

  • Injection Attempts: SQL, XSS, command injection patterns
  • Protocol Bypasses: URL manipulation, encoding tricks
  • Unicode Edge Cases: Emoji, RTL, zero-width characters
  • Binary Edge Cases: Empty data, all zeros, very large inputs

Test Coverage

1. Input Validation (src/lib/security/__tests__/input-validation.property.test.ts)

Tests: 40+ property tests, 1000+ assertions

Username Validation

  • βœ… Accepts valid alphanumeric + underscore + hyphen (3-30 chars)
  • βœ… Rejects invalid characters
  • βœ… Rejects too short/long usernames
  • βœ… Never throws on any string input

Email Validation

  • βœ… Accepts valid email formats
  • βœ… Rejects emails without @ symbol
  • βœ… Rejects overly long emails (>255 chars)
  • βœ… Never throws on any string input

Password Validation

  • βœ… Enforces uppercase requirement
  • βœ… Enforces lowercase requirement
  • βœ… Enforces number requirement
  • βœ… Enforces special character requirement
  • βœ… Never throws on any string input

HTML Sanitization

  • βœ… Always returns a string
  • βœ… Removes all <script> tags
  • βœ… Removes onclick handlers
  • βœ… Preserves safe HTML tags
  • βœ… Never throws on any input

Text Sanitization

  • βœ… Escapes all HTML entities (<, >, &, etc.)
  • βœ… Never contains unescaped < or >
  • βœ… Always returns a string

Filename Sanitization

  • βœ… Removes path traversal attempts (..)
  • βœ… Removes all forward/backslashes
  • βœ… Removes invalid filename characters (<>:"|?*)

URL Sanitization

  • βœ… Accepts HTTP/HTTPS URLs
  • βœ… Rejects javascript: protocol
  • βœ… Rejects data: protocol
  • βœ… Blocks localhost in production

SQL Injection Prevention

  • βœ… Escapes LIKE pattern wildcards (%, _)
  • βœ… Validates SQL identifiers (no special chars)
  • βœ… Never allows unescaped wildcards

NoSQL Injection Prevention

  • βœ… Removes all $operator keys
  • βœ… Preserves non-operator keys
  • βœ… Recursively sanitizes nested objects

Command Injection Prevention

  • βœ… Validates shell arguments (alphanumeric only)
  • βœ… Rejects shell metacharacters (&|;<>$`())
  • βœ… Escapes arguments with single quotes

Unicode Edge Cases

  • βœ… Handles zero-width characters
  • βœ… Handles emoji and unicode symbols
  • βœ… Handles RTL override characters
  • βœ… Handles combining characters

2. SSRF Protection (src/lib/security/__tests__/ssrf-protection.property.test.ts)

Tests: 35+ property tests, 800+ assertions

Protocol Validation

  • βœ… Accepts HTTP and HTTPS
  • βœ… Rejects javascript: protocol
  • βœ… Rejects data: protocol
  • βœ… Rejects file: protocol
  • βœ… Rejects ftp: protocol

Localhost Blocking

  • βœ… Blocks "localhost" hostname
  • βœ… Blocks 127.0.0.1
  • βœ… Blocks IPv6 localhost (::1)
  • βœ… Blocks all 127.x.x.x range

Private IP Blocking

  • βœ… Blocks 10.x.x.x range
  • βœ… Blocks 192.168.x.x range
  • βœ… Blocks 172.16-31.x.x range
  • βœ… Blocks 169.254.x.x link-local range

Cloud Metadata Blocking

  • βœ… Blocks 169.254.169.254 (AWS/GCP/Azure)
  • βœ… Blocks 100.100.100.200 (Alibaba Cloud)
  • βœ… Blocks metadata hostnames

IPv6 Edge Cases

  • βœ… Handles IPv6 addresses with brackets
  • βœ… Blocks private IPv6 ranges
  • βœ… Blocks IPv4-mapped IPv6 localhost
  • βœ… Blocks IPv4-mapped IPv6 private IPs

Bypass Attempt Detection

  • βœ… Detects IP in decimal format
  • βœ… Detects IP in octal format
  • βœ… Detects IP in hex format
  • βœ… Handles @ symbol tricks
  • βœ… Handles backslash tricks

Invariants

  • βœ… Never throws on any string input
  • βœ… Always returns result object with valid field
  • βœ… Provides reason when validation fails
  • βœ… Consistent results on repeated calls

3. Command Parser (src/lib/plugins/slash-commands/__tests__/command-parser.property.test.ts)

Tests: 30+ property tests, 700+ assertions

Tokenizer

  • βœ… Always returns an array
  • βœ… Preserves quoted strings
  • βœ… Handles escaped quotes
  • βœ… Splits on spaces outside quotes

Command Extraction

  • βœ… Returns null for non-commands
  • βœ… Extracts simple commands (/cmd)
  • βœ… Extracts namespaced commands (app:cmd)
  • βœ… Handles commands with arguments

Argument Parsing

  • βœ… Validates string arguments (minLength, maxLength, pattern)
  • βœ… Validates number arguments (min, max, type)
  • βœ… Validates boolean arguments (true/false/yes/no/1/0)
  • βœ… Validates user mentions (@username)
  • βœ… Validates channel references (#channel)
  • βœ… Validates choices constraints

Injection Detection

  • βœ… Handles command injection attempts (; && | `` $())
  • βœ… Handles SQL injection attempts (' OR '1'='1)
  • βœ… Handles XSS attempts (<script>, )
  • βœ… Handles path traversal attempts (../)

Unicode Edge Cases

  • βœ… Handles unicode in command names
  • βœ… Handles emoji in arguments
  • βœ… Handles RTL override characters
  • βœ… Handles zero-width characters

4. E2EE Crypto (src/lib/e2ee/__tests__/crypto.property.test.ts)

Tests: 25+ property tests, 500+ assertions

Random Generation

  • βœ… Generates bytes of requested length
  • βœ… Generates different bytes each call
  • βœ… Device IDs are 32 hex characters
  • βœ… Device IDs are unique
  • βœ… Registration IDs within 14-bit range (0-16383)

Hashing

  • βœ… SHA-256 produces deterministic hashes
  • βœ… SHA-256 produces 32-byte hashes
  • βœ… Different inputs produce different hashes
  • βœ… SHA-512 produces 64-byte hashes
  • βœ… Fingerprints are consistent

Key Derivation

  • βœ… Consistent keys from same password+salt
  • βœ… Keys are correct length (32 bytes)
  • βœ… Different passwords produce different keys
  • βœ… Different salts produce different keys
  • βœ… Verifies correct master keys
  • βœ… Rejects incorrect master keys

Encryption/Decryption

  • βœ… Encrypts to different ciphertext each time (random IV)
  • βœ… IVs are correct length (12 bytes)
  • βœ… Encoded data includes IV + ciphertext

Binary Edge Cases

  • βœ… Handles empty byte arrays
  • βœ… Handles very large byte arrays (1MB+)
  • βœ… Handles all-zero byte arrays
  • βœ… Handles all-ones byte arrays
  • βœ… Handles repeating patterns

Password Strength

  • βœ… Handles weak passwords
  • βœ… Handles very long passwords (10KB+)
  • βœ… Handles special characters
  • βœ… Handles null bytes
  • βœ… Handles emoji passwords

5. Log Sanitizer (src/lib/privacy/__tests__/log-sanitizer.property.test.ts)

Tests: 35+ property tests, 900+ assertions

String Operations

  • βœ… Masking preserves prefix/suffix
  • βœ… Email masking preserves domain
  • βœ… Phone masking preserves last 4 digits
  • βœ… Truncation respects max length

Secret Detection

  • βœ… Detects high-entropy strings
  • βœ… Detects secret prefixes (sk_, pk_, ghp_, AKIA)
  • βœ… Does not flag normal words

Log Entry Sanitization

  • βœ… Always returns result object
  • βœ… Never throws on any log entry
  • βœ… Redacts password fields
  • βœ… Hashes session IDs
  • βœ… Masks email addresses
  • βœ… Preserves user IDs

Pattern Matching

  • βœ… Detects JWT tokens
  • βœ… Detects Bearer tokens
  • βœ… Detects IPv4 addresses
  • βœ… Detects AWS access keys
  • βœ… Detects credit card numbers

Nested Objects

  • βœ… Recursively sanitizes nested objects
  • βœ… Sanitizes arrays of objects
  • βœ… Handles circular references

Unicode Edge Cases

  • βœ… Handles emoji in messages
  • βœ… Handles RTL characters
  • βœ… Handles zero-width characters
  • βœ… Handles mixed scripts

Running the Tests

Run All Property Tests

# Run all property-based tests
pnpm jest --testNamePattern="Property Tests|Fuzz Tests"

# Run with coverage
pnpm jest --coverage --testNamePattern="Property Tests|Fuzz Tests"

Run Specific Test Suites

# Input validation
pnpm jest src/lib/security/__tests__/input-validation.property.test.ts

# SSRF protection
pnpm jest src/lib/security/__tests__/ssrf-protection.property.test.ts

# Command parser
pnpm jest src/lib/plugins/slash-commands/__tests__/command-parser.property.test.ts

# E2EE crypto
pnpm jest src/lib/e2ee/__tests__/crypto.property.test.ts

# Log sanitizer
pnpm jest src/lib/privacy/__tests__/log-sanitizer.property.test.ts

Configuration

Property tests are configured with different numRuns based on complexity:

  • Simple properties: 2000 runs (e.g., "never throws")
  • Standard properties: 1000 runs (e.g., determinism)
  • Complex properties: 500 runs (e.g., nested validation)
  • Expensive properties: 100 runs (e.g., async crypto operations)
  • Very expensive: 10-20 runs (e.g., large data crypto)

Test Statistics

Test Suite Tests Runs per Test Total Assertions
Input Validation 42 500-2000 50,000+
SSRF Protection 38 200-1000 20,000+
Command Parser 32 500-2000 35,000+
E2EE Crypto 28 20-1000 15,000+
Log Sanitizer 37 200-2000 30,000+
TOTAL 177 varies 150,000+

Security Properties Verified

1. Injection Prevention

  • βœ… No SQL injection via user input
  • βœ… No XSS via HTML sanitization
  • βœ… No command injection via shell escaping
  • βœ… No NoSQL injection via operator filtering
  • βœ… No path traversal via filename sanitization

2. SSRF Prevention

  • βœ… No localhost access
  • βœ… No private IP access
  • βœ… No cloud metadata access
  • βœ… No protocol bypasses
  • βœ… No DNS rebinding

3. Data Protection

  • βœ… Passwords always hashed with salt
  • βœ… Secrets detected and redacted in logs
  • βœ… PII masked or hashed
  • βœ… Session IDs hashed
  • βœ… Encryption uses random IVs

4. Cryptographic Security

  • βœ… Keys derived with PBKDF2 (100K iterations)
  • βœ… Random generation uses crypto-secure PRNG
  • βœ… Hash functions are deterministic
  • βœ… Different inputs produce different hashes
  • βœ… Key verification uses constant-time comparison

5. Input Validation

  • βœ… All user input validated
  • βœ… Type coercion is safe
  • βœ… Length limits enforced
  • βœ… Pattern matching works correctly
  • βœ… Unicode handled safely

Continuous Testing

These property-based tests are run:

  1. On every commit (CI pipeline)
  2. Before every merge (PR checks)
  3. Nightly (extended runs with higher iteration counts)
  4. Before releases (full security audit)

Future Improvements

  1. Increase test coverage:

    • Add property tests for more parsers
    • Test more crypto operations
    • Add fuzzing for API endpoints
  2. Performance testing:

    • Add property tests for time complexity
    • Verify no ReDoS vulnerabilities in regex
    • Test memory usage under load
  3. Integration testing:

    • Property tests across module boundaries
    • End-to-end security flows
    • Real-world attack scenarios
  4. Continuous fuzzing:

    • Integrate with OSS-Fuzz
    • Run fuzzing on CI infrastructure
    • Automated security regression testing

References


🎯 Getting Started


✨ Features

Core Features

Communication

Security & Privacy

(See πŸ” Security section below for 2FA, PIN Lock, and security audits.)

Interactive

(Search lives in πŸ“š Reference below.)

Extensibility


πŸ“– Guides

User Guides

Developer Guides

Enterprise

Backend

Deployment


βš™οΈ Configuration


πŸ“‘ API

API Documentation


πŸš€ Deployment


πŸ“š Reference

Architecture

Quick Reference


πŸ” Security


πŸ†˜ Help


ℹ️ About


πŸ”— Links


v1.0.0 β€’ 2026

Clone this wiki locally