Security Headers Project


#1

:wave: All, I would love any feedback on a lightweight security headers and cookie attribute project for Python :snake: web frameworks (including Sanic) called Secure :lock:. Secure lets developers easily set security headers and secure cookies with recommended values. The repo is:
https://github.com/cakinney/secure. :pray:


#2

Awesome. Thanks for sharing. I’ll take a closer look later. Just curious, how do you intend this to work with CORS?


#3

Adam, thanks for creating this awesome web framework :star_struck: - I actually started this project to learn more about Python web frameworks (I am in application security and this is my way of giving back) and Sanic is awesome! Thank you for checking out the project! I will caveat I am more security :skull: than developer - these headers should not affect existing CORS policies and I am going to be adding in other headers as needed/requested and can absolutely add in CORS support, especially if you see value in adding it to the project. :pray:


#4

For the record… I did not create Sanic. Just joined the team to help push the project forward. The creator is @channelcat. :wink:

There already is the sanic-cors package that is maintained by one of the other core devs (@ashleysommer) that has some good adoption in the community. I know you are going for a more framework independent approach (:clap: on that), but as far as Sanic is concerned, if I were you, I would just make sure that it plays nice together. I think the answer would be yes, since it mainly is working on the Access-Control headers, and I do not think your package is doing that (yet).

Absolutely! Speaking for myself as a developer that uses Sanic, I would definitely love to pip install a package to get up an running quick, but then be able to get into the details as needed to make adjustments. If this can be done with one package, that is a win.


#5

I was looking at your implementation.

As an FYI, Sanic is Python 3.5 framework. While I totally am on board with you that f strings are the way to go, since they are Python 3.6, your package will not work with a Sanic project still on 3.5.

I just ran a query to see what the Python version breakdown is since November 1.

SELECT
  REGEXP_EXTRACT(details.python, r"([0-9]+\.[0-9]+)") AS python_version,
  COUNT(*) AS downloads
FROM TABLE_DATE_RANGE(
  [the-psf:pypi.downloads],
  TIMESTAMP("2018-11-01"),
  CURRENT_TIMESTAMP()
)
WHERE file.project="sanic"
GROUP BY python_version
ORDER BY downloads DESC

Here are the results. As you can see, it is less than 10%, but it is still a sizeable number. Take that information for what it is worth.

[
  {
    "python_version": "3.6",
    "downloads": "28005"
  },
  {
    "python_version": "3.7",
    "downloads": "10408"
  },
  {
    "python_version": "3.5",
    "downloads": "6087"
  },
  {
    "python_version": null,
    "downloads": "3838"
  },
  {
    "python_version": "2.7",
    "downloads": "356"
  },
  {
    "python_version": "3.4",
    "downloads": "64"
  },
  {
    "python_version": "3.3",
    "downloads": "10"
  },
  {
    "python_version": "2.6",
    "downloads": "2"
  }
]


#6

Thank you so much for the feedback - as stated previously I have a more security background than development and so I really appreciate you taking the time to look into the implementation and your insight - I want to be as modern as possible but still have proper coverage. Another one of my goals was to try to keep within the framework workflow and design - I hope I accomplished that (ie how in practice these headers/attributes are set inline) - please let me know if I missed the mark. Regarding CORS, if added it would be an optional value (since it needs to be specific and intentional) and I would attempt to always call out framework specific implementations as the preferred method - I do need to research which projects are available. I will test with the sanic-cors package to ensure interoperability. Also thanks for the project’s first star! I am actually headed out for a run with your (anticipated since announced) Talk Python podcast - looking forward to learning more about the framework.


#7

:grimacing: I hope I made sense and was not a babbling idiot.


#8

I thought the interview was awesome, great work!

Also, I tested sanic-cors and they work well together! :partying_face: I also just pushed an update to Secure - replacing the f-strings (and adding an override for default values) and also included a link to sanic-cors! :slight_smile:


#9

Very nice project you have in there! Thanks for sharing! It does add some nice layer of security on top of all frameworks (big plus in there), being very simple to implement in fact. To make this into a Sanic plugin / script (with middlewares to automatically add those headers / cookies keys to every request) is very easy, in fact.

Anyway, I’m not a huge security expert, so one thing I may add for your project would be a more detailed description for each configuration available and why does it matter; or, at least, bring the OWASP link to the top (I passed through it for 3 or 4 times before realizing it was related to the whole project and not only to the Cache-control / Pragma key :wink:).

Just one question: how does one stay in tune with OWASP updates for that matter?


#10

Thank you so much! That is a great suggestion, I will absolutely work on that content. :pray:

For OWASP - there are mailing lists for almost every topic (some more active than others) and there is an OWASP slack (I need to find the way to access - or I think I can invite you), I actually use(d) heavily for feedback on the project and recommendations.


#11

Yeah, well, I knew that the project had some great stuff because I started reading here in the forums, with your background in the area and etc. But, for someone that doesn’t know this background and end up bumping into your project without any introduction regarding from where those set of security tips and scripts for headers and cookies came from, they might just think “meh, another attempt to bring more stuff that I don’t need to my framework”.

I think it should be quite the opposite: make sure you capture the attention of anyone that knows little or nothing about the subject to understand how important this might be for their projects, specially in production environments :wink:

Regarding OWASP news, that could be interesting - specially for developers who takes security into serious concern. I would be happy to get news in my mailbox if I can.

PS: I really like the Sanic middleware example! That’s the way to go :metal:


#12

@vltr

Here is the link for signing up to OWASP Slack channel.

@cakinney Great job with the secure. It can save a whole lot of Security Review code fixes before the production drop. (code fixes = arguments :wink: )

Coming from a gevent background, it would be great if your secure module can add a mechanism to monkey patch the default HttpResponse and Cookie class from sanic so that the users don’t even have to explicitly add a middleware to do this. I know it might be too much of an ask considering the framework agnostic mode secure follows, but it will be great to have.

from secure.monkey import patch_sanic
patch_sanic()

The other option is to enable a simpler option of adding a secure middleware where-by the user passes the sanic app to the Class and it takes care of adding the necessary middleware and everything else and the user can just do

from secure import SanicSecureInit
SanicSecureInit(app)

That being said, the secure module is amazing. Kudos.


#13

Thank you so much :pray:! All the feedback has been awesome, encouraging and truly appreciated . :heart: Sanic :dash:

@vltr PS. re: middleware, thank you!


#14

@harshanarayana I think those are great suggestions and absolutely something to look into - even if it is available as an alternative option. I really appreciate the developer point of view as I want to make it as easy and painless to implement as possible (and stay true to individual framework design) to help secure applications. :pray:!


#15

The way to do this would be to make this “recommended”. I’m working on some ideas for content to disperse along with a docker image and some tutorials. I’m thinking maybe adding something about this as well.


#16

@harshanarayana

You know what might be nice and convenient (to take those awkward brackets out in import), what if there were just a subclass that handled this at run time?

from secure.sanic import Sanic 
app = Sanic()

#17

@cakinney, congratulations on your project! You’re actually featured on the Github trending repositories for Python today!

:clap:


#18

:exploding_head: ! Thank you to everyone on the Sanic team and this forum. I truly appeciate all of the advice and encouragement - you were the project’s first supporters and @ahopkins was the first :star2: !


#19

WooHoo! :beers::partying_face:

I look forward to seeing this project grow.