This document is published in several languages. In the event of any discrepancy between the language versions, the Polish version is binding.
Version 1.1 · Last updated: 22 October 2026
Measures under Art. 32 GDPR with which LW IT Solutions Company Lukas Wójcik, al. Tadeusza Kościuszki 80/82, lok. 301, 90-437 Łódź, Poland, protects the formexposed service. This page forms part of the Data Processing Agreement as Annex 2.
1. Scope and principle
The measures apply to all data processed by the service: to the data we process on behalf of our Customers (described in the Data Processing Agreement), and to the data for which we are controller ourselves, such as customer accounts and logs. There are no separate protection levels for the two; what protects the account also protects the processor data.
Structure under Art. 32(1) GDPR. Pseudonymisation and encryption (point (a)) are covered in section 4; the ongoing confidentiality, integrity, availability and resilience of the systems (point (b)) in sections 3, 5, 6 and 7; the ability to restore availability in a timely manner after an incident (point (c)) in section 7.1; the process for regularly testing, assessing and evaluating effectiveness (point (d)) in section 9. We selected the measures on the basis of the risks described in our Data Protection Impact Assessment, taking into account the state of the art and the costs of implementation.
Principle: measured rather than intended. Only what has actually been implemented in the code or in operation is stated here. What is planned but not yet implemented is expressly listed as “planned” in section 10. A measure that is missing here is not tacitly in place.
Names of machines, internal addresses, ports, user names and software versions are deliberately not stated. They help no one assess the measures, but they do help someone who wants to circumvent them. Anyone who needs them for an audit under the Data Processing Agreement will receive them in the course of that audit under confidentiality, to the extent they are necessary for the audit.
2. Structure of the service
The service runs on two of the provider’s own servers in Poland, located in the same internal network:
- Web server with database. It delivers the application, holds the database, sends notifications and backs up the data. It alone is set up to accept requests from the internet.
- Scan server. It carries out the checks of third-party and own websites in a browser and runs the language model that classifies individual forms, summarises scan findings as prioritised action plans for paid accounts and adds code in “Fix it for me”. It is not set up to accept requests from the internet, but fetches its jobs itself from the web server and returns the results there.
No hosting, data centre or cloud provider is involved in operation, and nothing goes to an external AI service. Which third parties receive data is set out on the page Sub-processors.
3. Confidentiality
3.1 Physical access control
The servers are located in premises of the provider in Poland that are not open to the public. Only the owner has access (as stated by the operator). The exact address of the location is deliberately not given here.
3.2 Access control: logging in to the service
- Passwords are stored only as a hash using PHP’s standard method (bcrypt). If the standard method changes, the hash is renewed at the next login. For a login attempt with an unknown address, the server still calculates a hash, so that the response time does not reveal whether an account exists. Likewise, the response to a password reset request reveals neither by its wording nor by its duration whether the account exists; reset e-mails are sent to the same address at most three times per hour. New passwords must be at least ten characters long and may not exceed 72 bytes (UTF-8), because bcrypt does not take more bytes into account. Changing the password signs out all other devices; resetting it via the link signs out all devices, and the link is valid only once.
- Lockout after failed attempts. Failed logins are counted per IP address; after too many in a short time (currently eight in 15 minutes), login from that address is temporarily blocked. A successful login resets this counter. The attempts are deleted after seven days. In addition, before every password check one attempt is counted per account (for an unknown address, per address entered) and per IP address, successful attempts included: currently at most eight per account from the same IP address and 80 per IP address in 15 minutes; a considerably higher limit applies per account across all addresses combined, against distributed guessing. Failed attempts from another address therefore no longer lock the owner out of an account. These counters contain only an HMAC key, no e-mail or IP address in clear text, and expire with their time window. If the counter storage is unavailable, the login is refused, not let through. The same kind of limit applies to confirming the password before a change of password or address, switching the second factor on or off, transferring a workspace, the data export and deleting the account (five attempts per account in 15 minutes), to registrations (ten per IP address per hour) and to passwords of client portals (ten attempts per portal and IP address, 50 per portal in 15 minutes).
- Second factor. Every account can enable login with a one-time code under RFC 6238 (TOTP). The secret for this is stored encrypted in the database; the key is not stored in the database, so a database extract alone is not enough. An accepted code is not valid a second time. Ten recovery codes are stored only as a hash. One-time and recovery codes are limited to ten attempts per account in 15 minutes, including during setup.
- Administration area only with a second factor. The operator’s administration area opens only to accounts with the second factor enabled. The setup checklist reports every administrator account without a second factor.
- Sessions. The session cookie cannot be read by scripts (HttpOnly), is sent only over HTTPS (Secure) and is not sent with requests from third-party sites that could change something (SameSite=Lax). On login, a new session ID is created, so that an ID planted beforehand is no longer valid; the server does not accept a session ID that it has not issued itself. Every account sees its signed-in devices and can sign them out individually.
- “Keep me signed in” is optional and is valid for 30 days, but not for accounts with administration rights; they always sign in with password and second factor. The token consists of two parts; the verifying part is stored in the database only as a hash. Each use replaces it with a new one, and even with simultaneous requests each token is valid only once, so that a stolen token is noticed at the latest on the next genuine visit.
- Links in e-mails. Links for confirming the address and resetting the password are stored in the database only as a hash. The reset link is valid for one hour, the link for confirming a registration for 72 hours, the link for confirming a changed address for 24 hours. If the e-mail address is changed, an open reset link becomes invalid.
- Interfaces. API keys, connection codes of the extensions and rollout codes are stored only as a hash. API keys can be used only a limited number of times per minute; connection codes of the extensions are valid for 15 minutes and only once.
- Bot protection on the public forms (registration, login, password, check, header tool, opt-out, support and contact): Google reCAPTCHA, which is loaded only on submission. Only a valid response from Google with a sufficient score for exactly the form’s action is accepted; if Google does not respond within three seconds, the submission is refused. Details are in the Privacy Policy.
3.3 Access control: server administration
- The server reachable from the internet uses a packet filter to allow only the services it offers, and automatically blocks addresses after repeated failed logins to server administration.
- Automated processes between the servers use their own keys with narrowly limited rights. The key with which the web server delivers new versions of the scanner may execute only a fixed list of commands on the scan server and may only copy, write-only, into the scanner’s directory; an interactive login is not possible with it, and every rejected command is logged. Likewise, the scan server may write screenshots only to a specific directory on the web server.
- The process that serves the website has neither write access to the production installation nor a key for the scan server. A deployment triggered in the administration area only files a job, which a separate run carries out.
- Secrets such as database credentials and keys are kept in configuration files outside the served directory and are not copied along during deployment. The web server configuration is not distributed via the web interface.
3.4 Authorisation control: rights within the service
- Roles. Each workspace has the roles owner, administrator and reader. Changing, deleting, inviting and storing credentials are reserved for owners and administrators; only the owner may change roles and remove members. An invitation is valid only as long as the person who sent it is still owner or administrator. Readers see the addresses of webhooks and chat channels only shortened to the host, because the address alone allows posting to the channel. The check takes place on the server, not just in the interface.
- Binding to the workspace. Domains and settings are accessible only to members of the workspace. For each check, the Service creates a report under a random link that cannot be guessed; the results and screenshots of a check can be accessed via this link without signing in, screenshots only together with the link of their report. The link appears in the account and in alerts; anyone who passes it on passes on the report.
- State-changing requests require a security token per session (CSRF protection), which is compared in constant time.
- “View as customer”. For support, the operator can see the application as a Customer sees it. The view ends after one hour, blocks changes to password, address, second factor, devices, subscription, export and deletion, closes the administration area in the meantime and is logged. Ending it signs the operator out completely; the operator can return to the administration area only by signing in again with password and second factor. The Customer can see it in their data export.
- Administration. Only a few expressly authorised accounts have administrative rights; every reset of a second factor by the administration is logged.
3.5 Separation control
- Customers’ data is logically separated by workspace. Every read and write path in the signed-in area carries this binding with it; reports are additionally accessible via their link (section 3.4).
- Development and operation run in separate installations with separate databases and separate database users. The development user has no access to the production database. Real customer data is not copied into development; there we work with generated sample data.
- For each environment, the scanner has its own credentials with rights only to the data it needs for its jobs. It cannot read accounts, billing or logs.
- Other services of the same provider also run on the web server. They have their own databases and their own database users without access to this service’s data.
4. Encryption, pseudonymisation and data minimisation
4.1 Credentials for the scan behind the login
For this function, the Customer stores the user name and password of a test account. They are the most sensitive data in the service and are therefore protected differently from everything else:
- When storing them, the web server encrypts them with the public key of the scan server (ECIES: X25519 with a one-time key per record, HKDF-SHA256, AES-256-GCM). The private key exists only on the scan server. Web server, database and backups contain only ciphertext; we cannot read it there either.
- Each record is cryptographically bound to its domain. If moved to another domain, decryption fails.
- For a scan, the ciphertext is attached to the job. The scan server decrypts it and passes the credentials to the check container only via standard input, never as a command-line argument that would be visible in process lists. As soon as the scan server has read it, the ciphertext is deleted from the job; a run clears up any remnants after one hour at the latest.
- The credentials are never displayed, never logged, never output via the API and not exported. The interface shows only the first character and the length of the user name. Removing them overwrites the ciphertext.
- Behind the login, the scanner only reads: no submitting, no active test, no screenshots, no pages for logging out, deleting or cancelling.
4.2 Further encryption and hashes
- Passwords, recovery codes, client portal passwords, API keys, connection and rollout codes, “Keep me signed in” tokens, session IDs in the device list and links for confirmation and resetting are stored only as a hash.
- Secrets for the second factor are stored encrypted (section 3.2).
- We do not claim encryption of the entire database at rest. The sensitive values are protected individually, as described above.
4.3 Data minimisation by design
- Delivery check: Only the headers and at most the first 8 KB of the text are read. Only the time, the assignment, where applicable the ID of the test submission, and the result of the authenticity check (SPF, DKIM, DMARC) end up in the database, never the content or a full sender address. The authenticity result of the most recent e-mail is kept with the domain and is overwritten by the next one; it contains the IP address of the delivering mail server and the sender’s e-mail domain. The e-mail is deleted from the mailbox after successful processing; if retrieval or deletion fails, this happens on the next successful run.
- Checks: The structure of the forms is stored with field names, types and labels, required and visibility attributes, no values; the scanner reads the beginnings of pre-filled hidden fields (up to 24 characters) and of data attributes (up to 60 characters) only during the check and does not store them. The screenshots of the full check are not redacted; only the browser checks cover input fields. Recipient addresses of forms are stored only as a domain. Active test submissions contain only labelled test texts without personal data.
- Extensions for WordPress and TYPO3 transmit only daily figures and characteristics such as the plugin inventory, and for a connected WordPress plugin also the domains of links from blocked messages for swarm protection (switched on by default); no other content, no names, addresses or IP addresses of visitors. Optional form and field error counts are switched off by default.
- “Fix it for me”: The pasted code is processed only for the duration of the request and is not stored.
- Badge: The badge image on customer websites sets no cookie and starts no session.
- Operational notifications to the operator’s phone are fixed texts without variables, i.e. without names, addresses or content. Error notifications by e-mail to the operator contain the raw text of the error message, not sanitised and truncated to 400 characters; in individual cases it may contain addresses or links.
- Swarm protection: Between Customers’ extensions, only domains from links in blocked spam are shared; the exchange of IP networks is switched off.
- Location: The country of an IP address is determined from a local database file; no address goes to a geolocation service.
5. Protection against misuse of the scanner
The scanner loads third-party pages with a real browser. Without protection, it would be a tool with which someone from outside could reach our internal network or other non-public targets (server-side request forgery). There are therefore two independent layers and isolation of every single run.
5.1 Isolated run
- Each check runs in its own container, which is removed afterwards. It runs without administrator rights, without additional operating system capabilities and without the possibility of escalating privileges. Its file system is read-only except for small volatile areas.
- Memory, number of processes and run time are limited; a run that exceeds the time is terminated.
5.2 Network: two layers
- First layer, in the scanner: Before the scan and then for every single request by the browser, including redirects and embedded content, it is checked where the address resolves to. Private, local, reserved and documentation networks (IPv4 and IPv6) are rejected, as are ports other than those customary for the web. The browser does not allow service workers, and WebSocket connections are closed, because both could bypass this check.
- Second layer, in the network: The containers run in their own network. Firewall rules allow connections from there to the internet only on web ports; connections into private networks, including our internal network with web server and database, are blocked. Exceptions that the check run itself requires are limited to what is necessary and described in our internal documentation. This layer also takes effect if a name resolves differently only after the first check.
5.3 Requests made by the web server
Where the web server itself requests third-party addresses – for proof of control of the domain, for the header tool, for the search for exposed files, for pulse requests, for RDAP queries and for checking certificates, for webhooks and chat alerts and for the optional second checkpoint – the same rules apply: web protocols only, on the customary web ports (webhooks and chat alerts only over HTTPS on the standard port), public addresses only, a connection only to exactly the address checked beforehand, so that a name cannot subsequently be redirected to an internal target, redirects either not followed at all or followed only manually and re-checked each time, short time limits; for proof of control of the domain, for pulse requests and for the second checkpoint in browser checks, also a limited response size.
5.4 What the scanner does not do on third-party sites
- Active test submissions (at most five per check) exist for Customers only for domains for which proof of control has been provided (DNS, meta tag, file or extension); the only exception is internal checks of our own test and demo domains. The hostname of a domain with proof of control cannot be changed, so that the proof does not pass to another host. Everything else is passive: reading pages like a visitor.
- Browser checks go up to the point before submission and do not trigger any order, payment or submission.
- Domains on the opt-out list are not checked; ongoing monitoring ends with the next scheduled check.
6. Integrity: transfer and input
6.1 Transport
- The application can be reached from the internet only via HTTPS; the browser is instructed to use only HTTPS for one year (HSTS). Certificates are renewed automatically.
- Further headers restrict embedding the application in third-party pages, guessing file types and submitting forms to third-party targets. A content security policy lets only those scripts run in the application that the server releases with the respective response; current browsers do not execute injected scripts or event handlers in the HTML.
- The delivery check mailbox is retrieved via an encrypted connection with certificate verification.
- Webhooks can be signed with a secret of the Customer (HMAC-SHA256 with timestamp), so that the recipient can verify origin and integrity. Requests to the optional second checkpoint are signed, and for browser checks their responses as well.
- Stated openly: Connections within our internal network are not encrypted throughout. The credentials for the scan behind the login remain encrypted throughout (section 4.1).
6.2 Input control and logs
- Important actions in accounts and workspaces (such as login, changes to domains, alert destinations and rights, deletions, support access) are recorded in the activity log with account, time, IP address and country, and deleted after 365 days.
- Page access records kept for security and abuse prevention are deleted after 60 days, error logs after 90 days, contents of e-mails sent after 30 days. Access tokens in requested addresses and referrers, such as those of report or portal links, appear in the page access records only in masked form.
- Acceptance of the contract documents is stored with the version displayed, its checksum, time, IP address and browser identifier.
- Evidence logs can be provided with a timestamp from an external timestamping authority; only a checksum of the content goes to it, not the content itself.
7. Availability and resilience
7.1 Backup
- The database is backed up every night. A backup receives its final name only after its content has been checked: successful completion of the backup program, at least one record, as many tables as the database has, and the closing line of a complete run. Older backups are removed only after a successful new one.
- Each backup is deleted after 14 days. The storage location is outside any served directory; a location inside the project is rejected.
- Restore test: Once a week, the latest backup is loaded into a disposable database, compared table by table with production and deleted again. The result is stored.
- If a backup or a test fails, a notification goes out by e-mail and to the operator’s phone.
- Recovery after an incident: If the database fails or data is corrupted, we restore the latest tested backup. Changes made since that backup, as a rule at most those of one day, may be lost in the process; if a backup has failed, correspondingly more. We then re-run known later deletion requests (section 8). We do not commit to any particular recovery time.
- Limit, stated openly: The backups are currently stored at the same location as the database and are not separately encrypted. They protect against operating errors, faulty changes and corrupted data, not against loss of the server itself. An encrypted copy at a second location is planned (section 10).
- The credentials for the scan behind the login are contained in the backups only as ciphertext; the second-factor secret only in encrypted form, with a key outside the database.
7.2 Monitoring
- A status run checks the components of the service every five minutes, including the database, the queue and the scanner’s heartbeat, which the scanner writes regularly even when idle. If a component fails, a notification goes out; if it recovers, an all-clear.
- Cross-watch: A status run cannot report the failure of the machine it runs on. The scan server therefore checks every minute whether the application responds and, after several consecutive failures, reports with a fixed text to the operator’s phone. Conversely, the web server monitors the heartbeat of the scanner; the setup checklist shows whether the cross-watch is running.
- Error alert: A type of error that has never occurred before is reported once immediately; an accumulation of errors triggers only a single signal to the operator’s phone; once a day an overview is sent. This means we do not first learn of an error from a Customer.
- Limit, stated openly: Both servers are at the same location. A failure of the entire location, for example of power or internet connection, is not reported by any alerting mechanism but noticed by a human.
7.3 Changes and deployment
- New versions are first built and tested in the separate development environment. Deployment checks all prerequisites before the first file is written, carries out the changes to the database schema and lets running checks finish in an orderly manner before the scanner restarts.
- For the path of a new Customer, there is a smoke test over real HTTP, which is run after changeovers. We do not claim an automated test suite before every single deployment.
8. Deletion and retention periods
- A deletion run every night enforces the periods stated in the Privacy Policy and the Data Processing Agreement. It reads the same settings from which the figures in the texts are taken; for these periods, text and behaviour therefore do not diverge.
- Check results including screenshots are deleted after 13 months (the latest per domain remains), extension figures after 13 months, alert delivery logs after 90 days, support requests after 24 months.
- Removing a domain deletes the domain’s data, including checks, forms, findings, screenshots, reports, jobs, alert destinations and logs, incidents, delivery data, credentials for the scan behind the login and evidence.
- Deletion of an account takes place immediately; workspaces without further members are deleted with their data, workspaces with further members pass to another member, first to administrators, and among them to the longest-standing one. Until their own periods expire, the following remain: the logs whose entries keep the old account number, which no longer refers to any existing account, including the deletion entry, as well as sent e-mails, the proof of conclusion of the contract, support requests, reports of prospect checks (up to 90 days) and billing data at Stripe; details are in the Privacy Policy.
- Deleted data remains in backups until they expire after 14 days. Targeted deletion within a backup does not take place; if a backup is restored, known later deletion requests are carried out again manually.
9. Organisation and review
- People: The service is currently operated by the owner himself. Further persons receive access only after an undertaking of confidentiality and only to the extent necessary, and they process data only on our instructions (Art. 29 and Art. 32(4) GDPR).
- Sub-processors: We engage them only after reviewing their guarantees and under a contract pursuant to Art. 28(4) GDPR, and list them on the Sub-processors page; details are governed by the Data Processing Agreement.
- Personal data breaches: If a personal data breach affects processor data, we notify the Customer without undue delay, if possible within 48 hours; details are governed by the Data Processing Agreement.
- Vulnerability reporting: We accept reports at Security and via the file
/.well-known/security.txt. - Setup and launch checklist: In the administration area, a checklist measures the state of security-relevant settings, such as backup, administrators without a second factor, mail setup and heartbeat, and displays deviations.
- Review of these measures (Art. 32(1)(d) GDPR): on every significant change to the service, after every security incident and otherwise at least once a year. In doing so, we assess whether the measures are effective and still match the risks, and record the result in a new version of this page or, if nothing changes, with the date of the review in section 11. On an ongoing basis, the set-up and launch checklist measures the state of the settings it covers.
- External audits: No external penetration tests are currently commissioned, and there are no security certifications. This is stated here so that no one assumes them.
10. Planned, not yet implemented
These points are not committed measures until they are listed here as implemented in a new version:
- Backup at a second location: an encrypted copy of the nightly backup outside the server, so that even a total loss of the server does not lead to data loss.
- Second checkpoint: Independent confirmation of browser checks from a second location is prepared in the service but not set up. Without it, there is no confirmation from a second location.
- Hardening of server administration: This is continuing. For the reasons given in section 1, we do not publish details.
11. Status and version
- Version 1.1 · Last updated: 22 October 2026 · in the event of discrepancies between the language versions, the Polish version prevails instead of the German one; no other change.
- Version 1.0 · Last updated: 11 October 2026 · first version as a separate page; previously Annex 2 to the Data Processing Agreement. Corrected compared with the previous annex: the restore test runs weekly, the backups are on the same server, no automated test suite runs before every deployment, connections in the internal network are not encrypted throughout. Newly described: encryption of the credentials for the scan behind the login, isolation of the scanner, cross-watch and error alert.
- Changes are published with a new version number here and in the overview Changes to the Contract Documents; for any weakening of measures, the notice period of the Data Processing Agreement applies.
- In the event of discrepancies between the language versions, the Polish version prevails.