Skip to content

Commit fa2deee

Browse files
author
Dylan Souza
committed
Strip token from upstream if conifigured and dynamically allocate string buffers
Adds a configuration option to strip uri signing tokens from both the cache key URL and the upstream URL. Additionally it was pointed out that some statically allocated buffers were too small in some of the string manipulating functions (normalize and strip token). These buffers are now dynamically allocated since the maximum buffer size is known for these.
1 parent 4f3b3c3 commit fa2deee

File tree

5 files changed

+84
-18
lines changed

5 files changed

+84
-18
lines changed

plugins/experimental/uri_signing/config.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct config {
4545
char **issuer_names;
4646
struct signer signer;
4747
struct auth_directive *auth_directives;
48+
bool strip_token;
4849
};
4950

5051
cjose_jwk_t **
@@ -80,6 +81,12 @@ find_key_by_kid(struct config *cfg, const char *issuer, const char *kid)
8081
return NULL;
8182
}
8283

84+
bool
85+
config_strip_token(struct config *cfg)
86+
{
87+
return cfg->strip_token;
88+
}
89+
8390
struct config *
8491
config_new(size_t n)
8592
{
@@ -106,6 +113,8 @@ config_new(size_t n)
106113

107114
cfg->auth_directives = NULL;
108115

116+
cfg->strip_token = false;
117+
109118
PluginDebug("New config object created at %p", cfg);
110119
return cfg;
111120
}
@@ -259,6 +268,11 @@ read_config(const char *path)
259268
renewal_kid = json_string_value(renewal_kid_json);
260269
}
261270

271+
json_t *strip_json = json_object_get(jwks, "strip_token");
272+
if (strip_json) {
273+
cfg->strip_token = json_boolean_value(strip_json);
274+
}
275+
262276
size_t jwks_ct = json_array_size(key_ary);
263277
cjose_jwk_t **jwks = (*jwkis++ = malloc((jwks_ct + 1) * sizeof *jwks));
264278
PluginDebug("Created table with size %d", cfg->issuers->size);

plugins/experimental/uri_signing/config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ struct signer *config_signer(struct config *);
3333
struct _cjose_jwk_int **find_keys(struct config *cfg, const char *issuer);
3434
struct _cjose_jwk_int *find_key_by_kid(struct config *cfg, const char *issuer, const char *kid);
3535
bool uri_matches_auth_directive(struct config *cfg, const char *uri, size_t uri_ct);
36+
bool config_strip_token(struct config *cfg);

plugins/experimental/uri_signing/jwt.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,41 +173,49 @@ jwt_check_uri(const char *cdniuc, const char *uri)
173173
int uri_ct = strlen(uri);
174174
int buff_ct = uri_ct + 2;
175175
int err;
176-
char normal_uri[buff_ct];
177-
176+
char *normal_uri = (char *)malloc(buff_ct);
178177
memset(normal_uri, 0, buff_ct);
178+
179179
err = normalize_uri(uri, uri_ct, normal_uri, buff_ct);
180180

181181
if (err) {
182-
return false;
182+
goto fail_jwt;
183183
}
184184

185185
const char *kind = cdniuc, *container = cdniuc;
186186
while (*container && *container != ':') {
187187
++container;
188188
}
189189
if (!*container) {
190-
return false;
190+
goto fail_jwt;
191191
}
192192
++container;
193193

194194
size_t len = container - kind;
195+
bool status;
195196
PluginDebug("Comparing with match kind \"%.*s\" on \"%s\" to normalized URI \"%s\"", (int)len - 1, kind, container, normal_uri);
196197
switch (len) {
197198
case sizeof CONT_URI_HASH_STR:
198199
if (!strncmp(CONT_URI_HASH_STR, kind, len - 1)) {
199-
return match_hash(container, normal_uri);
200+
status = match_hash(container, normal_uri);
201+
free(normal_uri);
202+
return status;
200203
}
201204
PluginDebug("Expected kind %s, but did not find it in \"%.*s\"", CONT_URI_HASH_STR, (int)len - 1, kind);
202205
break;
203206
case sizeof CONT_URI_REGEX_STR:
204207
if (!strncmp(CONT_URI_REGEX_STR, kind, len - 1)) {
205-
return match_regex(container, normal_uri);
208+
status = match_regex(container, normal_uri);
209+
free(normal_uri);
210+
return status;
206211
}
207212
PluginDebug("Expected kind %s, but did not find it in \"%.*s\"", CONT_URI_REGEX_STR, (int)len - 1, kind);
208213
break;
209214
}
210215
PluginDebug("Unknown match kind \"%.*s\"", (int)len - 1, kind);
216+
217+
fail_jwt:
218+
free(normal_uri);
211219
return false;
212220
}
213221

plugins/experimental/uri_signing/unit_tests/uri_signing_test.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,22 @@ normalize_uri_helper(const char *uri, const char *expected_normal)
5656
size_t uri_ct = strlen(uri);
5757
int buff_size = uri_ct + 2;
5858
int err;
59-
char uri_normal[buff_size];
59+
char *uri_normal = (char *)malloc(buff_size);
6060
memset(uri_normal, 0, buff_size);
6161

6262
err = normalize_uri(uri, uri_ct, uri_normal, buff_size);
6363

6464
if (err) {
65+
free(uri_normal);
6566
return false;
6667
}
6768

6869
if (expected_normal && strcmp(expected_normal, uri_normal) == 0) {
70+
free(uri_normal);
6971
return true;
7072
}
7173

74+
free(uri_normal);
7275
return false;
7376
}
7477

