diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0a3f177315b16c99ece09428b31306ba88161287..6635070320864c5ddf20aeb41f28e929253c8682 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,37 @@
 # Changelog
 
+## 2.3.3
+This release fixes a security vulnerability caused by the CORS implementation.
+Origins allowed for CORS can now be set in the configuration via
+`security.cors.origins`. (Reported by Rainer Rillke at Wikimedia)
+
+Additional changes:
+* Libraries have been upgraded to fix potential bugs
+
+## 2.2.2
+This release fixes a security vulnerability caused by the CORS implementation.
+Origins allowed for CORS can now be set in the configuration via
+`security.cors.origins`. (Reported by Rainer Rillke at Wikimedia)
+
+Additional changes:
+* Libraries have been upgraded to fix potential bugs
+
+## 2.1.2
+This release fixes a security vulnerability caused by the CORS implementation.
+Support for cross-origin requests has been removed. Use ARSnova version 2.2 or
+newer for proper CORS. (Reported by Rainer Rillke at Wikimedia)
+
+Additional changes:
+* Libraries have been upgraded to fix potential bugs
+
+## 2.0.4
+This release fixes a security vulnerability caused by the CORS implementation.
+Support for cross-origin requests has been removed. Use ARSnova version 2.2 or
+newer for proper CORS. (Reported by Rainer Rillke at Wikimedia)
+
+Additional changes:
+* Libraries have been upgraded to fix potential bugs
+
 ## 2.4
 Major features:
 * Support for new use case and feature settings has been added.
diff --git a/pom.xml b/pom.xml
index 36254d827930a653eef9dc7029a83959dcf62a5f..390523a5f21dd96e6c783f29ec68c9815edf5bbb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -80,7 +80,7 @@
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-javadoc-plugin</artifactId>
-				<version>2.10.3</version>
+				<version>2.10.4</version>
 				<configuration></configuration>
 			</plugin>
 		</plugins>
@@ -177,7 +177,7 @@
 		<dependency>
 			<groupId>cglib</groupId>
 			<artifactId>cglib</artifactId>
-			<version>3.2.2</version>
+			<version>3.2.4</version>
 		</dependency>
 		<dependency>
 			<groupId>org.slf4j</groupId>
@@ -325,7 +325,7 @@
 			<plugin>
 				<groupId>org.eclipse.jetty</groupId>
 				<artifactId>jetty-maven-plugin</artifactId>
-				<version>9.2.16.v20160414</version>
+				<version>9.2.17.v20160517</version>
 				<configuration>
 					<scanIntervalSeconds>1</scanIntervalSeconds>
 					<webApp>
@@ -365,7 +365,7 @@
 			<plugin>
 				<groupId>org.jacoco</groupId>
 				<artifactId>jacoco-maven-plugin</artifactId>
-				<version>0.7.6.201602180812</version>
+				<version>0.7.7.201606060606</version>
 				<executions>
 					<execution>
 						<id>default-prepare-agent</id>
diff --git a/src/main/java/de/thm/arsnova/config/ExtraConfig.java b/src/main/java/de/thm/arsnova/config/ExtraConfig.java
index ff713d4e95c408fe4c36882c9ca7b11fc363146b..e37d28ed49a21e562cda22c90a96f6776a0cf44a 100644
--- a/src/main/java/de/thm/arsnova/config/ExtraConfig.java
+++ b/src/main/java/de/thm/arsnova/config/ExtraConfig.java
@@ -18,6 +18,7 @@
 package de.thm.arsnova.config;
 
 import de.thm.arsnova.ImageUtils;
+import de.thm.arsnova.web.CorsFilter;
 import de.thm.arsnova.connector.client.ConnectorClient;
 import de.thm.arsnova.connector.client.ConnectorClientImpl;
 import de.thm.arsnova.socket.ARSnovaSocket;
@@ -40,6 +41,9 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 
 
+import java.util.Arrays;
+import java.util.Collections;
+
 /**
  * Loads property file and configures non-security related beans and components.
  */
