Contact Us
How to Secure Your Data Part 5: SQL Blocking
Learn how to bridge native database security gaps by implementing targeted SQL blocking guardrails without disrupting daily operational workflows.

In the first four parts of this series, we made a blunt case: detection is the bedrock of security. Prevention alone is a fantasy, even in theory, since you can’t calibrate it to be sensitive enough without breaking things. False positives in prevention mean people cannot do their jobs, production goes down, or data can even get corrupted. You must be able to detect, since failing to see what is happening inside your database means you have already lost the war.

But a detection-first approach does not mean leaving the front door open and turning your database into a free-for-all.

Effective prevention isn’t about building a perfect wall around the database and pretending nobody can climb it. It is about applying tight constraints on activity vectors that shouldn’t exist. You don’t need to block everything – you just need to block what you can achieve in practice, and that eliminates significant attack vectors. In other words, we aim for a strong reduction in the attack surface, not perfect security. The rest comes down to detection.

Before diving into the details of building effective blocking, let’s talk about the limitations of database security. That is a common lie, and we must address it to understand the purpose of blocking.

Why Native Database Security Fails

If you open any database vendor manual, you’ll find hundreds of pages dedicated to native access controls: users, passwords, roles, system privileges, table permissions, and column-level grants. For most database and security personnel, that is what database security means.

In practice, native database permissions are almost entirely useless for stopping real-world attacks.

Here’s why:

1. The Authentication Fallacy

Authentication systems, like users and passwords, check the credentials. They do not verify that the human or process using those credentials is who they claim to be. This gap is how many attacks manifest.

When an attacker steals a valid connection string from a compromised application server or grabs a DBA’s password from the file where they store it, native authentication lets them right through the front door. To the database, a stolen credential looks identical to a legitimate one.

Even attacks that don’t impersonate the real user exploit legitimate credentials. Either because the real user is the attacker (abuse of privilege) or because the program using the credentials is manipulated (e.g., SQL Injection).

One way or another, all attacks leverage legitimate authenticated connections. You cannot bypass proper validation and get into the database using “magic packets”. They don’t exist.

In other words, even though database authentication works flawlessly as designed, every attack vector gets through it, and databases get breached every day.

2. The Application Account

Database engine security designers in the 1970s built table- and column-level grants assuming each individual owns an account including all the information in it, and shares that information with other humans.

Modern software architecture completely broke this model.

Today, 99% of database activity originates from a handful of application service accounts. These accounts own all the data, and applications require this full access. The application enforces security controls in its code running on the application servers, not in the database.

If a malicious user connects to the database using these accounts, the database has no security restrictions protecting the data. Equally, when attackers exploit an application vulnerability, database security is non-existent.

3. The Unrestricted DBA

The second major class of active database accounts belongs to DBAs. DBAs require elevated privileges to manage the database. But the native database access control model also grants administrative accounts unlimited access to the data.

By giving DBAs permissions to maintain the database, you inevitably give them, or an attacker impersonating them, full access to all the information in the database.

Bridging the Gap

Native access controls fail because the way we use databases grants full access to almost everyone. SQL blocking adds another layer of rules on top of native permissions. These rules add more dimensions and can apply restrictions that native controls cannot.

The DBA Threat Vector

Privileged database accounts pose the highest risk and form the highest-value targets in your organization. They hold all the keys, and attackers know it. The threat isn’t just rogue DBAs – it’s also hackers leveraging credential theft or C2 compromise.

However, a DBA’s job is to manage the database, not access the data. By applying SQL blocking rules that prevent data access, we can eliminate vast swaths of DBA-related risk without impacting their daily work.

Rule 1: Strip Data Access

DBAs manage space, performance, backups, etc. None of these tasks require reading customer PII or modifying financial records.

A simple SQL blocking rule can fix that: Block all non-DDL statements from DBA accounts directed at data schemas.

You could apply different isolation rules depending on your data. Like blocking only queries or only DML. However, regardless of the isolation strategy, separating privileged accounts from data access is a powerful and effective principle.

It does not mean that DBAs never need to touch data – for example, when fixing corrupted entries. However, that is the exception to the rule and should be handled on a case-by-case basis as a temporary override, not blanket unfettered access.

Blocking data schema access from administrative accounts protects you from malicious DBAs and renders stolen DBA credentials useless for data exfiltration.

Rule 2: Block DML

DBAs should rarely, if ever, execute INSERT, UPDATE, or DELETE statements in production. Data modifications belong inside secured application workflows. Allowing DBAs to run raw DML in production opens the door to human error, data corruption, and deliberate tampering.

