NIST SP 800-53 Rev. 5 · System and Communications Protection
SC-7 on AWS
Unrestricted inbound exposure without approval — a published SQL (Athena) + Lambda query you can run against Amazon Athena over AWS Config security-group inventory, with the evidence it needs, the settings you decide, and what a result does and does not establish.
Why this matters
A server left open to the entire internet without approval
Cloud systems make it trivial to open a service to the whole internet, often as a temporary measure during troubleshooting. Temporary frequently becomes permanent. Some public exposure is intended and legitimate, so a check that reports every open port is ignored within a week.
Why this check earns its place. It distinguishes deliberate, documented exposure from undocumented exposure, which is the distinction that makes the result actionable rather than noise.
- What it reads
- The organization's own firewall rules, compared against its register of approved exposures.
- What it reports
- Services reachable from anywhere on the internet with no unexpired approval on record.
See related public disclosures on the Signals page →
What this finds
Inbound rule permitting unrestricted source access with no current, unexpired entry in the approved exposure register.
The requirement
The organization must monitor and control communications at the external managed interfaces to the system, and connect to external networks only through managed interfaces consisting of boundary protection devices arranged in accordance with an organizational security architecture.
NIST SP 800-53 Rev. 5 — SC-7 (Boundary Protection).
NIST requires controlled external interfaces. Which exposures are acceptable, for how long, and with what compensating controls is organization-defined — supplied here through the approved exposure register. Public exposure is not automatically wrong; undocumented or expired exposure is.
How this maps to the CISA performance goals
The Cross-Sector Cybersecurity Performance Goals are a voluntary baseline published by CISA — the U.S. federal agency for critical-infrastructure cybersecurity — written for organizations too small to employ security staff. This control speaks to:
- 3.S — Secure internet-facing devices
The goal is securing what faces the internet; the pack finds unrestricted inbound exposure that was never approved. - 3.I — Implement logical/physical network segmentation
Unreviewed inbound paths are the boundary that segmentation is meant to impose.
See the full coverage map, including the goals no query can answer →
Evidence this query needs
Approved exposure register approved_exposure_register.csv
Records which internet-facing exposures have been formally accepted, with an expiry. Public exposure is not automatically wrong; undocumented or expired exposure is.
Minimum fields: resource_id, port, approved_source_cidr, expires_on
The expiry date is the field that makes this register meaningful. Without it, a one-time approval silently becomes permanent — which is the failure mode this control exists to catch.
The query
Published as sc-7-unrestricted-exposure.aws.sql. Reads aws_config_security_groups, approved_exposure_register (supplied). Requires: athena:StartQueryExecution; config:SelectAggregateResourceConfig.
Before this returns anything,
aws_config_security_groups has to be reaching Amazon Athena over AWS Config security-group inventory, and approved_exposure_register (supplied) has to be landed there. If not, the query reports nothing found — which looks
exactly like nothing wrong. What has to be switched on first →
-- SC-7 -- security groups permitting unrestricted inbound access
-- without a current approved-exposure entry
SELECT
sg.group_id, sg.group_name, sg.vpc_id,
p.from_port, p.to_port, p.ip_protocol, p.cidr_ip,
'AWS EC2 Security Group' AS source_system
FROM aws_config_security_groups sg
CROSS JOIN UNNEST(sg.ip_permissions) AS t(p)
LEFT JOIN approved_exposure_register a
ON a.resource_id = sg.group_id
AND (a.port = CAST(p.from_port AS varchar) OR a.port = '*')
AND a.expires_on > current_date
WHERE p.cidr_ip IN ('0.0.0.0/0', '::/0')
AND a.resource_id IS NULL
ORDER BY p.from_port;
Open this pack on AWS to adjust the settings and download it →
The interactive version opens on AWS — the platform on this page — even if your environment profile does not list it.
Settings you decide
NIST states the objective and leaves these to your organization. The interactive version of this pack applies them to the query for you.
- Limit to specific security groups (optional)
- Paste security group identifiers, one per line.
Running it continuously
EventBridge rule → Lambda → Security Hub
Trigger: EventBridge rule on Config item change
for AWS::EC2::SecurityGroup
Compute: Lambda (Python 3.12), 60s timeout
Step 1: Parse the new ipPermissions set
Step 2: Check each 0.0.0.0/0 rule against the register
Step 3: If unapproved or expired, import to Security Hub
Severity label: CRITICAL
RelatedRequirements: NIST.800-53.r5 SC-7
Idempotency: Id = sha256(group_id + port + cidr)
Config item-change events fire on security-group modification, so a newly opened port is evaluated in near real time rather than at the next scheduled scan.
What a result does not prove
Unrestricted exposure is not automatically a vulnerability — public web tiers are meant to be public. What this check establishes is that the exposure is not currently covered by a documented, unexpired approval.
Validation status for this platform: Not tenant-validated. Structure, query generation, and preflight are covered by the project's automated test suites. This pack has not been executed against a live tenant, account, or index. Validate it in a non-production scope before relying on any result.
Before you act on a result
- Is this a deliberate public service that simply has not been registered?
- Has an approval lapsed rather than never existed?
- What compensating controls sit in front of this exposure?
- Can the source range be narrowed without breaking the service?
Common questions
- How do I check for unrestricted inbound exposure without approval in AWS?
- Run the published SQL (Athena) + Lambda query on this page against Amazon Athena over AWS Config security-group inventory. It reads aws_config_security_groups, approved_exposure_register (supplied) and reports: Inbound rule permitting unrestricted source access with no current, unexpired entry in the approved exposure register.
- What permissions are needed to run this AWS query?
- athena:StartQueryExecution; config:SelectAggregateResourceConfig.
- What evidence does SC-7 need that AWS cannot produce?
- Approved exposure register (approved_exposure_register.csv). Records which internet-facing exposures have been formally accepted, with an expiry. Public exposure is not automatically wrong; undocumented or expired exposure is. At minimum it must carry: resource_id, port, approved_source_cidr, expires_on.
- Does a result from this query mean the control has failed?
- Unrestricted exposure is not automatically a vulnerability — public web tiers are meant to be public. What this check establishes is that the exposure is not currently covered by a documented, unexpired approval.
Terms used on this page
- NIST SP 800-53the U.S. federal catalogue of security requirements
- The catalogue of security and privacy requirements published by the National Institute of Standards and Technology, a U.S. federal agency. U.S. government systems are measured against it, and many private organizations adopt it voluntarily. Each requirement has an identifier such as AC-2. Official source →
- CISACybersecurity and Infrastructure Security Agency
- The U.S. federal agency responsible for national critical-infrastructure cybersecurity. Its publications are works of the U.S. government and are free to use. Official source →
- CPGCross-Sector Cybersecurity Performance Goals
- A voluntary baseline of security practices published by the U.S. Cybersecurity and Infrastructure Security Agency, written specifically for organizations too small to employ security staff. It is a short, plainly written starting list rather than a full standard. Official source →
- not tenant-validatednever executed against real data
- The check has passed the project's automated tests for structure and syntax, but has never been run against real data anywhere. Test it in a safe scope before relying on any result.