You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jr...@apache.org on 2019/01/30 15:57:09 UTC
[trafficserver] branch master updated: JWT Parser strips token from
URI and places in buffer
This is an automated email from the ASF dual-hosted git repository.
jrushford pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 5f9d358 JWT Parser strips token from URI and places in buffer
5f9d358 is described below
commit 5f9d358b721fbe9b7660e23610d19632f7655503
Author: Dylan Souza <dy...@comcast.com>
AuthorDate: Tue Jan 15 18:50:55 2019 +0000
JWT Parser strips token from URI and places in buffer
---
plugins/experimental/uri_signing/parse.c | 28 +++-
plugins/experimental/uri_signing/parse.h | 3 +-
.../uri_signing/unit_tests/uri_signing_test.cc | 174 +++++++++++++++++++++
plugins/experimental/uri_signing/uri_signing.c | 8 +-
4 files changed, 208 insertions(+), 5 deletions(-)
diff --git a/plugins/experimental/uri_signing/parse.c b/plugins/experimental/uri_signing/parse.c
index 99ded7b..099acdb 100644
--- a/plugins/experimental/uri_signing/parse.c
+++ b/plugins/experimental/uri_signing/parse.c
@@ -29,10 +29,11 @@
#include <inttypes.h>
cjose_jws_t *
-get_jws_from_uri(const char *uri, size_t uri_ct, const char *paramName)
+get_jws_from_uri(const char *uri, size_t uri_ct, const char *paramName, char *strip_uri, size_t buff_ct, size_t *strip_ct)
{
/* Reserved characters as defined by the URI Generic Syntax RFC: https://tools.ietf.org/html/rfc3986#section-2.2 */
- const char *reserved_string = ":/?#[]@!$&\'()*+,;=";
+ static const char *reserved_string = ":/?#[]@!$&\'()*+,;=";
+ static const char *sub_delim_string = "!$&\'()*+,;=";
/* If param name ends in reserved character this will be treated as the termination symbol when parsing for package. Default is
* '='. */
@@ -94,6 +95,29 @@ get_jws_from_uri(const char *uri, size_t uri_ct, const char *paramName)
PluginDebug("Unable to read JWS: %.*s, %s", (int)(key_end - key), key, err.message ? err.message : "");
} else {
PluginDebug("Parsed JWS: %.*s (%16p)", (int)(key_end - key), key, jws);
+
+ /* Strip token */
+ /* Check that passed buffer is large enough */
+ *strip_ct = ((key - uri) + (end - value_end));
+ if (buff_ct <= *strip_ct) {
+ PluginDebug("Strip URI buffer is not large enough");
+ return NULL;
+ }
+
+ if (value_end != end && strchr(sub_delim_string, *value_end)) {
+ /*Strip from first char of package name to sub-delimeter that terminates the signed JWT */
+ memcpy(strip_uri, uri, (key - uri));
+ memcpy(strip_uri + (key - uri), value_end + 1, (end - value_end + 1));
+ } else {
+ /*Strip from reserved char to the last char of the JWT */
+ memcpy(strip_uri, uri, (key - uri - 1));
+ memcpy(strip_uri + (key - uri - 1), value_end, (end - value_end));
+ }
+
+ if (strip_uri[*strip_ct - 1] != '\0') {
+ strip_uri[*strip_ct - 1] = '\0';
+ }
+ PluginDebug("Stripped URI: %s", strip_uri);
}
return jws;
}
diff --git a/plugins/experimental/uri_signing/parse.h b/plugins/experimental/uri_signing/parse.h
index 8d82c63..d05bfd5 100644
--- a/plugins/experimental/uri_signing/parse.h
+++ b/plugins/experimental/uri_signing/parse.h
@@ -19,7 +19,8 @@
#include <stdlib.h>
struct _cjose_jws_int;
-struct _cjose_jws_int *get_jws_from_uri(const char *uri, size_t uri_ct, const char *paramName);
+struct _cjose_jws_int *get_jws_from_uri(const char *uri, size_t uri_ct, const char *paramName, char *strip_uri, size_t buff_ct,
+ size_t *strip_ct);
struct _cjose_jws_int *get_jws_from_cookie(const char **cookie, size_t *cookie_ct, const char *paramName);
struct config;
diff --git a/plugins/experimental/uri_signing/unit_tests/uri_signing_test.cc b/plugins/experimental/uri_signing/unit_tests/uri_signing_test.cc
index 30b8681..b879f7c 100644
--- a/plugins/experimental/uri_signing/unit_tests/uri_signing_test.cc
+++ b/plugins/experimental/uri_signing/unit_tests/uri_signing_test.cc
@@ -28,6 +28,7 @@ extern "C" {
#include <cjose/cjose.h>
#include "../jwt.h"
#include "../normalize.h"
+#include "../parse.h"
}
bool
@@ -92,6 +93,28 @@ remove_dot_helper(const char *path, const char *expected_path)
}
}
+bool
+jws_parsing_helper(const char *uri, const char *paramName, const char *expected_strip)
+{
+ bool resp;
+ size_t uri_ct = strlen(uri);
+ size_t strip_ct = 0;
+ char uri_strip[uri_ct + 1];
+ memset(uri_strip, 0, sizeof uri_strip);
+ cjose_jws_t *jws = get_jws_from_uri(uri, uri_ct, paramName, uri_strip, uri_ct, &strip_ct);
+ if (jws) {
+ resp = true;
+ if (strcmp(uri_strip, expected_strip) != 0) {
+ cjose_jws_release(jws);
+ resp = false;
+ }
+ } else {
+ resp = false;
+ }
+ cjose_jws_release(jws);
+ return resp;
+}
+
TEST_CASE("1", "[JWSParsingTest]")
{
INFO("TEST 1, Test JWT Parsing From Token Strings");
@@ -136,6 +159,157 @@ TEST_CASE("1", "[JWSParsingTest]")
fprintf(stderr, "\n");
}
+TEST_CASE("2", "[JWSFromURLTest]")
+{
+ INFO("TEST 2, Test JWT Parsing and Stripping From URLs");
+
+ SECTION("Token at end of URI")
+ {
+ REQUIRE(jws_parsing_helper(
+ "www.foo.com/hellothere/"
+ "URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
+ "URISigningPackage", "www.foo.com/hellothere"));
+ }
+
+ SECTION("No Token in URL")
+ {
+ REQUIRE(!jws_parsing_helper(
+ "www.foo.com/hellothere/"
+ "URISigningPackag=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
+ "URISigningPackage", NULL));
+ }
+
+ SECTION("Token in middle of the URL")
+ {
+ REQUIRE(jws_parsing_helper("www.foo.com/hellothere/"
+ "URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/Something/Else",
+ "URISigningPackage", "www.foo.com/hellothere/Something/Else"));
+ }
+
+ SECTION("Token at the start of the URL")
+ {
+ REQUIRE(jws_parsing_helper(":URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/www.foo.com/hellothere/Something/Else",
+ "URISigningPackage", "/www.foo.com/hellothere/Something/Else"));
+ }
+
+ SECTION("Pass empty path parameter at end")
+ {
+ REQUIRE(!jws_parsing_helper("www.foobar.com/hellothere/URISigningPackage=", "URISigningPackage", NULL));
+ }
+
+ SECTION("Pass empty path parameter in the middle of URL")
+ {
+ REQUIRE(!jws_parsing_helper("www.foobar.com/hellothere/URISigningPackage=/Something/Else", "URISigningPackage", NULL));
+ }
+
+ SECTION("Partial package name in previous path parameter")
+ {
+ REQUIRE(jws_parsing_helper("www.foobar.com/URISig/"
+ "URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/Something/Else",
+ "URISigningPackage", "www.foobar.com/URISig/Something/Else"));
+ }
+
+ SECTION("Package comes directly after two reserved characters")
+ {
+ REQUIRE(jws_parsing_helper("www.foobar.com/"
+ ":URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/Something/Else",
+ "URISigningPackage", "www.foobar.com//Something/Else"));
+ }
+
+ SECTION("Package comes directly after string of reserved characters")
+ {
+ REQUIRE(jws_parsing_helper("www.foobar.com/?!/"
+ ":URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/Something/Else",
+ "URISigningPackage", "www.foobar.com/?!//Something/Else"));
+ }
+
+ SECTION("Invalid token passed before a valid token")
+ {
+ REQUIRE(!jws_parsing_helper("www.foobar.com/URISigningPackage=/"
+ "URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/Something/Else",
+ "URISigningPackage", NULL));
+ }
+
+ SECTION("Empty string as URL") { REQUIRE(!jws_parsing_helper("", "URISigningPackage", NULL)); }
+
+ SECTION("Empty package name to parser")
+ {
+ REQUIRE(!jws_parsing_helper(
+ "www.foobar.com/"
+ "URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
+ "", NULL));
+ }
+
+ SECTION("Custom package name with a reserved character - at the end of the URI")
+ {
+ REQUIRE(jws_parsing_helper(
+ "www.foobar.com/CustomPackage/"
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
+ "CustomPackage/", "www.foobar.com"));
+ }
+
+ SECTION("Custom package name with a reserved character - in the middle of the URI")
+ {
+ REQUIRE(jws_parsing_helper(
+ "www.foobar.com/CustomPackage/"
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/Something/Else",
+ "CustomPackage/", "www.foobar.com/Something/Else"));
+ }
+
+ SECTION("URI signing package passed as the only a query parameter")
+ {
+ REQUIRE(jws_parsing_helper(
+ "www.foobar.com/Something/"
+ "Here?URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
+ "URISigningPackage", "www.foobar.com/Something/Here"));
+ }
+
+ SECTION("URI signing package passed as first of many query parameters")
+ {
+ REQUIRE(jws_parsing_helper("www.foobar.com/Something/"
+ "Here?URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c&query3=foobar&query1=foo&query2=bar",
+ "URISigningPackage", "www.foobar.com/Something/Here?query3=foobar&query1=foo&query2=bar"));
+ }
+
+ SECTION("URI signing package passed as one of many query parameters - passed in middle")
+ {
+ REQUIRE(jws_parsing_helper("www.foobar.com/Something/"
+ "Here?query1=foo&query2=bar&URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c&query3=foobar",
+ "URISigningPackage", "www.foobar.com/Something/Here?query1=foo&query2=bar&query3=foobar"));
+ }
+
+ SECTION("URI signing package passed as last of many query parameters")
+ {
+ REQUIRE(jws_parsing_helper("www.foobar.com/Something/"
+ "Here?query1=foo&query2=bar&URISigningPackage=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
+ "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
+ "URISigningPackage", "www.foobar.com/Something/Here?query1=foo&query2=bar"));
+ }
+}
+
TEST_CASE("3", "[RemoveDotSegmentsTest]")
{
INFO("TEST 3, Test Removal of Dot Segments From Paths");
diff --git a/plugins/experimental/uri_signing/uri_signing.c b/plugins/experimental/uri_signing/uri_signing.c
index 044731b..fadd269 100644
--- a/plugins/experimental/uri_signing/uri_signing.c
+++ b/plugins/experimental/uri_signing/uri_signing.c
@@ -175,7 +175,11 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
if (cpi < max_cpi) {
checkpoints[cpi++] = mark_timer(&t);
}
- cjose_jws_t *jws = get_jws_from_uri(url, url_ct, package);
+
+ char strip_uri[2000] = {0};
+ size_t strip_ct;
+ cjose_jws_t *jws = get_jws_from_uri(url, url_ct, package, strip_uri, 2000, &strip_ct);
+
if (cpi < max_cpi) {
checkpoints[cpi++] = mark_timer(&t);
}
@@ -222,7 +226,7 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
if (cpi < max_cpi) {
checkpoints[cpi++] = mark_timer(&t);
}
- struct jwt *jwt = validate_jws(jws, (struct config *)ih, url, url_ct);
+ struct jwt *jwt = validate_jws(jws, (struct config *)ih, strip_uri, strip_ct);
cjose_jws_release(jws);
if (cpi < max_cpi) {
checkpoints[cpi++] = mark_timer(&t);