SQL blocking can prevent DMLs originating from administrative accounts. Just like data access, exceptions must go through a temporary, audited exception workflow – not a persistent, blank-check permission.

Rule 3: Separation of Duties

Sensitive administrative operations such as user creation or permission grants must follow change control. But change control tickets are just text documents that cannot stop attackers from using a stolen session at 2 AM.

By combining SQL blocking with Amnesty rules, you can enforce a workflow that requires DBAs to obtain pre-authorization from security personnel before taking select sensitive actions. For example:

  • A manager generates a ticket requesting a new database user.
  • Security personnel validate the request and issue an Amnesty Code.
  • The DBA uses the Amnesty Code to bypass the blocking rule preventing user creation.
  • Security personnel are notified of the actions taken using the Amnesty Code and validate them.

This turns a static, vulnerable privilege into a dynamic, multi-party authorization process. It prevents malicious DBA actions but, more importantly, prevents hackers from abusing these accounts.

The Application Account

Application accounts are a security nightmare because they carry full access to the data schema. If attackers extract the connection string from the application server, they can connect directly to the database. Thereby bypassing the application security entirely.

SQL blocking can bridge this gap by constructing additional fences around the application account and around its data.

Activity Source Binding

The application account should only execute SQL when three conditions are met simultaneously:

  1. It is using the correct credentials (user and password). You do not need additional security here, since the database engine already validates these.
  2. It is originating from an authorized application server IP address. Most databases cannot test this.
  3. The connection is from a legitimate application (e.g., app1.exe), not an interactive client like SQL Plus, Management Studio, or a Python script.

If a connection uses valid application credentials from a developer’s laptop, or an unauthorized process on the app server itself, SQL blocking drops the traffic immediately, allowing security personnel time to take further action.

Protecting the Sensitive Core

We can take source binding a step further by creating a dedicated micro-perimeter around sensitive tables (e.g., payment details or PII).

Even within a complex application, not every microservice or web node needs access to the core sensitive tables. SQL blocking lets you secure specific tables by restricting access to particular accounts, IPs, and programs.

These tight restrictions ensure that no other account (application, DBA, or analyst), server, or program can touch critical information.

Isolation can be limited to queries or DML depending on the type of data. For example, financial information should resist unauthorized modifications while PII should restrict queries.

Advanced Guardrails

Beyond expanding traditional security with limits on activity source and SQL content, advanced SQL blocking introduces active guardrails across time and volume.

Time-Windows

Unauthorized database access often happens outside of normal operating hours. Businesses run 24/7, but expert personnel generally work during regular working hours. That means you can usually block off-hours activity or, at least, limit it.

SQL blocking allows you to enforce temporal boundaries such as:

  • Restrict most DBA administrative privileges to business hours. You can limit off-hours access to specific machines, programs, and activity types.
  • Restrict analyst and BI tools to business hours since off-hours emergency access is unlikely.

During business hours, security and DBA personnel are online and monitoring the systems. They can quickly react to malicious activity. During that time, hackers are also less likely to exploit a compromised C2 asset.

Off-hours, when you operate with skeleton crews and on-call personnel, are when organizations are most vulnerable. When the computers are on, but the experts are home, an alert may slip under the radar until Monday morning.

Circuit Breakers: Volume and Exfiltration Limits

Even if an attacker bypasses detective alerts and, for example, leverages an application vulnerability (like SQL injection or BOLA). They still face a fundamental physical constraint: data extraction means moving a massive volume of information.

Setting hard thresholds on database queries acts as an automatic circuit breaker:

Row Extraction Limits: If an application service account normally reads between 500 and 1,000 sensitive data rows per minute with peaks of 2,000 rows per minute, then setting a limit of 3,000 rows per minute will significantly restrict mass exfiltration.

That means a single injected SQL will not be able to extract more than 3,000 rows. It means that even multiple SQLs (e.g., BOLA) will take over 5 hours to extract 1 million rows and over 2 days to extract 10 million rows.

Call Volume Caps: Limiting query frequency when accessing sensitive tables can act as a powerful break against BOLA. It can, for example, allow larger per-minute extractions (e.g., 10,000 rows), but a lower execution rate (e.g., 1,000 calls per minute).

Setting limits per hour instead of per minute allows better time averaging. It means higher per-minute peaks with lower total per-hour thresholds.

Even if all detective alerts fail to notify security personnel in time, rate-limiting circuit breakers limit breach velocity and prevent attackers from dumping a multi-million-row customer database. It caps the damage at a fraction of the total dataset and gives security personnel precious time to respond.

Dynamic Masking

