From e357ff004b6e5a8e47171921f5f1c4eede429640 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 28 Apr 2021 13:52:52 -0400 Subject: [PATCH] check Origin + Sec-Fetch-Site headers for site API --- .../attestation/server/AttestationServer.java | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/main/java/app/attestation/server/AttestationServer.java b/src/main/java/app/attestation/server/AttestationServer.java index 61b202b7..82b843f2 100644 --- a/src/main/java/app/attestation/server/AttestationServer.java +++ b/src/main/java/app/attestation/server/AttestationServer.java @@ -92,6 +92,8 @@ public class AttestationServer { private static final long SESSION_LENGTH = 48 * 60 * 60 * 1000; private static final int HISTORY_PER_PAGE = 20; + private static final String ORIGIN = "https://attestation.app"; + private static final Logger logger = Logger.getLogger(AttestationServer.class.getName()); // This should be moved to a table in the database so that it can be modified dynamically @@ -388,6 +390,17 @@ public static void main(final String[] args) throws Exception { private abstract static class PostHandler implements HttpHandler { protected abstract void handlePost(final HttpExchange exchange) throws IOException, SQLiteException; + public void checkOrigin(final HttpExchange exchange) throws GeneralSecurityException { + final List origin = exchange.getRequestHeaders().get("Origin"); + if (origin != null && !origin.get(0).equals(ORIGIN)) { + throw new GeneralSecurityException(); + } + final List fetchSite = exchange.getRequestHeaders().get("Sec-Fetch-Site"); + if (fetchSite != null && !fetchSite.get(0).equals("same-origin")) { + throw new GeneralSecurityException(); + } + } + @Override public final void handle(final HttpExchange exchange) throws IOException { try { @@ -396,6 +409,12 @@ public final void handle(final HttpExchange exchange) throws IOException { exchange.sendResponseHeaders(405, -1); return; } + try { + checkOrigin(exchange); + } catch (final GeneralSecurityException e) { + exchange.sendResponseHeaders(403, -1); + return; + } handlePost(exchange); } catch (final Exception e) { logger.log(Level.SEVERE, "unhandled error handling request", e); @@ -406,6 +425,11 @@ public final void handle(final HttpExchange exchange) throws IOException { } } + private abstract static class AppPostHandler extends PostHandler { + @Override + public void checkOrigin(final HttpExchange exchange) {} + } + private static final SecureRandom random = new SecureRandom(); private static byte[] generateRandomToken() { @@ -1248,7 +1272,7 @@ private static void writeAttestationHistoryJson(final HttpExchange exchange, fin } } - private static class ChallengeHandler extends PostHandler { + private static class ChallengeHandler extends AppPostHandler { @Override public void handlePost(final HttpExchange exchange) throws IOException { final byte[] challenge = AttestationProtocol.getChallenge(); @@ -1265,7 +1289,7 @@ public void handlePost(final HttpExchange exchange) throws IOException { } } - private static class VerifyHandler extends PostHandler { + private static class VerifyHandler extends AppPostHandler { @Override public void handlePost(final HttpExchange exchange) throws IOException, SQLiteException { final List authorization = exchange.getRequestHeaders().get("Authorization"); @@ -1347,7 +1371,7 @@ public void handlePost(final HttpExchange exchange) throws IOException, SQLiteEx } } - private static class SubmitHandler extends PostHandler { + private static class SubmitHandler extends AppPostHandler { @Override public void handlePost(final HttpExchange exchange) throws IOException, SQLiteException { final InputStream input = exchange.getRequestBody();