Weblog

published Nov 03, 2021, last modified Nov 04, 2021

Armin Ronacher: SSL, CAs and keeping your stuff safe

published May 09, 2014

Armin Ronacher talks about SSL, CAs and keeping your stuff safe, at PyGrunn.

See the PyGrunn website for more info about this one-day Python conference in Groningen, The Netherlands.

The title really should have been: a capitalistic and system conformant talk about encryption, but okay, let's talk about SSL.

The problem with programmers is that they think everything is a technical problem.

Let's talk about fraud. What makes credit card numbers secure? Nothing. They are just 16 digits. Some consider it safe to trust you when you know the last four digits.

We accept stolen credit cards. So the protocol is insecure. It is too easy to forget the bigger picture: the process itself is secure.

The 'lock' symbol stands for 'secure'. But you can use that symbol anywhere: it does not prove anything.

'It has encryption, so it is secure?' No, the used encryption system can be very insecure.

Remember why you encrypt. Do you really need SSL on your weblog?

Why do we encrypt traffic? Before Starbucks there was basically no public wifi. They made it possible for agents to attack idiots.

Encryption gives you protection against passive eavesdropping. For active eavesdropping, you need authentication, so people cannot impersonate you or the one you talk too.

Your user does not check fingerprints. Your user just thinks a lock symbol means it is secure.

Enter the Certificate Authorities (CAs). It is a distribution of the trust problem: you trust your browser, they trust certificate authorities, they trust their clients.

Let it be known that CAs are worthless for securing APIs.

Protecting APIs (non javascript) and servers:

  • run your own CA
  • issue certificates for 24 hours
  • trust your own CA only
  • screw revocations

You trust your own CA by distributing its certificate to everybody.

from requests import get
resp = get('https://api.yourserver.com/',
           verify='your/certificate.bundle')

"But my awesome AntiVirus syas your certificate is not trusted." -- a Windows user.

Revocations do not work in practice.

One shitty employee in one shitty CA is enough to break your security. (Crowd: this actually happened in the Netherlands with Diginotar.)

Soon: Certificate pinning? Changes are happening. Ideas are floating about.

Frack OpenSSL and question 'Best practices'. Not enough people have looked at the OpenSSL code. There is not enough knowledge among developers. Never, ever look at the source code of openssl; wrong defaults, patches. Apple's 'patches' are even worse.

Plan for failure. Plan for things going wrong. What happens when your user gets hacked? Food for thought: keyloggers are still a thing. What happens to your data? What happens to your company?

Security should not be your only defense.

@mitsuhiko at Twitter.

Erik Romijn: Keeping Django chained; seven top security concerns for Django websites

published May 09, 2014

Erik Romijn talks about keeping Django chained (seven top security concerns for Django websites), at PyGrunn.

See the PyGrunn website for more info about this one-day Python conference in Groningen, The Netherlands.

This is not only for Django sites, but may apply to other websites as well.

I have created http://ponycheckup.com and https://www.securedjango.com

1. Improper deployment of HTTPS.

Or: not deploying it at all. Always use https if you have anything non-public. So: anything that requires a login.

Why? Encryption of traffic. Verification of server identity and authenticity of data: nice that no one can listen in on your password, but if you send it securely to an identity thief, it is still not very secure.

  • Enable HTTPS with a proper certificate. It need not be expensive, but do not let your users click to accept your certificate: they will just always click to accept it anyway, which is bad.
  • Enforce HTTPS on your entire domain: never deploy it partially.
  • Configure redirects and HSTS to enforce HTTPS usage. HSTS is a signal to your browser that it may never connect to a certain page via plain HTTP.
  • Set the secure flag on all cookies.
  • Configure proper ciphers: https://www.ssllabs.com/ssltest/

2. Failure to authorize users

Nice that a user is logged in, but is she allowed to view and do everything? Probably not.

You can filter on owner for some tables:

queryset.filter(owner=self.request.user)

You may generalize this into mixins and decorators, but you should keep them transparent and simple.

Distrust yourself: add tests for this. Do not only test that things work as they should, but also that they break as they should.

4. SQL injection with Django

It is not needed, but if you really want to, usually for speed reasons, you can use raw SQL queries in Django.

There are safe ways of using execute on a cursor.

Be very careful.

6. Media access

The way we use use uploaded media. If you put uploaded files in a directory and allow access to it, someone may guess a filename and have access to something they should not know about.

You can use django-random-filestorage to mitigate this.

7. Outdated Django versions

I can understand that you are one major version behind, but please keep up to date on the latest minor releases. It is seldom that a security fix has unwanted side effects.

@erikpub at Twitter.

Saúl Ibarra Corretgé: asyncio internals

published May 09, 2014

Saúl Ibarra Corretgé talks about asyncio internals, at PyGrunn.

