Security Audits & Penetration Testing Services

Security audits show which weaknesses in a website, API or server an attacker could actually use, and which of those weaknesses deserve a fix this week rather than a line in a forgotten spreadsheet. A scanner score is not that answer. Most real incidents start from an outdated plugin, a forgotten admin path, a token in a repository, or an endpoint that trusts the client a little too much.

At CodeWiz we assess and harden the systems we also know how to build: WordPress and WooCommerce, Laravel and plain PHP, Node.js APIs, online stores and the servers they run on. We combine a vulnerability assessment, focused penetration testing on a written scope, repeatable security scanning and a compliance review where a payment provider, a customer or a regulation actually asks for one. The outcome is a prioritized list of findings and, when you want it, the fixes in code and configuration.

This is for teams shipping a product that now holds customer data, stores about to turn on card payments, agencies inheriting a site they did not build, and companies that have grown past “the host takes care of security”. We test only systems you own or are authorized to have tested. Nothing starts without an agreed scope.

Testing: Close-up of blurred source code on a dark computer screen

Vulnerability Assessment: The Heart of a Security Audit

A vulnerability assessment is a structured look for known and observable weaknesses across the application, its dependencies and the host. It is broader than a penetration test and more deliberate than a single automated scan. This is where we map the attack surface: public URLs, admin panels, APIs, file uploads, authentication, third-party scripts, open ports and the way secrets move through deployments.

  • Application review of authentication, authorization, session handling, input handling, file uploads and error behaviour, checked against the OWASP Top 10 as a baseline, not as a ceiling.
  • Dependency and platform review of WordPress core, plugins and themes, Composer and npm packages, container images and the operating system.
  • Configuration review of TLS, security headers, cookie flags, CORS, directory listing, exposed debug tools and default credentials.
  • Data flow: where personal data, orders and tokens are stored, who can read them, and whether backups are encrypted and restorable.
  • A severity ranking that weighs exploitability and business impact, so a missing header on a static page does not outrank an insecure direct object reference on orders.

You receive the affected component, what an attacker would gain, and a concrete fix. We do not pad the report with informational noise from a scanner that has not been triaged.

Penetration Testing on an Agreed Scope

Penetration testing asks a sharper question than the assessment: within the rules we agreed, can someone reach data or actions they should not have? We confirm findings manually. An automated alert that cannot be reproduced does not go into the report as a proven issue, and a finding that can be reproduced is written so your developers can verify the fix.

The work follows the spirit of the OWASP Web Security Testing Guide: authentication, session management, access control, input validation and business logic, plus whatever is specific to your application. Business logic is where generic scanners are weakest – a coupon that can be reused, an ID in the URL that opens another customer’s invoice, a webhook that trusts its sender.

  • Scope, timing and forbidden actions are written down before any testing. Production checks are scheduled and kept within agreed rate limits.
  • We prefer a staging copy with realistic data that has been stripped of secrets. Live testing happens only when staging cannot show the behaviour, and never in a way that destroys orders or customer records.
  • Credentials for each role (guest, customer, staff, admin) let us test access control properly. Many serious issues only appear once you are logged in.
  • The report separates confirmed issues from residual risk, and each confirmed issue has a recommended fix and a retest.

Security Scanning That Runs on Every Release

Security scanning is the repeatable layer. A point-in-time review goes stale the week a dependency is published with a known flaw. We wire checks into the pipeline and onto the server so regressions fail in CI instead of in a customer’s browser.

CheckWhat it catchesWhere it runsWhat it does not replace
Dependency audit (npm, Composer, pip)Known vulnerabilities in librariesEvery pull requestFlaws in your own business logic
Secret scanningTokens and keys committed to GitPre-commit and CISecrets already pasted into a wiki or a chat
Image and host scan (Trivy and similar)Vulnerable packages in containers and the OSImage build and a weekly host jobA misconfigured firewall rule you wrote yesterday
DAST baseline (OWASP ZAP or Nuclei)Missing headers, exposed files, known CMS issuesStaging, on a scheduleAuthenticated, multi-step abuse of a checkout

For Node.js projects, supply-chain risk deserves its own habit: pin lockfiles, review new packages and keep install scripts from running with more privilege than they need. We have written separately about a sandbox that limits what a malicious npm package can touch during development. The scanning section tells you which of these checks you already have and which are missing.

Open stainless steel vault door at the entrance of a secure room

Compliance Audits Mapped to Real Obligations

A compliance audit checks your controls against a stated requirement. We do not issue certificates, and we will not pretend a questionnaire is a penetration test. What we do is read the obligation, see whether the system actually meets it, and close the gaps in code, hosting and process.

  • Payments. Card data should stay with the payment provider. Hosted fields or a redirect keep card numbers off your server and shrink the scope of PCI DSS. Our notes on payment gateway integration cover the architecture; the audit checks that the live site still matches it.
  • Personal data. HTTPS everywhere, access control on exports, retention that matches what you tell customers, and backups that are not world-readable.
  • Customer and enterprise questionnaires. We help you answer them from evidence – headers, access logs, dependency reports – instead of optimistic prose.
  • Headers and TLS as a minimum bar. HSTS, a modern certificate chain, and a Content-Security-Policy you can explain. A policy that is report-only forever is not a control.