@@ -61,6 +65,7 @@ public class ExtraConfig extends WebMvcConfigurerAdapter {
 	@Value(value = "${security.ssl}") private boolean socketUseSll;
 	@Value(value = "${security.keystore}") private String socketKeystore;
 	@Value(value = "${security.storepass}") private String socketStorepass;
+	@Value(value = "${security.cors.origins:}") private String[] corsOrigins;
 
 	private static int testPortOffset = 0;
 
@@ -84,6 +89,11 @@ public class ExtraConfig extends WebMvcConfigurerAdapter {
 		return propertiesFactoryBean;
 	}
 
+	@Bean
+	public CorsFilter corsFilter() {
+		return new CorsFilter(Arrays.asList(corsOrigins));
+	}
+
 	@Bean(name = "connectorClient")
 	public ConnectorClient connectorClient() {
 		if (!connectorEnable) {
diff --git a/src/main/java/de/thm/arsnova/web/CorsFilter.java b/src/main/java/de/thm/arsnova/web/CorsFilter.java
index f4c434e02cc65f0a89da48cdb9acda407780cdd1..acd2f7dc1541bbee46c504e0a90d2a5d9065e3de 100644
--- a/src/main/java/de/thm/arsnova/web/CorsFilter.java
+++ b/src/main/java/de/thm/arsnova/web/CorsFilter.java
@@ -17,36 +17,52 @@
  */
 package de.thm.arsnova.web;
 
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
+import java.util.List;
 
-/**
- * Sets response headers to allow CORS requests.
- */
-@Component
-public class CorsFilter extends OncePerRequestFilter {
+public class CorsFilter extends org.springframework.web.filter.CorsFilter {
+	protected final Logger logger = LoggerFactory.getLogger(CorsFilter.class);
+
+	public CorsFilter(List<String> origins) {
+		super(configurationSource(origins));
+		logger.info("CorsFilter initialized. Allowed origins: {}", origins);
+	}
 
-	@Override
-	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-			throws ServletException, IOException {
-		response.addHeader("Access-Control-Allow-Credentials", "true");
-		response.addHeader("Access-Control-Allow-Methods", "GET");
-		response.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
+	private static UrlBasedCorsConfigurationSource configurationSource(List<String> origins) {
+		CorsConfiguration config;
+		UrlBasedCorsConfigurationSource source;
 
-		if (request.getHeader("origin") != null) {
-			response.addHeader("Access-Control-Allow-Origin", sanitizeOriginUrl(request.getHeader("origin")));
-		}
+		/* Grant full access from specified origins */
+		config = new CorsConfiguration();
+		config.setAllowedOrigins(origins);
+		config.addAllowedHeader("Accept");
+		config.addAllowedHeader("Content-Type");
+		config.addAllowedHeader("X-Requested-With");
+		config.addAllowedMethod("GET");
+		config.addAllowedMethod("POST");
+		config.addAllowedMethod("PUT");
+		config.addAllowedMethod("DELETE");
+		config.setAllowCredentials(true);
+		source = new UrlBasedCorsConfigurationSource();
+		source.registerCorsConfiguration("/**", config);
 
-		filterChain.doFilter(request, response);
-	}
+		/* Grant limited access from all origins */
+		config = new CorsConfiguration();
+		config.addAllowedOrigin("*");
+		config.addAllowedHeader("Accept");
+		config.addAllowedHeader("X-Requested-With");
+		config.addAllowedMethod("GET");
+		config.setAllowCredentials(true);
+		source = new UrlBasedCorsConfigurationSource();
+		source.registerCorsConfiguration("/", config);
+		source.registerCorsConfiguration("/arsnova-config", config);
+		source.registerCorsConfiguration("/configuration/", config);
+		source.registerCorsConfiguration("/statistics", config);
 
-	private String sanitizeOriginUrl(String originUrl) {
-		return originUrl.replaceAll("[\n\r]+", " ");
+		return source;
 	}
 }
diff --git a/src/main/resources/arsnova.properties.example b/src/main/resources/arsnova.properties.example
index f7efb747218faba8df18a1964abd541f243b72fe..ee1bab9736f07a5332cb7ac7d48864792cc3d992 100644
--- a/src/main/resources/arsnova.properties.example
+++ b/src/main/resources/arsnova.properties.example
@@ -167,6 +167,15 @@ security.google.key=
 security.google.secret=
 
 
+################################################################################
+# Cross-Origin Resource Sharing
+################################################################################
+# CORS grants full API access to client-side (browser) applications from other
+# domains. Multiple entries are separated by commas. Untrusted and vulnerable
+# applications running on these domains pose a security risk to ARSnova users.
+#security.cors.origins=https://
+
+
 ################################################################################
 # ARSnova Connector (for LMS)
 ################################################################################
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index 7daa0e4c21695641e954b8e1b98c8239c3c9e33a..95f404bd0d1c9ec724d76b00eb5aba0bff6f4818 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -63,7 +63,7 @@
 
 	<filter>
 		<filter-name>corsFilter</filter-name>
-		<filter-class>de.thm.arsnova.web.CorsFilter</filter-class>
+		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 		<async-supported>true</async-supported>
 	</filter>
 	<filter-mapping>
diff --git a/src/test/resources/arsnova.properties.example b/src/test/resources/arsnova.properties.example
index 3f118a73331349cb3c25362bf29e8e5db0dd5e71..b9bd4b7891dc305f7f721c2067a677f9b793392a 100644
--- a/src/test/resources/arsnova.properties.example
+++ b/src/test/resources/arsnova.properties.example
@@ -160,6 +160,15 @@ security.google.key=
 security.google.secret=
 
 
+################################################################################
+# Cross-Origin Resource Sharing
+################################################################################
+# CORS grants full API access to client-side (browser) applications from other
+# domains. Multiple entries are separated by commas. Untrusted and vulnerable
+# applications running on these domains pose a security risk to ARSnova users.
+#security.cors.origins=https://
+
+
 ################################################################################
 # ARSnova Connector (for LMS)
 ################################################################################