feat: add rule AZ-DB-008 SQL Server minimum TLS version below 1.2 - #361
dipeshrayg wants to merge 3 commits into
Conversation
|
Hi @dipeshrayg, thanks for picking up #246! Before I do a full review, could you test this against a real Azure environment? Create a SQL server, set its minimum TLS to different values, run the scanner, then run the playbook. It'll help you understand both your change and how OpenShield behaves end to end. You can get free Azure credits with a student account (Azure for Students). |
TFT444
left a comment
There was a problem hiding this comment.
Reviewed f2aa197. CI all green. Approving.
Rule (az_db_008.py)
_COMPLIANT_VERSIONS = {"1.2", "1.3"}is the right set: future TLS 1.3 adoption is pre-allowed without needing a code change.getattr(server, "minimal_tls_version", None)correctly handles a missing attribute as non-compliant. The inline comment explaining that Azure's API allows the string"None"(distinct from PythonNone) is exactly the kind of why-not-what comment this codebase needs.- CIS N/A convention is correctly applied with a clear justification citing the actual CIS Azure Foundations Benchmark 2.0.0 document. The CIS description explains why no numbered control exists (storage-account TLS 3.15 does not apply to
Microsoft.Sql/servers). - Framework mappings are accurate: NIST PR.DS-2 (data-in-transit protection), ISO 27001 A.10.1.1 (cryptographic controls policy), SOC 2 CC6.7 (protects data in transit). All four match the rule's intent without overreach.
enisa_pqc.jsonandncsc_pqc.jsonare PQC-specific frameworks; correctly not modified here.
Playbook (fix_az_db_008.sh)
set -euo pipefailis set.- Empty-server guard prevents a no-op run from producing misleading output.
- The TLS check allows 1.2 or 1.3 before remediating, consistent with
_COMPLIANT_VERSIONS. --minimal-tls-version 1.2(not 1.3) is the right default: remediation brings the server to the minimum acceptable baseline, not the maximum.
Tests (test_rules_database.py)
Six cases cover: compliant 1.2, compliant 1.3, non-compliant 1.0, non-compliant 1.1, explicit string "None", and missing attribute. Every flagged case asserts rule_id, severity, category, resource_type, and the metadata.minimal_tls_version payload. The _REQUIRED_FIELDS assertion on the 1.0 case verifies the full finding schema.
parthrohit22
left a comment
There was a problem hiding this comment.
Please handle failures from az sql server show separately from a successfully retrieved TLS value. The current || echo "" fallback treats read errors as non-compliant configuration and may trigger an update without verifying the server’s state. Consider reporting the error and skipping that server; remediate only after a successful read confirms the TLS version is below 1.2.
Detects Azure SQL Servers whose minimal_tls_version is missing, an
explicit "None", or below 1.2 ("1.0"/"1.1"), matching the real
azure-mgmt-sql Server model (a plain string, not the TLS1_0-style
enum some other Azure services use).
No numbered CIS Azure Foundations control exists for this specific
setting (verified against the official 2.0.0 control mapping; only
the storage-account minimum TLS control, 3.15, is numbered, and it
does not apply to Microsoft.Sql/servers), so this follows the repo's
existing N/A-* convention like AZ-STOR-006 through AZ-STOR-009.
Closes OWASP#246
Signed-off-by: Dipesh Ray <dipesh.ray.g@gmail.com>
The previous '|| echo ""' fallback made a failed 'az sql server show' (permissions, transient API error) indistinguishable from a server with no minimum TLS set, so the playbook could update a server without ever confirming its state. A failed read now reports an error, skips that server, and makes the script exit non-zero; only a successful read of an unset/None/below-1.2 value is remediated. Signed-off-by: Dipesh Ray <dipesh.ray.g@gmail.com>
f2aa197 to
931d027
Compare
TFT444
left a comment
There was a problem hiding this comment.
@parthrohit22's requested change has been addressed. The || echo "" fallback has been replaced with a proper if ! guard that catches read failures, logs an error, increments a READ_FAILURES counter, and skips the server via continue. No update is ever made without a confirmed successful read. The script also exits with code 1 if any reads failed, so CI or operators see the failure rather than a silent partial run.
Rule, tests, and compliance mappings were already sound in the previous review. Approving.
|
@parthrohit22 the playbook fix addresses your earlier request-changes. Could you re-review when you get a chance? Thanks. |
| """Detect Azure SQL Servers whose minimum TLS version is below 1.2 or unset.""" | ||
| findings: List[Dict[str, Any]] = [] | ||
|
|
||
| for server in azure_client.get_sql_servers(): |
There was a problem hiding this comment.
AzureClient.get_sql_servers() catches SDK/API exceptions and returns [], so this loop cannot distinguish a successful empty inventory from an authorization, network, or throttling failure. In the latter case AZ-DB-008 reports no findings and can make an incomplete scan look clean. Please preserve an indeterminate/error state for inventory failures and avoid treating it as a compliant empty result.
There was a problem hiding this comment.
The PR notes that testing against a live Azure subscription was not performed because no subscription was available in the contributor’s environment. I had previously asked [@dipeshrayg](https://github.com/dipeshrayg) to test the change in Azure or let us know if they were unable to do so. Could you please confirm whether you can perform this manual test? If not, please let us know so we can determine how to proceed.
…nventory is UNKNOWN AzureClient.get_sql_servers() returns [] on any API failure as well as for an empty subscription, so scan() alone made an unreadable inventory look like a clean result. Add evaluate() per the OWASP#263 contract: PASS/FAIL per server, and UNKNOWN (never a pass) when no servers are returned. scan() is unchanged apart from sharing the finding builder. Signed-off-by: Dipesh Ray <dipesh.ray.g@gmail.com>
|
Thanks for the review. Pushed three changes:
Full suite, ruff and the mapping validator pass locally. I'll come back separately on the live Azure test question. |
What does this PR do?
Adds rule AZ-DB-008: detects Azure SQL Servers that do not enforce a minimum TLS version of 1.2.
Type of change
Rule details
Testing
Notes on scoping
Checked the actual installed
azure-mgmt-sqlSDK model before writing this:Server.minimal_tls_versionis a plain string (not an enum), and the real Azure API allows an explicit"None"value alongside"1.0"/"1.1"/"1.2"/"1.3", different from theTLS1_0-style values some other Azure services use. The rule and tests match that, flagging a missing attribute, an explicit"None","1.0", or"1.1".Verified against the official CIS Azure Foundations Benchmark 2.0.0 control mapping that no numbered control exists for this SQL-server-specific setting (only the storage-account minimum TLS control, 3.15, is numbered, and it doesn't apply to
Microsoft.Sql/servers), so this follows the repo's existingN/A-*convention already used for AZ-STOR-006 through AZ-STOR-009.Related issue
Closes #246
Checklist
Signed-off-bytrailer