See the PyGrunn website for more info about this one-day Python conference in Groningen, The Netherlands.

See the first talk introducing asyncio.

In asyncio there is no event class, no abstraction of what an event is. It runs callbacks which are put in a queue.

[Note: I am not going to type over the code examples, too easy to make typos.]

I/O handling APIs are in readyness style (tell us when you can start) or completion style (tell us when you are done). On Windows there are limits, so you may need to do it differently.

Polling: calculate a timeout, block for I/O, process I/O events (schedule callbacks), process timers (schedule callbacks), run pending callbacks.

Coroutines are generator functions, can also receive values. With the @asyncio.coroutine decorator I know I can use yield from on that function.

Futures represent a value which is not there yet. yield from can be used to wait for it. asyncio.wrap_future can be used to wrap a PEP-3148 Future into one of these.

f = Future()
f.set_result(...)  # or f.set_exception
yield from f  # wait until the result arrives

A Task is a unit on concurrent asynchronous work. It is actually a coroutine wrapped in a Future. It schedules callbacks using loop.call_soon. Use asyncio.async to turn a coroutine into a task.

Go read PEP-3156. Don't be afraid of looking under the hood in the source code.

@saghul on Twitter.

Artur Barseghyan: Modern authentication in Python web applications

published May 09, 2014

Artur Barseghyan talks about Modern authentication in Python web applications, at PyGrunn.

See the PyGrunn website for more info about this one-day Python conference in Groningen, The Netherlands.

Part 1: Single Sign-on (SSO) using a Central Authentication Service (CAS).

Without SSO you need to login manually to lots more websites or apps, or put everything in one website/app. Or you can create a custom API to share authentication information.

With SSO a user logs in once and gains access to all systems without begin prompted to log in again.

(JaSig) CAS is an enterprise SSO solution. Open source, well documented. Web browser talks to application server, app server talks to CAS, web browser authenticates with CAS once, CAS gives the app a ticket showing that the web browser is authenticated.

See http://jasig.org/cas

Pro: CAS is modular, highly pluggable, so it is fit for lots of frameworks.

Contra: SSO availability and security become critical. You should subscribe to the CAS mailing list to keep on top of issues. Setup notifications for when your CAS server runs into problems.

Our use case:

  • User base in an Active Directory server
  • CAS server
  • Two apps/websites:
    • Dashboard app in Django
    • Document management system in Plone
    • More to come

CAS alternatives: JOSSO, OpenAM, Pubcookie, CoSign.

Part 2: Two-step verification

Or: two-factor authentication. Can be based on:

  • knowledge factor, something only you know
  • possession factor, something only you possess
  • inheritance factor, something only you have, like fingerprints

Common solutions:

  • SMS authentication. You need to pay for each SMS, so it can become expensive. Phone might not be connected.
  • Google Authenticator (for mobile apps). Very easy to integrate in your app. Requires an extra app to be installed on your device.
  • Hardware token generators. Easy to use. But extra device to carry with you.

Software we made for Plone:

Similar software is available for Django.

Alternatives:

  • risk-based authentication, based on behavioral biometrics, keystroke dynamics, etc
  • strong authentication
  • reliance authentication

Rodrigo Bernardo Pimentel: A first look at asyncio

published May 09, 2014

Rodrigo Bernardo Pimentel gives us a first look at asyncio, at PyGrunn.

See the PyGrunn website for more info about this one-day Python conference in Groningen, The Netherlands.

Rodrigo is backend developer and team lead at Layar. That is an app that for example pops up a video when you point it at a certain page in a magazine.

asyncio was introduced about two months ago in Python 3.4. Also available on PyPI for 3.3, which is the bare minimum, because it uses yield from.

At Layar we already use some form of asynchronous IO. We have about 175k scans per day, so images that people scanned with their app. 85k publishers. We use Twisted, and some Tornado, on Python 2.7. We have been looking for excuses to start using Python 3.

asyncio is PEP-3156. It replaces asyncore. It is not meant to replace Twisted or Tornado, it just takes some experience from those packages.

asyncio has:

  • coroutines, futures and tasks
  • event loop
  • transport, protocols

Coroutines replace callbacks. Give a task and a callback to call when the task is finished.

Futures are objects that will eventually have a result. You can yield from futures.

Tasks are a subclass of Future. It is a coroutine wrapped in a Future. As soon as you create the tasks, it starts running until it comes to a point where it has to wait. It does not wait for you to call .next() on the code that uses the task.

Event loop: it is Twisted-like. You can use it to call a function soon, later, or at a specific time. A loop can run forever or run until a certain task is completed.

Transports represent a connection. Typically implemented by a framework.

Protocols represent an application. Typically implemented by you.

See the slides of this talk. @rbp on Twitter.