Back to flin
flin

Validation and Sanitization Functions

How FLIN ships 67 validation and sanitization functions as built-ins -- from email and URL checks to HTML sanitization and SQL injection prevention, all without importing a library.

Thales & Claude | March 25, 2026 10 min flin
flinvalidationsanitizationinput

Every web application has the same vulnerability: user input. A form field that expects an email address receives JavaScript injection. A search box that expects text receives an SQL query. A comment field that expects words receives a Hello!" safe = sanitize_html(comment) // "Hello!" -- the script tag is removed ```

Validation rejects bad input at the boundary. Sanitization neutralizes input that passes validation but might still be dangerous in a specific context (HTML display, SQL queries, URL construction).

Validation Functions

Text Format Validation

text.is_email              // RFC 5322 simplified email check
text.is_url                // Valid URL with protocol
text.is_ip                 // IPv4 or IPv6 address
text.is_ipv4               // IPv4 address only
text.is_ipv6               // IPv6 address only
text.is_uuid               // UUID v4 format
text.is_json               // Valid JSON string
text.is_hex                // Hexadecimal characters only
text.is_base64             // Valid base64 string

Each validation function returns a boolean. No exceptions. No error objects. Just true or false. If you need to know why validation failed (for user-facing error messages), the entity constraint system provides that:

entity User {
    email: text where is_email  // Constraint with automatic error message
    age: int where >= 13 and <= 120
    username: text where len >= 3 and len <= 30
}

// When validation fails, you get a specific error: result = User.create(email: "not-an-email", age: 10) // Error: "email: must be a valid email address" // Error: "age: must be >= 13" ```

Numeric Validation

text.is_numeric            // All digits (0-9)
text.is_alpha              // All letters (a-z, A-Z)
text.is_alphanumeric       // Letters and digits only
text.is_integer            // Valid integer string ("-42", "0", "100")
text.is_float              // Valid float string ("3.14", "-0.5")

These functions validate string content without converting it. "42".is_numeric returns true without producing an integer value. This is the correct approach for form validation: first check that the input is valid, then convert it.

Pattern Validation

text.matches(pattern)       // Regex match
text.is_phone              // International phone number format
text.is_credit_card        // Credit card number (Luhn check)
text.is_hex_color          // "#ff6b35" or "#f63"
text.is_slug               // URL slug (lowercase, hyphens, no spaces)
text.is_semver             // Semantic version ("1.2.3")

is_phone validates international phone numbers with country codes. It does not validate that the number exists -- only that its format is plausible. This is sufficient for most web applications, where phone verification happens via SMS.

is_credit_card performs a Luhn checksum validation. It does not validate that the card is active or has funds -- that requires a payment processor API call. But the Luhn check catches typos and random numbers, preventing unnecessary API calls.

Length and Range Validation

text.len_between(3, 50)    // Length between 3 and 50 characters
text.len_min(3)            // At least 3 characters
text.len_max(50)           // At most 50 characters
n.between(1, 100)          // Number in range [1, 100]
n.positive                 // Greater than 0
n.negative                 // Less than 0

These are convenience wrappers around comparisons. text.len_between(3, 50) is equivalent to text.len >= 3 and text.len <= 50, but it reads better in validation chains and entity constraints.

Sanitization Functions

HTML Sanitization

HTML sanitization is the primary defense against Cross-Site Scripting (XSS) attacks. FLIN provides three levels:

// Level 1: Escape HTML entities (preserve all text, neutralize HTML)
html_escape("<script>alert('xss')</script>")
// "&lt;script&gt;alert('xss')&lt;/script&gt;"

// Level 2: Strip all HTML tags (keep text content only) strip_tags("Hello World") // "Hello World"

// Level 3: Sanitize HTML (keep safe tags, remove dangerous ones) sanitize_html("Bold Link") // "Bold Link" ```

html_escape converts every <, >, &, ", and ' to their HTML entity equivalents. This is the safest approach -- it preserves the input text but ensures nothing is interpreted as HTML.

strip_tags removes all HTML tags and returns only the text content. This is useful when you need plain text from user input that might contain HTML (pasted from a rich text editor, for example).

sanitize_html is the most sophisticated option. It maintains a whitelist of safe tags (, , ,

,
,

Responses

Write a response
0/2000
Loading responses...

Related Articles