Thirteen thousand WordPress sites are hacked every single day. Not because WordPress developers are incompetent, but because the platform's architecture makes security a responsibility that falls on every plugin author, every theme developer, and every site administrator individually. One misconfigured plugin, one outdated dependency, one exposed admin panel -- and the entire site is compromised.
FLIN takes a radically different approach. Security is not a feature you enable. It is not a middleware you add. It is not a library you install. It is a consequence of the language design itself. Every one of the OWASP Top 10 vulnerabilities is addressed at the language level, where the fix applies to every application automatically and cannot be bypassed.
This article walks through each of the ten vulnerability categories and shows exactly how FLIN eliminates or mitigates them.
The Rust Foundation
Before examining individual vulnerabilities, it is worth understanding what FLIN inherits from its implementation language. The FLIN runtime is written in Rust, which eliminates entire classes of memory safety vulnerabilities at compile time:
Buffer Overflows -- Compile-time bounds checking
Use-After-Free -- Ownership system prevents
Double-Free -- Single owner guarantee
Null Pointer Dereference -- Option<T> forces explicit handling
Data Races -- Borrow checker prevents
Memory Leaks -- RAII automatic cleanup
Dangling Pointers -- Lifetime system prevents
Integer Overflows -- Checked in debug, explicit in releaseMicrosoft has stated that 70% of all security vulnerabilities in their products stem from memory safety issues. Google found that 70% of high-severity Chromium bugs are memory-related. By choosing Rust for the FLIN runtime, these vulnerabilities simply do not exist. They are not mitigated. They are not reduced. They are eliminated.
A01: Broken Access Control
Broken access control is the number one vulnerability in the OWASP Top 10. It occurs when an application fails to enforce who can access what.
In FLIN, access control is declarative and enforced at the routing level:
flin// app/api/admin/users.flin
guard auth // Must be authenticated
guard role("admin") // Must be admin
route GET {
User.all
}
route DELETE {
guard owner(params.id) // Must own resource or be admin
user = User.find(params.id)
delete user
{ success: true }
}Guards are evaluated before the handler executes. There is no way to bypass them. There is no code path that skips the check. If the guard fails, the response is sent and the handler never runs.
The middleware system provides directory-level protection:
flin// app/admin/_middleware.flin
middleware {
if session.user == none {
redirect("/login")
}
next()
}Every file in the admin/ directory is protected. Adding a new admin page means creating a file in that directory -- the protection is inherited automatically.
A02: Cryptographic Failures
Cryptographic failures occur when applications use weak algorithms, hardcoded keys, or fail to encrypt sensitive data.
FLIN's built-in cryptographic functions use modern, secure algorithms by default:
flin// Password hashing -- Argon2id by default (2024 recommendation)
hash = hash_password(password)
is_valid = verify_password(password, hash)
// JWT tokens -- signed with HMAC-SHA256 or RS256
token = create_token(user, { expires: "7d" })
claims = verify_token(token)
// Encryption -- AES-256-GCM
encrypted = encrypt(data, key: env("ENCRYPTION_KEY"))
decrypted = decrypt(encrypted, key: env("ENCRYPTION_KEY"))There is no option to use MD5, SHA-1, or DES. There is no way to create an unsigned JWT. There is no function that performs "encryption" with Base64 encoding. The secure algorithm is the only algorithm.
A03: Injection
SQL injection is the most notorious web vulnerability. It occurs when user input is concatenated into database queries.
FLIN makes SQL injection impossible because FLIN has no SQL:
flin// FLIN: Entity queries are parameterized by design
users = User.where(email == input_email)
// Compiles to parameterized query internally -- no string concatenation
// Intent queries parse semantics, not concatenate strings
results = ask "users who signed up last week"
// The AI translates the intent -- user input never becomes SQLThere is no raw_query() function. There is no way to execute arbitrary SQL. The entity query system compiles to parameterized queries in the runtime, and the parameters are bound, not interpolated.
XSS injection is similarly prevented. FLIN's view templates automatically escape all output:
flinuser_input = "<script>alert('xss')</script>"
<p>{user_input}</p>
// Renders: <p><script>alert('xss')</script></p>A04: Insecure Design
Insecure design covers architectural flaws that cannot be fixed by correct implementation. FLIN addresses this through secure defaults:
flinentity User {
email: text @unique
password: text @hidden // Never sent to client
role: text = "user" // Default role, not admin
login_attempts: int = 0
locked_until: time?
}The @hidden decorator ensures password hashes never appear in API responses or view templates. The default role is always the least-privileged option. Account lockout fields are part of the entity pattern, not an afterthought.
A05: Security Misconfiguration
Security misconfiguration happens when secure settings exist but are not enabled. FLIN eliminates this by removing configuration entirely:
flin// There is no security configuration file.
// Security headers are automatic in production.
// HTTPS is automatic with Let's Encrypt.
// Debug mode is disabled in production.
// Directory listing is disabled.
// Stack traces are hidden from clients.Zero configuration means zero misconfiguration. The secure behavior is the only behavior.
A06: Vulnerable and Outdated Components
The average Express.js application has 400+ transitive dependencies. The average WordPress installation has dozens of plugins, each with their own dependency tree. Every dependency is a potential vulnerability.
FLIN has zero runtime dependencies:
FLIN Binary Size: approximately 15 MB
WordPress + Plugins: 500 MB - 2 GB
FLIN Dependencies: 0 runtime packages
Express Application: 400+ npm packagesThere is no npm install. There is no composer require. There is no package manager. There is no supply chain. The entire runtime is a single binary compiled from audited Rust code.
A07: Identification and Authentication Failures
Authentication failures include weak passwords, missing rate limiting, and exposed credentials. FLIN's built-in auth system addresses all of these:
flinguard rate_limit(5, 60) // 5 attempts per minute
route POST "/login" {
user = User.where(email == body.email).first
if user != none && user.locked_until != none && user.locked_until > now {
return error(423, "Account locked")
}
if user == none || !verify_password(body.password, user.password) {
if user != none {
user.login_attempts = user.login_attempts + 1
if user.login_attempts >= 5 {
user.locked_until = now + 15.minutes
}
save user
}
return error(401, "Invalid credentials")
}
user.login_attempts = 0
save user
create_session(user)
}Rate limiting prevents brute force. Account lockout stops credential stuffing. Timing-safe password comparison prevents timing attacks. The same error message for "user not found" and "wrong password" prevents email enumeration.
A08: Software and Data Integrity Failures
This category covers attacks where external resources are tampered with -- CDN hijacking, CI/CD compromise, unsigned updates.
FLIN applications serve all assets from the same origin. There are no CDN dependencies, no external script tags, and no runtime package downloads. Content Security Policy headers are set automatically:
httpContent-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'No external script can execute. No external stylesheet can be loaded. The attack surface is limited to the single FLIN binary.
A09: Security Logging and Monitoring Failures
Many applications fail to log security-relevant events, making it impossible to detect attacks or investigate breaches.
FLIN's temporal model provides automatic audit logging for all entity changes:
flin// Every entity change is recorded in the temporal model
user @ yesterday // What was the state yesterday?
user.history // All changes ever made to this entityAuthentication events are logged automatically. Failed login attempts, successful logins, password changes, session creation and destruction -- all captured without any developer code.
A10: Server-Side Request Forgery (SSRF)
SSRF attacks trick the server into making requests to internal resources. FLIN's HTTP functions validate URLs and block internal addresses:
flin// Configuration in flin.config
http {
allowed_domains = ["api.stripe.com", "api.sendgrid.com"]
block_internal = true // Block 10.*, 192.168.*, localhost, 127.0.0.1
}
// Runtime enforcement
response = http_get(url) // Validated against allowed_domainsThe block_internal setting prevents requests to private IP ranges, localhost, and link-local addresses. This is enabled by default. An application cannot be used as a proxy to scan internal networks.
The Compound Effect
Any single security measure can be circumvented by a determined attacker. The value of FLIN's approach is the compound effect: every layer of the application stack is hardened simultaneously. Rust eliminates memory bugs. Entity queries eliminate injection. Guards eliminate access control failures. Automatic headers eliminate misconfiguration. Zero dependencies eliminate supply chain attacks. The temporal model eliminates logging failures.
An attacker would need to find a vulnerability that bypasses ALL of these protections simultaneously. That is a fundamentally different security posture than a WordPress installation where any one of 70,000 plugins can compromise the entire system.
In the next article, we go deep on one specific security feature: Argon2 password hashing, the algorithm that FLIN uses by default for every password in every application.
This is Part 106 of the "How We Built FLIN" series, documenting how a CEO in Abidjan and an AI CTO designed and built a programming language from scratch.
Series Navigation: - [105] Response Helpers and Status Codes - [106] Security by Design: OWASP Top 10 in the Language (you are here) - [107] Argon2 Password Hashing Built Into FLIN - [108] JWT Authentication in 3 Lines of FLIN