your_search_query = 'super very news'
qset = Q()
for term in your_search_query.split():
qset |= Q(name__contains=term)
matching_results = YourModel.objects.filter(qset)
Django Questions and Answers?
Monday 5 September 2016
Searching Easy way in Django
Sunday 4 September 2016
What is Signals in Djaango?
What are Django signals?
Signals allow certain senders to notify a set of receivers that some action has taken place
Signals allow certain senders to notify a set of receivers that some action has taken place
Actions :
model's save() method is called.
django.db.models.signals.pre_save | post_save
django.db.models.signals.pre_save | post_save
model's delete() method is called.
django.db.models.signals.pre_delete | post_delete
django.db.models.signals.pre_delete | post_delete
ManyToManyField on a model is changed.
django.db.models.signals.m2m_changed
django.db.models.signals.m2m_changed
Django starts or finishes an HTTP request.
django.core.signals.request_started | request_finished
django.core.signals.request_started | request_finished
All signals are django.dispatch.Signal instances.
very basic example :
models.py
from django.db import models
from django.db.models import signals
def create_customer(sender, instance, created, **kwargs):
print "Save is called"
class Customer(models.Model):
name = models.CharField(max_length=16)
description = models.CharField(max_length=32)
signals.post_save.connect(create_customer, sender=Customer)
Shell
In [1]: obj = Customer(name='foo', description='foo in detail')
In [2]: obj.save()
Save is called
Decorater ?
Using decorators to wrap and modify Django views is quick, easy, composable, and just about the most awesome thing I’ve seen in a while. It also takes a little bit of figuring out. Here’s my explanation…
More than just decoration
Using a decorator looks (in Python) like this:
@a_decorator
def a_function(an_arg):
return "Functionate: %s!" % (an_arg)
Where
a_decorator
is some function or other which takes an argument (a_function
, in this particular case) and returns a value. When Python loads a module containing this code it creates a new function a_function
as normal, but then it calls a_decorator
on it and binds the value it returns to the name a_function
rather than the original function created from the definition. So how do we write these decorators? Just like a normal function!def a_decorator(the_func):
"""
Make another a function more beautiful.
"""
def _decorated(*args, **kwargs):
return the_func(*args, **kwargs)
return _decorated
But what about parameterised decorators? It’s just a little more involved. Recall that you use a decorator like this:
@the_decorator
. It turns out that such decorator statements don’t just name a decorator to be called, but can also call a function to return a decorator to be called:def wrap_in_a(tag):
"""
Wrap the result of a function in a `tag` HTML tag.
"""
def _dec(func):
def _new_func(*args, **kwargs):
return "<%s>%s</%s>" % (tag, func(*args, **kwargs), tag)
return _new_func
return _dec
@wrap_in_a('div')
@login_required
def my_name(request):
return request.user.first_name
The first decorator statement
@wrap_in_a('div')
calls wrap_in_a('div')
which returns a function (_dec
). This function is then applied to the following definition (@login_required
applied to my_name
). Simple!
It’s probably a good idea to add a few more bits and pieces to the function returned by a decorator (copying
__doc__
and __dict__
, for instance), but that’s the core of it.Using it in Django
So this is all pretty cool, but how do we use it in Django? We’ll here’s a
anonymous_required
decorator that you can use to redirect authenticated users to their home page if they try to login again:def anonymous_required(function=None, home_url=None, redirect_field_name=None):
"""Check that the user is NOT logged in.
This decorator ensures that the view functions it is called on can be
accessed only by anonymous users. When an authenticated user accesses
such a protected view, they are redirected to the address specified in
the field named in `next_field` or, lacking such a value, the URL in
`home_url`, or the `USER_HOME_URL` setting.
"""
if home_url is None:
home_url = settings.USER_HOME_URL
def _dec(view_func):
def _view(request, *args, **kwargs):
if request.user.is_authenticated():
url = None
if redirect_field_name and redirect_field_name in request.REQUEST:
url = request.REQUEST[redirect_field_name]
if not url:
url = home_url
if not url:
url = "/"
return HttpResponseRedirect(url)
else:
return view_func(request, *args, **kwargs)
_view.__name__ = view_func.__name__
_view.__dict__ = view_func.__dict__
_view.__doc__ = view_func.__doc__
return _view
if function is None:
return _dec
else:
return _dec(function)
It’s probably not very Django-ish, but you get the impression. Just use it like Django’s built-in
login_required
decorator:@anonynous_required
def a_view(request):
return HttpResponse("We are anonymous! We are legion!")
Comments and suggestions welcome!
Update: Amended the example decorator above to work correctly as
@anonymous_required
, @anonymous_required(...)
or foo = anonymous_required(foo)
.What is a CSRF token ? What is its importance and how does it work?
Detailed Info
- Assume you are currently logged into your online banking at
www.mybank.com
- Assume a money transfer from
mybank.com
will result in a request of (conceptually) the formhttp://www.mybank.com/transfer?to=<SomeAccountnumber>;amount=<SomeAmount>
. (Your account number is not needed, because it is implied by your login.) - You visit
www.cute-cat-pictures.org
, not knowing that it is a malicious site. - If the owner of that site knows the form of the above request (easy!) and correctly guesses you are logged into
mybank.com
(requires some luck!), they could include on their page a request likehttp://www.mybank.com/transfer?to=123456;amount=10000
(where123456
is the number of their Cayman Islands account and10000
is an amount that you previously thought you were glad to possess). - You retrieved that
www.cute-cat-pictures.org
page, so your browser will make that request. - There is no way how your bank could recognize that the request was not made by you: Your web browser will send the request along with your
www.mybank.com
cookie and it will look perfectly legitimate. There goes your money!
This is the world without CSRF tokens.
Now for the better one with CSRF tokens:
- The transfer request is extended with a third argument:
http://www.mybank.com/transfer?to=123456;amount=10000;token=31415926535897932384626433832795028841971
. - That token is a huge, impossible-to-guess random number that
mybank.com
will include on their own web page when they serve it to you. It is different each time they serve any page to anybody. - The attacker is not able to guess the token, is not able to convince your web browser to surrender it (if the browser works correctly...), and so the attacker will not be able to create a valid request, because requests with the wrong token (or no token) will be refused by
www.mybank.com
.
Assume that your bank's website provides a form that allows transferring money from the currently logged in user to another bank account. For example, the HTTP request might look like:
POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly
Content-Type: application/x-www-form-urlencoded
amount=100.00&routingNumber=1234&account=9876
Now pretend you authenticate to your bank's website and then, without logging out, visit an evil website. The evil website contains an HTML page with the following form:
<form action="https://bank.example.com/transfer" method="post">
<input type="hidden"
name="amount"
value="100.00"/>
<input type="hidden"
name="routingNumber"
value="evilsRoutingNumber"/>
<input type="hidden"
name="account"
value="evilsAccountNumber"/>
<input type="submit"
value="Win Money!"/>
</form>
You like to win money, so you click on the submit button. In the process, you have unintentionally transferred $100 to a malicious user. This happens because, while the evil website cannot see your cookies, the cookies associated with your bank are still sent along with the request.
Worst yet, this whole process could have been automated using JavaScript. This means you didn't even need to click on the button. So how do we protect ourselves from such attacks?
The issue is that the HTTP request from the bank's website and the request from the evil website are exactly the same. This means there is no way to reject requests coming from the evil website and allow requests coming from the bank's website. To protect against CSRF attacks we need to ensure there is something in the request that the evil site is unable to provide.
One solution is to use the Synchronizer Token Pattern. This solution is to ensure that each request requires, in addition to our session cookie, a randomly generated token as an HTTP parameter. When a request is submitted, the server must look up the expected value for the parameter and compare it against the actual value in the request. If the values do not match, the request should fail.
We can relax the expectations to only require the token for each HTTP request that updates state. This can be safely done since the same origin policy ensures the evil site cannot read the response. Additionally, we do not want to include the random token in HTTP GET as this can cause the tokens to be leaked.
Let's take a look at how our example would change. Assume the randomly generated token is present in an HTTP parameter named _csrf. For example, the request to transfer money would look like this:
POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly
Content-Type: application/x-www-form-urlencoded
amount=100.00&routingNumber=1234&account=9876&_csrf=<secure-random>
You will notice that we added the _csrf parameter with a random value. Now the evil website will not be able to guess the correct value for the _csrf parameter (which must be explicitly provided on the evil website) and the transfer will fail when the server compares the actual token to the expected token.
When you use CSRF protection? Our recommendation is to use CSRF protection for any request that could be processed by a browser by normal users. If you are only creating a service that is used by non-browser clients, you will likely want to disable CSRF protection.
A common question is, but do I need to protect JSON requests made by javascript? The short answer is, it depends. However, you must be very careful as there are CSRF exploits that can impact JSON requests. For example, a malicious user can create a CSRF with JSON using the following form:
<form action="https://bank.example.com/transfer" method="post" enctype="text/plain">
<input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
<input type="submit"
value="Win Money!"/>
</form>
This will produce the following JSON structure
{ "amount":100,
"routingNumber": "evilsRoutingNumber",
"account": "evilsAccountNumber",
"ignore_me": "=test"
}
If an application were not validating the Content-Type, then it would be exposed to this exploit. Depending on the setup, a Spring MVC application that validates the Content-Type could still be exploited by updating the URL suffix to end with ".json" as shown below:
<form action="https://bank.example.com/transfer.json" method="post" enctype="text/plain">
<input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
<input type="submit"
value="Win Money!"/>
</form>
What if my application is stateless? That doesn't necessarily mean you are protected. In fact, if a user does not need to perform any actions in the web browser for a given request, they are likely still vulnerable to CSRF attacks.
For example, consider an application uses a custom cookie that contains all the state within it for authentication instead of the JSESSIONID. When the CSRF attack is made the custom cookie will be sent with the request in the same manner that the JSESSIONID cookie was sent in our previous example.
User's using basic authentication are also vulnerable to CSRF attacks since the browser will automatically include the username password in any requests in the same manner that the JSESSIONID cookie was sent in our previous example.
So what are the steps necessary to use Spring Security's to protect our site against CSRF attacks? The steps to using Spring Security's CSRF protection are outlined below:
The first step to protecting against CSRF attacks is to ensure your website uses proper HTTP verbs. Specifically, before Spring Security's CSRF support can be of use, you need to be certain that your application is using PATCH, POST, PUT, and/or DELETE for anything that modifies state.
This is not a limitation of Spring Security's support, but instead a general requirement for proper CSRF prevention. The reason is that including private information in an HTTP GET can cause the information to be leaked. See RFC 2616 Section 15.1.3 Encoding Sensitive Information in URI's for general guidance on using POST instead of GET for sensitive information.
The next step is to include Spring Security's CSRF protection within your application. Some frameworks handle invalid CSRF tokens by invaliding the user's session, but this causes its own problems. Instead by default Spring Security's CSRF protection will produce an HTTP 403 access denied. This can be customized by configuring theAccessDeniedHandler to process
InvalidCsrfTokenException
differently.
For passivity reasons, if you are using the XML configuration, CSRF protection must be explicitly enabled using the <csrf> element. Refer to the <csrf> element's documentation for additional customizations.
Note | |
---|---|
SEC-2347 is logged to ensure Spring Security 4.x's XML namespace configuration will enable CSRF protection by default.
|
<http>
<!-- ... -->
<csrf />
</http>
CSRF protection is enabled by default with Java configuration. If you would like to disable CSRF, the corresponding Java configuration can be seen below. Refer to the Javadoc of csrf() for additional customizations in how CSRF protection is configured.
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable();
}
}
The last step is to ensure that you include the CSRF token in all PATCH, POST, PUT, and DELETE methods. This can be done using the _csrf request attribute to obtain the current CsrfToken. An example of doing this with a JSP is shown below:
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}"
method="post">
<input type="submit"
value="Log out" />
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
</form>
Note | |
---|---|
If you are using Spring MVC <form:form> tag, the
CsrfToken is automatically included for you using the CsrfRequestDataValueProcessor. |
If you using JSON, then it is not possible to submit the CSRF token within an HTTP parameter. Instead you can submit the token within a HTTP header. A typical pattern would be to include the CSRF token within your meta tags. An example with a JSP is shown below:
<html>
<head>
<meta name="_csrf" content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>
<!-- ... -->
</head>
<!-- ... -->
You can then include the token within all your Ajax requests. If you were using jQuery, this could be done with the following:
$(function () {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
});
As a alternative to jQuery, we recommend using cujoJS’s rest.js. rest.js provides advanced support for working with HTTP request and responses in RESTful ways. A core capability is the ability to contextualize the HTTP client adding behavior as needed by chaining interceptors on to the client.
var client = rest.chain(csrf, {
token: $("meta[name='_csrf']").attr("content"),
name: $("meta[name='_csrf_header']").attr("content")
});
The configured client can be shared with any component of the application that needs to make a request to the CSRF protected resource. One significant different between rest.js and jQuery is that only requests made with the configured client will contain the CSRF token, vs jQuery where all requests will include the token. The ability to scope which requests receive the token helps guard against leaking the CSRF token to a third party. Please refer to the rest.js reference documentation for more information on rest.js.
There are a few caveats when implementing CSRF.
One issue is that the expected CSRF token is stored in the HttpSession, so as soon as the HttpSession expires your configured
AccessDeniedHandler
will receive a InvalidCsrfTokenException. If you are using the default AccessDeniedHandler
, the browser will get an HTTP 403 and display a poor error message.Note | |
---|---|
One might ask why the expected
CsrfToken isn't stored in a cookie. This is because there are known exploits in which headers (i.e. specify the cookies) can be set by another domain. This is the same reason Ruby on Rails no longer skips CSRF checks when the header X-Requested-With is present. See this webappsec.org thread for details on how to perform the exploit. Another disadvantage is that by removing the state (i.e. the timeout) you lose the ability to forcibly terminate the token if something got compromised. |
A simple way to mitigate an active user experiencing a timeout is to have some JavaScript that lets the user know their session is about to expire. The user can click a button to continue and refresh the session.
Alternatively, specifying a custom
AccessDeniedHandler
allows you to process the InvalidCsrfTokenException
anyway you like. For an example of how to customize the AccessDeniedHandler
refer to the provided links for both xml and Java configuration.
In order to protect against forging log in requests the log in form should be protected against CSRF attacks too. Since the
CsrfToken
is stored in HttpSession, this means an HttpSession will be created as soon as CsrfToken
token attribute is accessed. While this sounds bad in a RESTful / stateless architecture the reality is that state is necessary to implement practical security. Without state, we have nothing we can do if a token is compromised. Practically speaking, the CSRF token is quite small in size and should have a negligible impact on our architecture.
Adding CSRF will update the LogoutFilter to only use HTTP POST. This ensures that log out requires a CSRF token and that a malicious user cannot forcibly log out your users.
One approach is to use a form for log out. If you really want a link, you can use JavaScript to have the link perform a POST (i.e. maybe on a hidden form). For browsers with JavaScript that is disabled, you can optionally have the link take the user to a log out confirmation page that will perform the POST.
There are two options to using CSRF protection with multipart/form-data. Each option has its tradeoffs.
Note | |
---|---|
More information about using multipart forms with Spring can be found within the 17.10 Spring's multipart (file upload) support section of the Spring reference.
|
The first option is to ensure that the
MultipartFilter
is specified before the Spring Security filter. Specifying the MultipartFilter
after the Spring Security filter means that there is no authorization for invoking the MultipartFilter
which means anyone can place temporary files on your server. However, only authorized users will be able to submit a File that is processed by your application. In general, this is the recommended approach because the temporary file upload should have a negligble impact on most servers.
To ensure
MultipartFilter
is specified before the Spring Security filter with java configuration, users can override beforeSpringSecurityFilterChain as shown below:public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
}
To ensure
MultipartFilter
is specified before the Spring Security filter with XML configuration, users can ensure the <filter-mapping> element of theMultipartFilter
is placed before the springSecurityFilterChain within the web.xml as shown below:<filter>
<filter-name>MultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>MultipartFilter</filter-name>
<servlet-name>/*</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
If allowing unauthorized users to upload temporariy files is not acceptable, an alternative is to place the
MultipartFilter
after the Spring Security filter and include the CSRF as a query parameter in the action attribute of the form. An example with a jsp is shown below<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">
The disadvantage to this approach is that query parameters can be leaked. More genearlly, it is considered best practice to place sensitive data within the body or headers to ensure it is not leaked. Additional information can be found in RFC 2616 Section 15.1.3 Encoding Sensitive Information in URI's.
The HiddenHttpMethodFilter should be placed before the Spring Security filter. In general this is true, but it could have additional implications when protecting against CSRF attacks.
Note that the HiddenHttpMethodFilter only overrides the HTTP method on a POST, so this is actually unlikely to cause any real problems. However, it is still best practice to ensure it is placed before Spring Security's filters.
Subscribe to:
Posts (Atom)