@@ -99,8 +102,10 @@ jws_parsing_helper(const char *uri, const char *paramName, const char *expected_
99102
bool resp;
100103
size_t uri_ct = strlen(uri);
101104
size_t strip_ct = 0;
102-
char uri_strip[uri_ct + 1];
103-
memset(uri_strip, 0, sizeof uri_strip);
105+
106+
char *uri_strip = (char *)malloc(uri_ct + 1);
107+
memset(uri_strip, 0, uri_ct + 1);
108+
104109
cjose_jws_t *jws = get_jws_from_uri(uri, uri_ct, paramName, uri_strip, uri_ct, &strip_ct);
105110
if (jws) {
106111
resp = true;
@@ -112,6 +117,7 @@ jws_parsing_helper(const char *uri, const char *paramName, const char *expected_
112117
resp = false;
113118
}
114119
cjose_jws_release(jws);
120+
free(uri_strip);
115121
return resp;
116122
}
117123

plugins/experimental/uri_signing/uri_signing.c

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,11 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
157157
int cpi = 0;
158158
int url_ct = 0;
159159
const char *url = NULL;
160+
char *strip_uri = NULL;
160161

161162
const char *package = "URISigningPackage";
162163

164+
TSRemapStatus status = TSREMAP_NO_REMAP;
163165
TSMBuffer mbuf;
164166
TSMLoc ul;
165167
TSReturnCode rc = TSHttpTxnPristineUrlGet(txnp, &mbuf, &ul);
@@ -176,16 +178,20 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
176178
checkpoints[cpi++] = mark_timer(&t);
177179
}
178180

179-
char strip_uri[2000] = {0};
181+
strip_uri = (char *)malloc(url_ct + 1);
182+
memset(strip_uri, 0, url_ct + 1);
180183
size_t strip_ct;
181-
cjose_jws_t *jws = get_jws_from_uri(url, url_ct, package, strip_uri, 2000, &strip_ct);
184+
cjose_jws_t *jws = get_jws_from_uri(url, url_ct, package, strip_uri, url_ct + 1, &strip_ct);
182185

183186
if (cpi < max_cpi) {
184187
checkpoints[cpi++] = mark_timer(&t);
185188
}
186189
int checked_cookies = 0;
187190
if (!jws) {
188191
check_cookies:
192+
/* There is no valid token in the url */
193+
strncpy(strip_uri, url, url_ct);
194+
strip_ct = url_ct;
189195
++checked_cookies;
190196

191197
TSMLoc field;
@@ -218,6 +224,32 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
218224
checkpoints[cpi++] = mark_timer(&t);
219225
}
220226
jws = get_jws_from_cookie(&client_cookie, &client_cookie_sz_ct, package);
227+
} else {
228+
/* There has been a JWS found in the url */
229+
/* Strip the token from the URL for upstream if configured to do so */
230+
if (config_strip_token((struct config *)ih)) {
231+
if (strncmp(url, strip_uri, strip_ct) != 0) {
232+
char *strip_uri_start = &strip_uri[0];
233+
char *strip_uri_end = &strip_uri[strip_ct];
234+
PluginDebug("Stripping token from upstream url to: %s", strip_uri_start);
235+
if (TSUrlParse(rri->requestBufp, rri->requestUrl, (const char **)&strip_uri_start, strip_uri_end) != TS_PARSE_DONE) {
236+
PluginDebug("Error in TSUrlParse");
237+
} else {
238+
status = TSREMAP_DID_REMAP;
239+
}
240+
}
241+
}
242+
243+
/* Check auth_dir and pass through if configured */
244+
if (uri_matches_auth_directive((struct config *)ih, url, url_ct)) {
245+
if (url != NULL) {
246+
TSfree((void *)url);
247+
}
248+
if (url != NULL) {
249+
free(strip_uri);
250+
}
251+
return TSREMAP_NO_REMAP;
252+
}
221253
}
222254
if (!jws) {
223255
goto fail;
@@ -226,8 +258,10 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
226258
if (cpi < max_cpi) {
227259
checkpoints[cpi++] = mark_timer(&t);
228260
}
261+
229262
struct jwt *jwt = validate_jws(jws, (struct config *)ih, strip_uri, strip_ct);
230263
cjose_jws_release(jws);
264+
231265
if (cpi < max_cpi) {
232266
checkpoints[cpi++] = mark_timer(&t);
233267
}
@@ -239,6 +273,8 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
239273
}
240274
}
241275

276+
/* There has been a validated JWT found in either the cookie or url */
277+
242278
struct signer *signer = config_signer((struct config *)ih);
243279
char *cookie = renew(jwt, signer->issuer, signer->jwk, signer->alg, package);
244280
jwt_delete(jwt);
@@ -260,15 +296,13 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
260296
last_mark = checkpoints[i];
261297
}
262298
PluginDebug("Spent %" PRId64 " ns uri_signing verification of %.*s.", mark_timer(&t), url_ct, url);
299+
263300
TSfree((void *)url);
264-
return TSREMAP_NO_REMAP;
265-
fail:
266-
if (uri_matches_auth_directive((struct config *)ih, url, url_ct)) {
267-
if (url != NULL) {
268-
TSfree((void *)url);
269-
}
270-
return TSREMAP_NO_REMAP;
301+
if (strip_uri != NULL) {
302+
free(strip_uri);
271303
}
304+
return status;
305+
fail:
272306

273307
PluginDebug("Invalid JWT for %.*s", url_ct, url);
274308
TSHttpTxnStatusSet(txnp, TS_HTTP_STATUS_FORBIDDEN);
@@ -277,6 +311,9 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
277311
if (url != NULL) {
278312
TSfree((void *)url);
279313
}
314+
if (strip_uri != NULL) {
315+
free(strip_uri);
316+
}
280317

281318
return TSREMAP_DID_REMAP;
282319
}

0 commit comments

Comments
 (0)