Live & Continuously Monitored

Security Status

LabelingIQ runs an automated security assessment of its own application and infrastructure around the clock - software composition analysis, static and dynamic application security testing, SSL/TLS, and infrastructure hardening checks, all shown here in real time.

All Systems Secure
25 Tests Passed  ·  Last checked Oct 2, 2026, 4:16 AM

Software Composition Analysis (SCA)

2 Tests Passed
Dependency Vulnerability Scan
npm audit found no known vulnerabilities across 600 scanned dependencies. (from the last successful scan at install time, 2026-09-28T16:21:28.814Z - this environment has no live registry access at runtime.)
Dependency Lockfile Integrity
package-lock.json is present and pins exact versions for all 30 direct dependencies (lockfile version 3).

Static Application Security Testing (SAST)

4 Tests Passed
No Dangerous eval()/Function() Usage
Scanned 164 source files - no eval() or Function() constructor usage found.
No Hardcoded Credentials in Source
Scanned 164 source files for hardcoded credentials (AWS keys, Stripe live keys, private key material, generic secret literals) - none found.
Parameterized Database Queries
All database access goes through Sequelize's parameterized ORM methods, except src/services/databaseService.js, src/services/schemaGuard.js, which run SQL the ORM cannot express - admin-authored queries against a company's own external database, and the application's own schema file. Each is constrained at runtime by a guard that makes misuse throw rather than execute (assertReadOnlySql() restricts the former to read-only statements; assertTrustedSchemaPath() restricts the latter to the repository's own db/schema.sql), and neither builds SQL by interpolating untrusted input.
Cryptographically Secure Token Generation
All tokens/passwords are generated with crypto.randomBytes()/crypto.randomUUID() (cryptographically secure) - no Math.random() usage found in application source.

Dynamic Application Security Testing (DAST)

3 Tests Passed
Live Security Response Headers
Live response to GET / includes: x-content-type-options, x-frame-options, strict-transport-security.
Reflected XSS Probe
A reflected-XSS probe (<script>alert(1)</script>) on GET /login?error= was correctly HTML-escaped in the response.
No Verbose Error Disclosure
The 404 response for an unknown path reveals no internal file paths, stack traces, or framework details.

In-Code Security Middleware

2 Tests Passed
Security Headers Middleware (Helmet) Active
This application's Content-Security-Policy is configured with a per-request nonce on script-src and no 'unsafe-inline' anywhere (src/middleware/security.js). Note the Content-Security-Policy header observed on this response ("upgrade-insecure-requests") is not the policy this app emits - it carries no script-src at all - so an upstream reverse proxy or managed host is replacing the header in front of Node. That is a deployment/platform setting, not an application misconfiguration.
Rate-Limiting Middleware Active
Rate-limiting middleware is active on auth endpoints (RateLimit-Limit: 120 requests per window).

Sitewide SSL

2 Tests Passed
HTTPS Enforcement
This origin is served over HTTPS with TLS terminating upstream at a reverse proxy or load balancer (no local certificate is configured on the Node process itself - see the SSL/TLS Certificate Validity check). HSTS is also advertised, so browsers refuse plaintext on subsequent visits.
SSL/TLS Certificate Validity
TLS is terminated upstream of this process (no local certificate file, which is expected for this deployment). The certificate actually served to browsers for labelingiq.com is valid and trusted: issued by Let's Encrypt to labelingiq.com, valid until 2026-11-09T22:51:01.000Z (39 days remaining).

Password Security

1 Test Passed
Salted scrypt Password Hashing
Employee passwords are hashed with salted scrypt (src/utils/hash.js) - a deliberately slow, memory-hard KDF with a unique per-password salt - and verified in constant time. Legacy unsalted SHA-256 hashes are still accepted for verification only, and are transparently re-hashed on the owner's next successful sign-in (see services/authService.js).

HTTP Strict Transport Security (HSTS)

1 Test Passed
HSTS Header Active
HSTS is active with a 365-day max-age: max-age=31536000; includeSubDomains; preload

Secure Cookies

1 Test Passed
Session Cookie Flags (HttpOnly/SameSite/Secure)
Session cookie is configured with httpOnly: true, sameSite: 'lax', and secure: 'auto' (src/app.js) - no live session was observable to probe directly on this request, so this reflects the actual configured session middleware.

Web Server Hardening

3 Tests Passed
X-Powered-By Header Suppressed
X-Powered-By header is not present on live responses (hidden by the helmet middleware).
Request Body Size Limits
JSON and urlencoded request bodies are capped at Express's default 100kb limit (no unbounded override configured), bounding request payload size.
Stack Traces Hidden Outside Development
The production error page (src/views/errors/server-error.ejs) renders a stack trace in exactly one place, gated on NODE_ENV, and the opt-in SHOW_ERROR_DETAIL diagnostic never prints one.

Input Validation

1 Test Passed
Public Form Input Validation (Live Probe)
A live probe submitting a malformed email address to the Get Started signup form was correctly rejected with a validation error, not accepted.

Denial of Service Defense

1 Test Passed
Per-IP Rate Limiting
Per-IP rate limiting is active on authentication endpoints (limit: 120 requests per 15-minute window) and sitewide (global ceiling) to blunt flooding.

Configuration Assessment

4 Tests Passed
Session Secret Strength
SESSION_SECRET is explicitly configured to a non-default value.
Environment Mode Explicitly Configured
NODE_ENV is explicitly set to "production".
Secrets Excluded from Version Control
.gitignore excludes .env and other local secrets/artifacts from version control.
Continuous Automated Re-Assessment
This security assessment itself runs automatically on a recurring schedule (see startSecurityScanScheduler), in addition to whenever this page is loaded, so configuration drift is caught continuously rather than only when someone remembers to check.

This page automatically refreshes every 30 seconds. Checks are also re-run on a recurring background schedule independent of page views, so the results reflect the platform's real, current state - not a static snapshot.

Curious how this holds up for your own data?

Try LabelingIQ free for 7 days. No charge until your trial ends.

Start Free Trial