Skip to content

Commit caf23c9

Browse files
authored
Merge pull request #4 from GitHubSecurityLab/cache
Add Cache Support
2 parents 5e41207 + a635750 commit caf23c9

File tree

9 files changed

+301
-31
lines changed

9 files changed

+301
-31
lines changed

ql/lib/codeql/bicep/Frameworks.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import frameworks.Microsoft.Cache
12
import frameworks.Microsoft.Compute
3+
import frameworks.Microsoft.General
24
import frameworks.Microsoft.Network
35
import frameworks.Microsoft.Storage
46
import frameworks.Microsoft.Databases
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
private import bicep
2+
private import codeql.bicep.Concepts
3+
4+
module Cache {
5+
abstract class CacheResource extends Resource { }
6+
7+
/**
8+
* Represents an Azure Cache for Redis resource.
9+
*/
10+
class RedisCacheResource extends CacheResource, Resource {
11+
/**
12+
* Constructs a RedisCacheResource for Microsoft.Cache/Redis resources.
13+
*/
14+
RedisCacheResource() { this.getResourceType().regexpMatch("^Microsoft.Cache/Redis@.*") }
15+
16+
/**
17+
* Returns the properties object for the Redis cache resource.
18+
*/
19+
CacheProperties::Properties getProperties() { result = this.getProperty("properties") }
20+
21+
CacheProperties::RedisConfiguration getRedisConfiguration() {
22+
result = this.getProperties().getProperty("redisConfiguration")
23+
}
24+
25+
/**
26+
* Returns the SKU of the Redis cache.
27+
*/
28+
Sku getSku() { result = this.getProperty("sku") }
29+
30+
/**
31+
* Returns the Redis version.
32+
*/
33+
string redisVersion() {
34+
result = this.getProperties().getProperty("redisVersion").(StringLiteral).getValue()
35+
}
36+
37+
/**
38+
* Returns true if non-SSL port is enabled.
39+
*/
40+
boolean enableNonSslPort() {
41+
result = this.getProperties().getProperty("enableNonSslPort").(Boolean).getBool()
42+
}
43+
44+
/**
45+
* Returns the publicNetworkAccess property, if present.
46+
*/
47+
string publicNetworkAccess() {
48+
result = this.getProperties().getProperty("publicNetworkAccess").(StringLiteral).getValue()
49+
}
50+
51+
/**
52+
* Returns a string representation of the Redis cache resource.
53+
*/
54+
override string toString() { result = "RedisCacheResource" }
55+
}
56+
57+
/**
58+
* Represents a public Azure Cache for Redis resource (public network access enabled).
59+
*/
60+
class PublicRedisCacheResource extends PublicResource {
61+
private RedisCacheResource redisCache;
62+
63+
/**
64+
* Constructs a PublicRedisCacheResource if the Redis cache has public network access enabled.
65+
*/
66+
PublicRedisCacheResource() {
67+
redisCache.publicNetworkAccess() = "Enabled" and
68+
this = redisCache
69+
}
70+
71+
/**
72+
* Returns the property that indicates public access for the Redis cache resource.
73+
*/
74+
override Expr getPublicAccessProperty() {
75+
result = redisCache.getProperties().getProperty("publicNetworkAccess")
76+
}
77+
}
78+
79+
module CacheProperties {
80+
/**
81+
* Represents the properties object for a Redis cache resource.
82+
*/
83+
class Properties extends Object {
84+
private RedisCacheResource redisCache;
85+
86+
/**
87+
* Constructs a Properties object for the given Redis cache resource.
88+
*/
89+
Properties() { this = redisCache.getProperty("properties") }
90+
91+
/**
92+
* Returns the parent RedisCacheResource.
93+
*/
94+
RedisCacheResource getRedisCacheResource() { result = redisCache }
95+
96+
string toString() { result = "CacheProperties" }
97+
}
98+
99+
/**
100+
* Represents the redisConfiguration object for Azure Cache for Redis.
101+
* Provides accessors for all supported redisConfiguration properties.
102+
*/
103+
class RedisConfiguration extends Object {
104+
private Properties properties;
105+
106+
/**
107+
* Constructs a RedisConfiguration object for the given properties.
108+
*/
109+
RedisConfiguration() { this = properties.getProperty("redisConfiguration") }
110+
111+
/** Returns the 'aad-enabled' property as a StringLiteral, if present. */
112+
StringLiteral getAadEnabled() { result = this.getProperty("aad-enabled") }
113+
114+
/** Returns the 'aad-enabled' property as a string, if present. */
115+
string aadEnabled() { result = this.getAadEnabled().getValue() }
116+
117+
/** Returns the 'aof-backup-enabled' property as a StringLiteral, if present. */
118+
StringLiteral getAofBackupEnabled() { result = this.getProperty("aof-backup-enabled") }
119+
120+
/** Returns the 'aof-backup-enabled' property as a string, if present. */
121+
string aofBackupEnabled() { result = this.getAofBackupEnabled().getValue() }
122+
123+
/** Returns the 'aof-storage-connection-string-0' property as a StringLiteral, if present. */
124+
StringLiteral getAofStorageConnectionString0() {
125+
result = this.getProperty("aof-storage-connection-string-0")
126+
}
127+
128+
/** Returns the 'aof-storage-connection-string-0' property as a string, if present. */
129+
string aofStorageConnectionString0() {
130+
result = this.getAofStorageConnectionString0().getValue()
131+
}
132+
133+
/** Returns the 'aof-storage-connection-string-1' property as a StringLiteral, if present. */
134+
StringLiteral getAofStorageConnectionString1() {
135+
result = this.getProperty("aof-storage-connection-string-1")
136+
}
137+
138+
/** Returns the 'aof-storage-connection-string-1' property as a string, if present. */
139+
string aofStorageConnectionString1() {
140+
result = this.getAofStorageConnectionString1().getValue()
141+
}
142+
143+
/** Returns the 'authnotrequired' property as a StringLiteral, if present. */
144+
StringLiteral getAuthNotRequired() { result = this.getProperty("authnotrequired") }
145+
146+
/** Returns the 'authnotrequired' property as a string, if present. */
147+
string authNotRequired() { result = this.getAuthNotRequired().getValue() }
148+
149+
/** Returns the 'maxfragmentationmemory-reserved' property as a StringLiteral, if present. */
150+
StringLiteral getMaxFragmentationMemoryReserved() {
151+
result = this.getProperty("maxfragmentationmemory-reserved")
152+
}
153+
154+
/** Returns the 'maxfragmentationmemory-reserved' property as a string, if present. */
155+
string maxFragmentationMemoryReserved() {
156+
result = this.getMaxFragmentationMemoryReserved().getValue()
157+
}
158+
159+
/** Returns the 'maxmemory-delta' property as a StringLiteral, if present. */
160+
StringLiteral getMaxMemoryDelta() { result = this.getProperty("maxmemory-delta") }
161+
162+
/** Returns the 'maxmemory-delta' property as a string, if present. */
163+
string maxMemoryDelta() { result = this.getMaxMemoryDelta().getValue() }
164+
165+
/** Returns the 'maxmemory-policy' property as a StringLiteral, if present. */
166+
StringLiteral getMaxMemoryPolicy() { result = this.getProperty("maxmemory-policy") }
167+
168+
/** Returns the 'maxmemory-policy' property as a string, if present. */
169+
string maxMemoryPolicy() { result = this.getMaxMemoryPolicy().getValue() }
170+
171+
/** Returns the 'maxmemory-reserved' property as a StringLiteral, if present. */
172+
StringLiteral getMaxMemoryReserved() { result = this.getProperty("maxmemory-reserved") }
173+
174+
/** Returns the 'maxmemory-reserved' property as a string, if present. */
175+
string maxMemoryReserved() { result = this.getMaxMemoryReserved().getValue() }
176+
177+
/** Returns the 'notify-keyspace-events' property as a StringLiteral, if present. */
178+
StringLiteral getNotifyKeyspaceEvents() {
179+
result = this.getProperty("notify-keyspace-events")
180+
}
181+
182+
/** Returns the 'notify-keyspace-events' property as a string, if present. */
183+
string notifyKeyspaceEvents() { result = this.getNotifyKeyspaceEvents().getValue() }
184+
185+
/** Returns the 'preferred-data-persistence-auth-method' property as a StringLiteral, if present. */
186+
StringLiteral getPreferredDataPersistenceAuthMethod() {
187+
result = this.getProperty("preferred-data-persistence-auth-method")
188+
}
189+
190+
/** Returns the 'preferred-data-persistence-auth-method' property as a string, if present. */
191+
string preferredDataPersistenceAuthMethod() {
192+
result = this.getPreferredDataPersistenceAuthMethod().getValue()
193+
}
194+
195+
/** Returns the 'rdb-backup-enabled' property as a StringLiteral, if present. */
196+
StringLiteral getRdbBackupEnabled() { result = this.getProperty("rdb-backup-enabled") }
197+
198+
/** Returns the 'rdb-backup-enabled' property as a string, if present. */
199+
string rdbBackupEnabled() { result = this.getRdbBackupEnabled().getValue() }
200+
201+
/** Returns the 'rdb-backup-frequency' property as a StringLiteral, if present. */
202+
StringLiteral getRdbBackupFrequency() { result = this.getProperty("rdb-backup-frequency") }
203+
204+
/** Returns the 'rdb-backup-frequency' property as a string, if present. */
205+
string rdbBackupFrequency() { result = this.getRdbBackupFrequency().getValue() }
206+
207+
/** Returns the 'rdb-backup-max-snapshot-count' property as a StringLiteral, if present. */
208+
StringLiteral getRdbBackupMaxSnapshotCount() {
209+
result = this.getProperty("rdb-backup-max-snapshot-count")
210+
}
211+
212+
/** Returns the 'rdb-backup-max-snapshot-count' property as a string, if present. */
213+
string rdbBackupMaxSnapshotCount() { result = this.getRdbBackupMaxSnapshotCount().getValue() }
214+
215+
/** Returns the 'rdb-storage-connection-string' property as a StringLiteral, if present. */
216+
StringLiteral getRdbStorageConnectionString() {
217+
result = this.getProperty("rdb-storage-connection-string")
218+
}
219+
220+
/** Returns the 'rdb-storage-connection-string' property as a string, if present. */
221+
string rdbStorageConnectionString() {
222+
result = this.getRdbStorageConnectionString().getValue()
223+
}
224+
225+
/** Returns the 'storage-subscription-id' property as a StringLiteral, if present. */
226+
StringLiteral getStorageSubscriptionId() {
227+
result = this.getProperty("storage-subscription-id")
228+
}
229+
230+
/** Returns the 'storage-subscription-id' property as a string, if present. */
231+
string storageSubscriptionId() { result = this.getStorageSubscriptionId().getValue() }
232+
233+
/**
234+
* Returns a string representation of the RedisConfiguration object.
235+
*/
236+
string toString() { result = "RedisConfiguration" }
237+
}
238+
}
239+
}

