I want to secure my Task Queue URLs against malicious access.
In the views that the Task Queue requests I've got:
if not users.is_current_user_admin():
return HttpResponse(status=403)
But my Task Queues are receiving 403 errors! I was under the impression from this GAE documentation that the Task Queue user was gauranteed to be an admin. What gives?
NOTE: I'm using DjangoNonRel so I can't specify the admin only url access in my app.yaml, I have to do it programmatically in the views.
Tasks can bypass login: admin restrictions, however users.is_current_user_admin() will still return false, as there is technically no current user.
Using Django-nonrel shouldn't stop you from protecting your tasks with app.yaml. Just add a protected handler above your Django catch-all:
handlers:
- url: /tasks/.+
script: main.py
login: admin
- url: .*
script: main.py
Any URLs that start with /tasks/ will be accessible to the task queue and inaccessible to non-admin visitors, without changing how anything routes.
Your handlers can look for a task queue HTTP header, such as X-AppEngine-QueueName.
From official GAE docs :
Requests from the Task Queue service contain the following HTTP headers:
X-AppEngine-QueueName
X-AppEngine-TaskName
X-AppEngine-TaskRetryCount
X-AppEngine-TaskExecutionCount
X-AppEngine-TaskETA
These headers are set internally by Google App Engine. If your
request handler finds any of these headers, it can trust that the
request is a Task Queue request. If any of the above headers are
present in an external user request to your app, they are stripped.
You can accomplish this by doing 2 checks
Check remote address, it will be 0.1.0.1
Check for existence of header [X-Appengine-Cron].
This will secure you Task Queue URLs (this is only applicable for Pull Queues as per my knowledge).
I wrote a decorator which does this checks for me.Hope this was helpful
For more info, Please refer Docs
Related
Frankly speaking azure still does not have direct way to set up alerts on continuous web job's so that one can get notification if web job stops for unknown reasons. After some investigation i found that logic apps are best way to do that. Here are the steps how one can achieve this
Go to azure web job, select properties and copy web hook url, username and password.
By default web hook url will have /run option at end to so remove that as you dont want to run webjob
Create a logic app setting following parameters in exact order
Recurrence - Your choice how frequently you want to run your logic
app
Initialize a variable for example status (type - string)
Call Http end point giving following details which you copied
earlier []2]
Add a step of parse
JSON response, pasting response so that logic app can create its own
schema
Pick the item name for
value you want to read for example i am using status
Add a condition for failure
Send the mail or whatever you want to do
Over all your Login app will look something like this
This is helpful, indeed. But I was facing issue with the web hook url authentication. The logic app connector was returning 401 – Unauthorized for the http request, as the password was encoded. Took a while to understand why it is throwing unauthorized even after providing correct credentials. Hence, copying the original password helped in that case ( if not anything else).
Suddenly, as of this morning, our Django log does not display the logging from some requests, even though it appears that all requests are being serviced. Some requests display their logging in the log, others don't, but no one has changed anything. (I am the only person that has access to change anything). Does anyone know of a reason this could occur?
Thanks.
This turns out to not be a Django issue at all. Unbeknownst to us, our web hosting provider adjusted an Apache policy regarding caching. Our iOS app now needs to specifically specify its cache policy in the HTTP header, or provide a unique URL parameter for the request, or Apache serves up stale responses. (The requests were not even reaching Django).
I'm struggling to understand how flask_login or django knows when a user logs in that they retain access?
If I were to use ReactJs or Angular with flask-restful or django/tastypie, what is being added to the header/body of future json requests to ensure that my user stays logged in?
This is done via sessions, which is based on cookies. From the Flask documentation:
In addition to the request object there is also a second object called session which allows you to store information specific to a user from one request to the next. This is implemented on top of cookies for you and signs the cookies cryptographically.
and the Django docs:
Django provides full support for anonymous sessions. The session framework lets you store and retrieve arbitrary data on a per-site-visitor basis. It stores data on the server side and abstracts the sending and receiving of cookies. Cookies contain a session ID – not the data itself (unless you’re using the cookie based backend).
So, the requests to the server automatically include a cookie that indicates some ID that the server then uses to figure out what the session data should be for the given user. In general, when Ajax requests are made from client-side applications to the server, this cookie is included and so ensures that the user is considered to be logged in for those requests.
In some cases, you can also (optionally) manually add a special header to HTTP requests to indicate which user is logged in.
See also Securing RESTapi in flask for some more information.
If you use REST service then you should take a look at oAuth. In other words it uses token which you attach to every request from client to server and the last can determine which user sent this request by this token.
On the other hand, you can use cookie or session to determine a user status. And in this case you don't need to add any headers to your request.
Also I recommend you this package for Django - Django Rest Framework (there you can read more about token and auth via REST) and this extension for Flask.
I have created a REST web service using Django. This web service has a log file. I'd like to log all web service (http) requests in the log file. However, the web service request handling is done by Django, I only setup url-request handlers mapping and create the request handlers (views in Django nomenclature). Is there a way to log all requests in a central point, without needing to log each request in its associated request handler (view)?
Thanks in advance.
Yes Django has a built in signals framework.
It allows you to register a function to be called everytime a request starts.
This documenation page explains how to do it step by step
Using the decorator method:
from django.core.signals import request_started
from django.dispatch import receiver
#receiver(request_started)
def my_callback(sender, **kwargs):
# log the request here
pass
Where should this code live? You can put signal handling and
registration code anywhere you like. However, you’ll need to make sure
that the module it’s in gets imported early on so that the signal
handling gets registered before any signals need to be sent. This
makes your app’s models.py a good place to put registration of signal
handlers.
In my development enviroment (localhost of course).
Based on this documentation I've sucessfully created a apps token with this:
https://graph.facebook.com/oauth/access_token?client_id=<app-id>&client_secret=<app-secret>&grant_type=client_credentials
then make post request to verify my callback_url to FB graph, like this
https://graph.facebook.com/<app-id>/subscriptions?access_token=my_apps_access_token=user&fields=first_name&callback_url=http://localhost:3000&verify_token=mystringtoken
but it's always return :
{"error":{"message":"(#2200) callback verification failed: ","type":"OAuthException"}}
(I've try using lvh.me:3000)
Is there possible to verify the callback_url using localhost?
From the API documentation:
Your callback server must handle two types of requests.
Facebook servers will make a single HTTP GET to your callback URL when you try to add or modify a subscription. After a successful subscription, Facebook servers will notify your server of changes by issuing HTTP POST requests to the same URL.
From this statement, I would presume that you must provide a publicly accessible URL.
Here is How to . I've explained the proccess.