Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
<http auto-config="true">
...
<headers disabled="true"/>
...
</http>
HttpFirewall
into its FilterChainProxy
, which processes the requests before they are sent through the filter chain. Sprint Security uses the StrictHttpFirewall
implementation by default.%2F
and ;
characters:
<beans:bean id="httpFirewall" class="org.springframework.security.web.firewall.StrictHttpFirewall" p:allowSemicolon="true" p:allowUrlEncodedSlash="true"/>
Ant
path expressions to specify how to protect endpoints./admin
" Ant
path expression requires administrator privileges for access:
<http auto-config="true">
...
<intercept-url pattern="/app/admin" access="ROLE_ADMIN" />
...
<intercept-url pattern="/**" access="permitAll" />
</http>
Accept
header or by specifying the desired content-type using an extension. For example, you can request the /admin
resource as a JSON document by sending the request to /admin.json
.Ant
path expressions do not account for content-negotiation extensions, and therefore, the request does not match the /admin
expression and the endpoint is not protected.anyRequest()
. Failing to define a fallback check that uses the anyRequest()
matcher, might leave endpoints unprotected.
<http auto-config="true">
<intercept-url pattern="/app/admin" access="ROLE_ADMIN" />
<intercept-url pattern="/" access="permitAll" />
</http>
Example 1
above, current or future endpoints such as /admin/panel
might be left unprotected.
<http auto-config="true">
...
<intercept-url pattern="/app/admin" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="permitAll" />
</http>
ACTUATOR
role may access them.
management.security.enabled=false
endpoints.health.sensitive=false
@Component
public class CustomEndpoint implements Endpoint<List<String>> {
public String getId() {
return "customEndpoint";
}
public boolean isEnabled() {
return true;
}
public boolean isSensitive() {
return false;
}
public List<String> invoke() {
// Custom logic to build the output
...
}
}
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="true">
...
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>false</param-value>
</context-param>
...
</web-app>
__Host-
or __Secure-
prefix must have the Secure attribute set, must not set Domain attribute, and must restrict Path attribute value to /
.__Host-
and __Secure-
prefix must be set with the secure attribute. They must be set from a secure page (HTTPS). Additionally, a __Host-
prefixed cookie must not have a domain attribute specified (so that it is not sent to subdomains) and the path attribute must be set to /
. Violation of these rules can cause a browser to reject the cookie. Restricting a cookie's access to a secure channel protects it from being sent or being overwritten by a forged site over an unencrypted HTTP channel. Restrictions provided by the __Host
prefix prevent a cookie from being accessed by a subdomain where the subdomain might be owned by different entities such as a shared blog platform.spring-boot-devtools
on a remote application is a security risk. You should never enable support on a production deployment."
endpoints.shutdown.enabled=true
spring.application.admin.enabled
property. This exposes the SpringApplicationAdminMXBean
on the platform MBeanServer
. Developers could use this feature to administer the Spring Boot application remotely, however this feature exposes an additional attack surface in the form of a remote JMX endpoint. Depending on the configuration of the MBeanServer
the MBean
can be exposed locally or remotely, and may or may not require authentication. In the worst case, attackers will be able to manage the application remotely, including shutting it down without any authentication. In the best case, the service will be as strong as the credentials used to protect the server.HttpOnly
property to true
for CSRF cookies.HttpOnly
cookie property that prevents client-side scripts from accessing the cookie. Cross-site scripting attacks often access cookies in an attempt to steal session identifiers or authentication tokens. Without HttpOnly
enabled, attackers have easier access to user cookies.withHttpOnlyFalse()
method of the Spring framework's CookieCsrfTokenRepository class, a CSRF cookie is generated without setting the HttpOnly
property.
...
CookieCsrfTokenRepository c = CookieCsrfTokenRepository.withHttpOnlyFalse();
...
HttpOnly
flag to true
for CSRF cookies.HttpOnly
cookie property that prevents client-side scripts from accessing the cookie. Cross-site scripting attacks often access cookies in an attempt to steal session identifiers or authentication tokens. Without HttpOnly
enabled, attackers have easier access to user cookies.django.middleware.csrf.CsrfViewMiddleware
Django middleware, CSRF cookies are sent without setting the HttpOnly
property.
...
MIDDLEWARE = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'csp.middleware.CSPMiddleware',
'django.middleware.security.SecurityMiddleware',
...
)
...
Secure
flag to true
for CSRF cookies.Secure
flag for each cookie. If the flag is set, the browser will only send the cookie over HTTPS. Sending cookies over an unencrypted channel can expose them to network sniffing attacks, so the secure flag helps keep a cookie's value confidential. This is especially important if the cookie contains private data, session identifiers, or carries a CSRF token.Secure
flag for CSRF cookies, with the Spring framework.
...
CookieCsrfTokenRepository c = new CookieCsrfTokenRepository();
...
Secure
flag, cookies sent during an HTTPS request will also be sent during subsequent HTTP requests. Attackers can then compromise the cookie by sniffing the unencrypted network traffic, which is particularly easy over wireless networks.CSRF_COOKIE_SECURE
property to True
or set it to False
.Secure
flag for each cookie. If the flag is set, the browser will only send the cookie over HTTPS. Sending cookies over an unencrypted channel can expose them to network sniffing attacks, so the secure flag helps keep a cookie's value confidential. This is especially important if the cookie contains private data, session identifiers, or carries a CSRF token.Secure
bit for CSRF cookies.
...
MIDDLEWARE = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'csp.middleware.CSPMiddleware',
'django.middleware.security.SecurityMiddleware',
...
)
...
Secure
flag, cookies sent during an HTTPS request will also be sent during subsequent HTTP requests. Attackers can then compromise the cookie by sniffing the unencrypted network traffic, which is particularly easy over wireless networks.Example 2: The application uses unvalidated data controlled by the user in a Spring tag that perfoms double SpEL evaluation:
String expression = request.getParameter("input");
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw(expression);
<spring:message text="" code="${param['message']}"></spring:message>
@SessionAttributes
will mean Spring replicates changes to model attributes in the session object. If an attacker is able to store arbitrary values within a model attribute, these changes will be replicated in the session object where they may be trusted by the application. If the session attribute is initialized with trusted data which the user should not be able to modify, the attacker may be able to conduct a Session Puzzling attack and abuse the application logic.
@Controller
@SessionAttributes("user")
public class HomeController {
...
@RequestMapping(value= "/auth", method=RequestMethod.POST)
public String authHandler(@RequestParam String username, @RequestParam String password, RedirectAttributes attributes, Model model) {
User user = userService.findByNamePassword(username, password);
if (user == null) {
// Handle error
...
} else {
// Handle success
attributes.addFlashAttribute("user", user);
return "redirect:home";
}
}
...
}
User
instance from the session since the class is annotated with @SessionAttributes("user")
and uses it to verify the reset password question.
@Controller
@SessionAttributes("user")
public class ResetPasswordController {
@RequestMapping(value = "/resetQuestion", method = RequestMethod.POST)
public String resetQuestionHandler(@RequestParam String answerReset, SessionStatus status, User user, Model model) {
if (!user.getAnswer().equals(answerReset)) {
// Handle error
...
} else {
// Handle success
...
}
}
}
user
instance from the session where it was stored during the login process. However Spring will check the request and will try to bind its data into the model user
instance. If the received request contains data that can be bound to the User
class, Spring will merge the received data into the user session attribute. This scenario can be abused by submitting both an arbitrary answer in the answerReset
query parameter and the same value to override the value stored in the session. This way, the attacker may set an arbitrary new password for random users.
...
String returnURL = request.getParameter("returnURL");
return new ModelAndView(returnURL);
...
script-src
, img-src
, object-src
, style_src
, font-src
, media-src
, frame-src
, connect-src
.*
to indicate all or part of the source. None of the directives are mandatory. Browsers will either allow all sources for an unlisted directive or will derive its value from the optional default-src
directive. Furthermore, the specification for this header has evolved over time. It was implemented as X-Content-Security-Policy
in Firefox until version 23 and in IE until version 10, and was implemented as X-Webkit-CSP
in Chrome until version 25. Both of the names are deprecated in favor of the now standard name Content Security Policy
. Given the number of directives, two deprecated alternate names, and the way multiple occurrences of the same header and repeated directives in a single header are treated, there is a high probability that a developer might misconfigure this header.unsafe-inline
or unsafe-eval
defeats the purpose of CSP.script-src
directive is set but no script nonce
is configured.frame-src
is set but no sandbox
is configured.django-csp
configuration uses unsafe-inline
and unsafe-eval
insecure directives to allow inline scripts and code evaluation:
...
MIDDLEWARE = (
...
'csp.middleware.CSPMiddleware',
...
)
...
CSP_DEFAULT_SRC = ("'self'", "'unsafe-inline'", "'unsafe-eval'", 'cdn.example.net')
...
script-src
img-src
object-src
style_src
font-src
media-src
frame-src
connect-src
default-src
directive. Furthermore, the specification for this header has evolved over time. It was implemented as X-Content-Security-Policy
in Firefox until version 23, in Internet Explorer until version 10, and was implemented as X-Webkit-CSP
in Chrome until version 25. Both of the names are deprecated in favor of the now standard name Content Security Policy. Given the umber of directives, two deprecated alternate names, and the way multiple occurrences of the same header and repeat directives in a single header are treated, there is a high probability that a developer might misconfigure this header.
String beans = getBeanDefinitionFromUser();
GenericApplicationContext ctx = new GenericApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
xmlReader.loadBeanDefinitions(new UrlResource(beans));
ctx.refresh();
/
"). This exposes the cookie to all web applications on the domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum. For example:
...
String path = '/';
Cookie cookie = new Cookie('sessionID', sessionID, path, maxAge, true, 'Strict');
...
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a user of the forum clicks this link, the browser will send the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
./
", however, doing so exposes the cookie to all web applications on the same domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum.
HttpCookie cookie = new HttpCookie("sessionID", sessionID);
cookie.Path = "/";
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a user of the forum clicks this link, the browser will send the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
./
"). This exposes the cookie to all web applications on the domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum.
cookie := http.Cookie{
Name: "sessionID",
Value: sID,
Expires: time.Now().AddDate(0, 0, 1),
Path: "/",
}
...
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a forum user clicks this link, the browser sends the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
./
"). This exposes the cookie to all web applications on the domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum.
Cookie cookie = new Cookie("sessionID", sessionID);
cookie.setPath("/");
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a user of the forum clicks this link, the browser will send the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
./
"). This exposes the cookie to all web applications on the domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum.
cookie_options = {};
cookie_options.path = '/';
...
res.cookie('important_cookie', info, cookie_options);
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a user of the forum clicks this link, the browser will send the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
./
"). This exposes the cookie to all web applications on the domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum.
...
NSDictionary *cookieProperties = [NSDictionary dictionary];
...
[cookieProperties setValue:@"/" forKey:NSHTTPCookiePath];
...
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
...
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a user of the forum clicks this link, the browser will send the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
./
"). This exposes the cookie to all web applications on the domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum.
setcookie("mySessionId", getSessionID(), 0, "/", "communitypages.example.com", true, true);
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a user of the forum clicks this link, the browser will send the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
./
"). This exposes the cookie to all web applications on the domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum.
from django.http.response import HttpResponse
...
def view_method(request):
res = HttpResponse()
res.set_cookie("sessionid", value) # Path defaults to "/"
return res
...
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a user of the forum clicks this link, the browser will send the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
./
"). This exposes the cookie to all web applications on the domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum.
Ok(Html(command)).withCookies(Cookie("sessionID", sessionID, path = "/"))
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a user of the forum clicks this link, the browser will send the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
./
"). This exposes the cookie to all web applications on the domain. Because cookies often carry sensitive information such as session identifiers, sharing cookies across applications can cause a vulnerability in one application to compromise another application.http://communitypages.example.com/MyForum
and the application sets a session ID cookie with the path "/
" when users log in to the forum.
...
let properties = [
NSHTTPCookieDomain: "www.example.com",
NSHTTPCookiePath: "/",
NSHTTPCookieName: "foo",
NSHTTPCookieValue: "bar",
NSHTTPCookieSecure: true
]
let cookie : NSHTTPCookie? = NSHTTPCookie(properties:properties)
...
http://communitypages.example.com/EvilSite
and posts a link to this site on the forum. When a user of the forum clicks this link, the browser will send the cookie set by /MyForum
to the application running at /EvilSite
. By stealing the session ID, the attacker can compromise the account of any forum user that browsed to /EvilSite
./EvilSite
to create its own overly broad cookie that overwrites the cookie from /MyForum
.HttpOnly
flag to true
.HttpOnly
cookie property to prevent client-side scripts from accessing the cookie. Cross-site scripting attacks often access cookies in an attempt to steal session identifiers or authentication tokens. Without the HttpOnly
flag enabled, attackers have easier access to user cookies.HttpOnly
property.
HttpCookie cookie = new HttpCookie("emailCookie", email);
Response.AppendCookie(cookie);
HttpOnly
flag to true
.HttpOnly
cookie property that prevents client-side scripts from accessing the cookie. Cross-site scripting attacks often access cookies in an attempt to steal session identifiers or authentication tokens. Without HttpOnly
enabled, attackers have easier access to user cookies.HttpOnly
property.
cookie := http.Cookie{
Name: "emailCookie",
Value: email,
}
...
HttpOnly
flag to true
.HttpOnly
cookie property to prevent client-side scripts from accessing the cookie. Cross-site scripting attacks often access cookies in an attempt to steal session identifiers or authentication tokens. Without the HttpOnly
flag enabled, attackers have easier access to user cookies.HttpOnly
property.
javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie("emailCookie", email);
// Missing a call to: cookie.setHttpOnly(true);
HttpOnly
flag to true
.HttpOnly
cookie property to prevent client-side scripts from accessing the cookie. Cross-site scripting attacks often access cookies in an attempt to steal session identifiers or authentication tokens. Without the HttpOnly
flag enabled, attackers have easier access to user cookies.httpOnly
property.
res.cookie('important_cookie', info, {domain: 'secure.example.com', path: '/admin'});
HttpOnly
flag to true
.HttpOnly
cookie property to prevent client-side scripts from accessing the cookie. Cross-site scripting attacks often access cookies in an attempt to steal session identifiers or authentication tokens. Without the HttpOnly
flag enabled, attackers have easier access to user cookies.HttpOnly
property.
setcookie("emailCookie", $email, 0, "/", "www.example.com", TRUE); //Missing 7th parameter to set HttpOnly
HttpOnly
flag to True
.HttpOnly
cookie property that prevents client-side scripts from accessing the cookie. Cross-site scripting attacks often access cookies in an attempt to steal session identifiers or authentication tokens. Without HttpOnly
enabled, attackers have easier access to user cookies.HttpOnly
property.
from django.http.response import HttpResponse
...
def view_method(request):
res = HttpResponse()
res.set_cookie("emailCookie", email)
return res
...
HttpOnly
flag to true
.HttpOnly
cookie property to prevent client-side scripts from accessing the cookie. Cross-site scripting attacks often access cookies in an attempt to steal session identifiers or authentication tokens. Without the HttpOnly
flag enabled, attackers have easier access to user cookies.HttpOnly
property.
Ok(Html(command)).withCookies(Cookie("sessionID", sessionID, httpOnly = false))