Control: 7.4 Ensure that HTTP(S) access from the Internet is evaluated and restricted
Description
Network security groups should be periodically evaluated for port misconfigurations. Where certain ports and protocols may be exposed to the Internet, they should be evaluated for necessity and restricted wherever they are not explicitly required and narrowly configured.
The potential security problem with using HTTP(S) over the Internet is that attackers can use various brute force techniques to gain access to Azure resources. Once the attackers gain access, they can use the resource as a launch point for compromising other resources within the Azure tenant.
Remediation
From Azure Portal
- Go to 
Virtual machines. - For each VM, open the 
Networkingblade. - Click on 
Inbound port rules. - Delete the rule with:
 
- Port = 80/443 OR [port range containing 80/443]
 - Protocol = TCP OR Any
 - Source = Any (*) OR IP Addresses(0.0.0.0/0) OR Service Tag(Internet)
 - Action = Allow
 
From Azure CLI
- Run below command to list network security groups:
 
az network nsg list --subscription <subscription-id> --output table
- For each network security group, run below command to list the rules associated with the specified port:
 
az network nsg rule list --resource-group <resource-group> --nsg-name <nsg-name> --query "[?destinationPortRange=='80 or 443']"
- Run the below command to delete the rule with:
 
- Port = 80/443 OR [port range containing 80/443]
 - Protocol = TCP OR "*"
 - Source = Any (*) OR IP Addresses(0.0.0.0/0) OR Service Tag(Internet)
 - Action = Allow
 
az network nsg rule delete --resource-group <resource-group> --nsg-name <nsg-name> --name <rule-name>
Usage
Run the control in your terminal:
powerpipe control run azure_compliance.control.cis_v300_7_4Snapshot and share results via Turbot Pipes:
powerpipe loginpowerpipe control run azure_compliance.control.cis_v300_7_4 --shareSQL
This control uses a named query:
with network_sg as (  select distinct    name sg_name  from    azure_network_security_group nsg,    jsonb_array_elements(security_rules) sg,    jsonb_array_elements_text(sg -> 'properties' -> 'destinationPortRanges' || (sg -> 'properties' -> 'destinationPortRange') :: jsonb) dport,    jsonb_array_elements_text(sg -> 'properties' -> 'sourceAddressPrefixes' || (sg -> 'properties' -> 'sourceAddressPrefix') :: jsonb) sip  where    sg -> 'properties' ->> 'access' = 'Allow'    and sg -> 'properties' ->> 'direction' = 'Inbound'    and sg -> 'properties' ->> 'protocol' ilike 'TCP'    and sip in    (      '*',      '0.0.0.0',      '0.0.0.0/0',      'Internet',      'any',      '<nw>/0',      '/0'    )    and    (      dport in      (        '80',        '443',        '*'      )      or      (        dport like '%-%'        and split_part(dport, '-', 1) :: integer <= 80        and split_part(dport, '-', 2) :: integer >= 80        and split_part(dport, '-', 1) :: integer <= 443        and split_part(dport, '-', 2) :: integer >= 443      )    ))select  sg.id resource,  case    when nsg.sg_name is null then 'ok'    else 'alarm'  end as status,  case    when nsg.sg_name is null then sg.title || ' restricts HTTPS access from internet.'    else sg.title || ' allows HTTPS access from internet.'  end as reason    , sg.resource_group as resource_group  , sub.display_name as subscriptionfrom  azure_network_security_group sg  left join network_sg nsg on nsg.sg_name = sg.name  left join azure_subscription sub on sub.subscription_id = sg.subscription_id;