ql/lib/codeql/bicep/frameworks/Microsoft/Databases.qll

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -211,21 +211,6 @@ module Databases {
211211
override string databaseType() { result = "datalakestore" }
212212
}
213213

214-
/**
215-
* Represents an Azure Cache for Redis resource.
216-
*/
217-
class RedisCaches extends DatabaseResource, Resource {
218-
/**
219-
* Constructs an instance for Azure Cache for Redis resources.
220-
*/
221-
RedisCaches() { this.getResourceType().regexpMatch("^Microsoft.Cache/Redis@.*") }
222-
223-
/**
224-
* Returns the type of the database resource ("redis").
225-
*/
226-
override string databaseType() { result = "redis" }
227-
}
228-
229214
/**
230215
* Represents an Azure Data Explorer (Kusto) cluster resource.
231216
*/
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
private import bicep
2+
3+
class Sku extends Object {
4+
private Resource resource;
5+
6+
/**
7+
* Constructs a Sku object for the given resource.
8+
*/
9+
Sku() { this = resource.getProperty("sku") }
10+
11+
/**
12+
* Returns the SKU name (e.g., Basic, Standard, Premium).
13+
*/
14+
string getName() {
15+
result = this.getProperty("name").(StringLiteral).getValue()
16+
}
17+
18+
/**
19+
* Returns the SKU tier (e.g., Basic, Standard, Premium).
20+
*/
21+
string getTier() {
22+
result = this.getProperty("tier").(StringLiteral).getValue()
23+
}
24+
25+
string toString() {
26+
result = "SKU"
27+
}
28+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
cache
2+
| app.bicep:1:1:17:1 | RedisCacheResource |
3+
cacheConfig
4+
| app.bicep:1:1:17:1 | RedisCacheResource | app.bicep:13:25:15:5 | RedisConfiguration |
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import bicep
2+
3+
query predicate cache(Cache::CacheResource cache) { any() }
4+
5+
query predicate cacheConfig(
6+
Cache::RedisCacheResource cache, Cache::CacheProperties::RedisConfiguration config
7+
) {
8+
cache.getRedisConfiguration() = config
9+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
resource redisCache 'Microsoft.Cache/Redis@2023-04-01' = {
2+
name: 'myRedisCache'
3+
location: resourceGroup().location
4+
sku: {
5+
name: 'Standard'
6+
family: 'C'
7+
capacity: 1
8+
}
9+
properties: {
10+
enableNonSslPort: false
11+
minimumTlsVersion: '1.2'
12+
publicNetworkAccess: 'Enabled'
13+
redisConfiguration: {
14+
maxmemory-policy: 'allkeys-lru'
15+
}
16+
}
17+
}

ql/test/library-tests/frameworks/databases/Databases.expected

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,5 @@
88
| app.bicep:98:1:111:1 | DatabaseResource[mysql] |
99
| app.bicep:114:1:124:1 | DatabaseResource[mariadb] |
1010
| app.bicep:127:1:131:1 | DatabaseResource[datalakestore] |
11-
| app.bicep:134:1:144:1 | DatabaseResource[redis] |
12-
| app.bicep:147:1:156:1 | DatabaseResource[kusto] |
13-
| app.bicep:159:1:166:1 | DatabaseResource[arc-sql-managed-instance] |
11+
| app.bicep:134:1:143:1 | DatabaseResource[kusto] |
12+
| app.bicep:146:1:153:1 | DatabaseResource[arc-sql-managed-instance] |

ql/test/library-tests/frameworks/databases/app.bicep

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,6 @@ resource datalakeStore 'Microsoft.DataLakeStore/accounts@2016-11-01' = {
130130
properties: {}
131131
}
132132
133-
// Azure Cache for Redis
134-
resource redisCache 'Microsoft.Cache/Redis@2023-04-01' = {
135-
name: 'rediscache1'
136-
location: 'eastus'
137-
properties: {
138-
sku: {
139-
name: 'Basic'
140-
family: 'C'
141-
capacity: 0
142-
}
143-
}
144-
}
145-
146133
// Azure Data Explorer (Kusto)
147134
resource kustoCluster 'Microsoft.Kusto/Clusters@2023-05-02' = {
148135
name: 'kustocluster1'

0 commit comments

Comments
 (0)