Dynamic data masking is a little bit of a stepchild in the preventive field. It aims to deliver partial field information to some users. It aims to bridge an application functional gap more than to perform a security feature. It is often touted as a critical silver bullet, but suffers from severe limitations in modern architectures.

Inside the database engine, dynamic masking is only aware of the database context (e.g., DB user, IP address). That prevents it from making granular masking decisions based on the end-user logged into the web application. Masking only part of the application activity is the most common use case.

True end-user-aware masking (e.g., hiding SSNs from customer service agents while showing them to credit analysts) must occur inside the application layer. It can leverage application code or rely on technologies like Application Dynamic Masking that we will discuss later in this series.

Database-level masking is critical if you are trying to mask privileged connections. Non-privileged connections can usually be masked using views, but privileged connections cannot. However, since there aren’t many use cases for masking privileged connections, dynamic masking in the database engine offers limited value.

From Theory to Practice

When implementing SQL blocking, two requirements are non-negotiable:

  1. 100% Blocking: Malicious SQL must never execute.
  2. Minimal Performance Impact: Database latency and throughput cannot be compromised.

Most traditional solutions rely on an external server, so they fail on one of these points. It means that:

  • Latency: Under one configuration option, the database is forced to wait for the central server to approve or reject each packet before processing it. This creates unacceptable latency that slows down the database.
  • Delayed Action: Under another configuration option, the database starts processing all the requests immediately. The connection is later severed if the central server determines the packet should have been blocked. That ensures malicious activity gets processed and, depending on timing, may also send back the result set.

The Core Audit architecture, for example, does not rely on external servers for making blocking decisions. The agent running on the database server makes instantaneous decisions about every execution. That ensures every SQL is reviewed before execution and the impact on database performance is minimal.

Safe Deployment

Blocking queries in a live production environment is risky. A misconfigured policy or activity you didn’t consider can wreak havoc. It can break an application, prevent legitimate users from doing their jobs, or even cause data corruption.

Before activating a blocking policy, consider this 4-step deployment methodology:

Step 1: Historical Validation

Never activate a blocking rule blindly. Use Core Audit’s proactive forensics to review activity in the security repository. Check at least 90 days back to ensure no one performed activity that would trigger the blocking rule. Ideally, set the time range to the beginning of your history to validate that no legitimate business process, background job, or application workflow violates the rule you intend to enforce.

Step 2: Test

Deploy the rule in a test or pre-production environment. Run comprehensive regression tests for legitimate application workflows to ensure you get no false positives. Then, simulate the attack you aim to block and confirm the rule works as expected.

Step 3: Log-Only Mode

Deploy the policy in production under log-only mode. The Core Audit agent will do everything it normally does during blocking. However, instead of actually blocking, it will generate a WOULD BLOCK event. Let the blocking policy run for a while in log-only mode to ensure there are no surprises.

Step 4: Active Enforcement

When the tests give a green light, flip the rule to active enforcement.

Operational Rule: Always ensure on-call DBAs and security personnel have a clear procedure and know how to disable blocking in case of an emergency. There are multiple ways to do that, from changing the policy to log-only mode to disabling the policy on the instance, or completely taking the agent offline. But when something breaks at 4 am, they need to know how to get things working again.

Final Thoughts

SQL blocking can pose an operational risk. However, deterministic, reliable policies, along with structured phased deployment, can minimize this risk and turn blocking into an asset that enhances security and is operationally responsible.

However, it should not be your first step into advanced database security. SQL blocking is a powerful security step, but one you should only take when you have complete visibility and solid control over your databases.

You should not use SQL blocking just for the sake of doing it. You should have a clear methodology, like the one outlined in this article, and a thorough understanding of how it will enhance your security and contribute to your overall posture. Otherwise, it will be yet another unrelated effort in a large patchwork of disparate security measures.

If this series has made one thing clear, it is this: effective security relies on deep detection, amplified by advanced prevention. Combining the detective methodologies we discussed earlier in the series, and adding prevention on top, yields an incredibly solid and powerful defense. One that is nearly impossible to penetrate. By layering different measures and targeting each attack vector in multiple ways, you maximize your chances of knowing and responding to an attack in real time.

What Comes Next

Until now, this article series focused strictly on securing the database layer. However, as we highlighted before, the database is only the first battle. In modern 3-tier architectures, the application layer sits right on top of your database. Some attacks that filter through the application are visible in the database, but others are not. End-user identities, context, and business logic are in the application domain. Securing them may, therefore, require us to look at the world through the application.

In Part 6, we will shift our focus to Application Security – exploring how to gain the control we achieved in the database – in the application.

No posts found

If you have a question or a comment, please let us know. We’ll be happy to hear from you.