If a requirement does not apply to you, we say so. A five-page brochure site does not need the same control set as a store that saves cards, and selling you the larger one would be theatre.

Hardening WordPress, Laravel and Node.js

Hardening is the part that changes the system. We patch, remove what is unused, and set defaults that fail closed. A typical web stack gets the same short list of HTTP headers, tuned so they do not break legitimate embeds:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'none'" always;

Content-Security-Policy needs a real inventory of your scripts and styles. The OWASP CSP Cheat Sheet is the reference we use when a third-party tag makes a strict policy awkward. Alongside headers, the practical work looks like this:

  • WordPress: remove unused plugins and themes, block XML-RPC and user enumeration if you do not need them, disable the file editor, and keep admin on a strong unique password with two-factor authentication.
  • Laravel and PHP: APP_DEBUG off in production, session cookies Secure, HttpOnly and SameSite, mass-assignment limited to explicit fields, and uploaded files stored outside the web root or on object storage.
  • Node.js: no stack traces to the client, helmet-style headers where they fit, dependencies installed from a lockfile, and the process running as a user that cannot write its own code.
  • The server: SSH keys instead of passwords, automatic security updates, a firewall with only 80, 443 and a restricted admin port, and database ports that are not published to the internet.

Sessions, Secrets and API Abuse

Accounts and APIs are where these reviews usually find the issues that matter. A missing rate limit on login, a JWT that never expires, or a .env file copied into a Docker image turns a small bug into an account takeover.

  • Passwords hashed with a current algorithm (Argon2id or bcrypt), reset links that expire, and session IDs that rotate on login.
  • Secrets in a manager or in CI variables, never in Git history. If a key has already leaked, we rotate it and then remove it from the tree.
  • Authorization checked on the server for every object, not only hidden in the interface. A button the user cannot see is not access control.
  • Webhooks verified with a signature and a timestamp, so a replayed request does not create a second order.
  • Rate limiting and lockouts on login, password reset and expensive API routes. The patterns are covered in our guide to API rate limiting; here we check that your routes actually use them.

Logging belongs in the same pass. Authentication failures, privilege changes and payment events should be recorded without storing passwords, card numbers or full session tokens.

Common Security Audit Findings We Fix

  • An admin or phpMyAdmin path exposed to the internet, protected only by a shared password.
  • File upload that accepts an extension the application later executes, or that serves uploads from the same origin as the app.
  • CORS set to reflect any origin together with credentials.
  • Debug mode, directory listing or a .git folder left on the production host.
  • Plugins and packages years behind, including ones the site no longer uses.
  • Backups sitting in a public bucket, or a backup that has never been restored in a test.
  • Security headers copied from a blog and then disabled because they broke one page, with nothing put back.
Green characters streaming down a black screen like source code

How We Work

  1. Scope: we list the systems, the roles, the data that matters and the rules of engagement, and we get written permission before any testing.
  2. Assess: we review the application, dependencies, headers, hosting and secrets, and we run triaged scans.
  3. Test: we confirm the issues that carry real impact, on staging where possible, within the agreed limits.
  4. Report: you get findings ordered by severity, each with impact, evidence and a fix your developers can apply.
  5. Fix: we can patch the code, the CMS and the server ourselves, or support your team while they do it.
  6. Retest: we verify the closed items and leave the scanning and update routine in place so the next release does not undo the work.

Why CodeWiz

  • We build the same stacks we audit. WordPress, Laravel, Node.js, APIs and hosting are daily work, so findings come with a fix that fits the code, not a generic paragraph.
  • Open-source tooling first. OWASP ZAP, Nuclei, Trivy, Dependabot and fail2ban keep the ongoing checks free of a licence you cannot leave.
  • Sized to the risk. A small site gets a focused security audit. We do not sell a multi-week exercise when a careful review and hardening will do.
  • Performance and security together. Caching, Cloudflare and server setup stay in the same hands, so a security header is not stripped out by the next performance tweak.
  • Fair pricing, from Banja Luka. Premium development without premium prices, working remotely with clients locally and internationally. More about CodeWiz.

Frequently Asked Questions

How much does a security audit cost?

It depends on the number of applications, whether you need authenticated testing, and how much fixing you want included. A review of one website and its server is a compact project; several APIs plus a retest takes longer. We estimate after a short look at the scope, before work starts.

How long does a penetration test take?

A single web application with a staging environment is often a matter of days, including the report. Larger scopes, with several roles and a fix-and-retest cycle, usually run for a few weeks. Scanning setup is quicker once the first audit has shown what to automate.

Will testing take the website down?

It should not. We agree the rules first, prefer staging, and keep production checks inside limits that will not exhaust the server or place orders. Destructive checks are not part of a standard engagement.

What is the difference between a vulnerability assessment and penetration testing?

The assessment looks widely for weaknesses and ranks them. Penetration testing tries to confirm, on an agreed scope, whether those weaknesses can be used to reach something valuable. Scanning then watches for the same classes of issue on later releases. A useful security audit uses all three, in that order.

Do you need our source code?

Source code makes the review faster and catches issues a black-box test will miss, so we ask for it when you can share it. We can still assess a site from the outside, with test accounts, when the code belongs to a platform you do not control.

Ready for a Security Audit That Ends in Fixes?

Tell us what you run, what data it holds and whether you already have a deadline from a customer or a payment provider. Contact us to agree a scope, or see our security audit services.