Blog · Security
Injection attacks beat presentation-only liveness — the frame-level detection that answers back
Presentation attacks reach the camera; injection attacks replace it. Why ISO 30107-3 liveness does not cover injection, and the frame-level signals, spectral forensics and capture-integrity layer that do.
Two attacks, one word: 'liveness'
A presentation attack is something shown to a real camera — a printed photo, a face on a phone screen, a replayed video, a mask. An injection attack skips the camera entirely: a virtual-camera device or a tampered client feeds pre-recorded or synthetic frames straight into the capture path, so the “camera” the server trusts was never pointed at anyone. Deepfakes are a payload, not a category — they arrive by either route.
This distinction is now the buying question. iProov reports virtual-camera attacks rose 2,665% in 2024, and injection has become the criterion analysts tell buyers to test for in 2026. The uncomfortable part, which most vendor pages skip, is that a liveness classifier — of any shape — is largely blind to a good injection, because the injected frames genuinely are frames of a live person. They are just not this moment’s frames, from this camera.
Why ISO 30107-3 conformance does not cover injection
Presentation-attack detection is measured against ISO/IEC 30107-3, and its levels describe how many presentations a system withstands — attacks arriving through the sensor. That is real and worth having, but it says nothing about an attack that bypasses the sensor. Injection needs a different standard: CEN/TS 18099, injection-attack detection, which iBeta began testing against in mid-2026. As of early 2026 iProov is the only holder of its “High” level worldwide.
Certification honesty, up front
We do not hold CEN/TS 18099, iBeta, NIST, ISO or SOC 2 certification of any kind. CEN/TS 18099 testing is on our roadmap, not in our past. When a vendor tells you injection is a solved problem, ask which accredited lab said so and at what level — and read our own status, in plain words, on the trust page. Everything below is engineering we can point at in the API, not a lab result.
The honest tradeoff we start from
Our passive liveness runs over bare REST with no mandatory capture SDK — send a frame from any client. That is a genuine friction win, and against injection it is also the weaker posture: a plain REST upload cannot, by itself, prove the bytes came from a camera rather than a virtual device. We would rather say that than pretend a single passive call solves injection. What follows is the layered answer — frame, spectrum, and capture — where an attacker has to beat all of it and the liveness model in the same submission.
Layer 1: frame-level signals from the stream engine
Injection is a temporal attack, so the strongest answer lives where the engine sees a stream rather than a frame. Continuous liveness ingests frames over a WebSocket and holds properties across them, surfacing named signals when they break:
POST /v1/stream/start # open session + challenge script
GET /v1/stream/{id} # WebSocket: stream frames in
# raised across the session, not per isolated frame:
# IDENTITY_SWITCH face swapped mid-stream (identity broke)
# NO_MOTION static photo — no real head motion at all
# REPLAYED_FRAME looped / re-fed content, inconsistent with live capture
# low sustained liveness EMA drifts below the live envelope over time
# end of session -> one signed verdict + full audit trailEach of these is something a per-frame classifier cannot see. IDENTITY_SWITCH fires when the embedded face stops being the same 512-d identity partway through — the genuine customer starts, the real beneficiary takes over. NO_MOTION catches a static image looped as “video.” REPLAYED_FRAME catches content re-fed into the capture path. The point is not any single flag; it is that an injected stream has to satisfy all of them at once while also answering a randomized challenge it has never seen.
Layer 2: spectral forensics you can read
On still frames, re-captured and screen-replayed imagery leaves a spectral fingerprint. A 2-D FFT of a genuine camera frame looks different from a photo of a screen or a re-encoded synthetic image. Rather than fold that into a bare verdict, the engine exposes the underlying measurements — high_freq_ratio and spectral_peak — so a reviewer can see why a frame was flagged, not just that it was. Explainability is the differentiator here: deepfake responses elsewhere tend to be a single opaque probability.
Layer 3: capture integrity — did these bytes come from a camera, now?
Classification asks “does this look live?” Capture integrity asks a different, harder question: “did these exact bytes come from a real camera, at this moment?” That is the question injection is really attacking, and the engine stacks several independent signals against it:
Exact-replay hashing — the same submission bytes seen before are caught as a replay. EXIF and capture-metadata forensics — editor fingerprints and missing camera metadata flag an image that took a detour through software. C2PA Content Credentials are verified when a manifest is present, surfacing provenance in the AI era. And for clients that support it, Ed25519-signed capture payloads: the SDK signs sha256(selfie_bytes) || capture_nonce, and a capture that is not signed raises CAPTURE_UNSIGNED when you require it.
# optional multipart fields on face-match / liveness / age
attest_platform "ios" | "android"
attest_token base64 (App Attest object, or Play Integrity token)
capture_nonce the challenge the app bound into the attestation
# response gains:
"attestation": { "platform": "...", "verified": true|false, "detail": "..." }
# iOS is verified fully offline against the Apple App Attest root CAA failed attestation never errors the request — it adds the ATTESTATION_FAILED warning, at review severity, or declines when you configure it to. Alongside REPLAYED_IMAGE and EDITED_IMAGE, these are the aggregate verdict’s inputs, so the policy decision is yours to tune per workflow rather than baked into a single number.
No layer is decisive alone — that is the design
What we are and are not claiming
None of these signals is individually decisive, and we do not present any of them as a certified injection defence. A sufficiently good injected stream — a virtual camera feeding a real-time deepfake — can present frames that are individually live-looking, answer challenges and hold one identity. The defensible claim is that the attacker has to beat the temporal model, the spectral forensics, the capture-integrity stack and a randomized challenge in the same submission — and that every signal that fired is in the audit log for a human to review.
If you are evaluating this seriously, the natural next reads are the shapes of liveness detection — passive, active and continuous — the deeper treatment of which attacks each one stops, and the buyer’s vendor checklist with the specific injection questions worth asking.