118

Updated Answer for Craft 3 I've updated and consolidated the technical parts of this for Craft 3 and placed them in a security FAQ for easier referencing: https://craftcms.com/guides/security-faq Original Answer for Craft 2) Let me get this out of the way, first... there is no perfect software. Bugs exist and some of those will be security related. ...


16

First a bit of history: Craft 2 has a similar concept where it would store a unique random security key in craft/storage/runtime/validation.key. Alternatively, you could set the validationKey config setting if you wanted to provide your own key instead of use the one generated by Craft. Craft 2 would essentially only use this for encrypting cookie data in ...


14

Yes. Use the RequireLogin tag at the top of a page: {% requireLogin %} This tag will ensure that the user is logged in. If they aren’t, they will be redirected to the Login page, and returned to the original page after successfully logging in. (make sure you are logged out before you test this!)


9

So a few potential things to consider: You do not want to be serving static assets like Javascript, CSS, etc. out of the templates directory. I realize you're planning to put them "elsewhere", but ensure that elsewhere is in the /public/ folder, so that php, Yii, and Craft do not have to be spun up just to serve a static asset. Do not use a Craft routine/...


8

We got this sorted before I finished my Stack Exchange question so I figured I'd share if anyone else runs into similar behavior. After some troubleshooting, we learned that the issue here was that some of our Forms were being cached by Craft's {% cache %} tag and others were not. CSRF Cookies are unique per user per session, so you don't want to cache ...


8

This morning a couple of postings on Craft Slack #devops area linked good descriptions of basic server security, led by @merlingore there. Their instructions are tilted towards Ubuntu as far as specifics, but should fit for any Linux VPS. Recording the links here so we don't lose the patterns. I agree with them because they're actually the same as what I ...


7

If you’re running Apache, you can put a .htaccess file in your templates/ folder with this in it: Deny from all and any HTTP traffic to that folder will be given an Apache 403 error. Even better, you can put this in there: # Send the request to Craft RewriteEngine On RewriteRule (.*) /index.php?p=$1 [QSA,L] and the request will be redirected to Craft’s ...


7

When dealing with XSS concerns, it's important to stay focused on the fact that this is a client-side issue... So in regards to Craft, Twig is the star of the show. Fortunately, Twig takes measures by default to ensure that your output is safe. For example, any time you're outputting some HTML code via a Twig variable, you're required to add a raw filter to ...


7

As long as the PHP files themselves don't introduce any security holes, having them in your web root is perfectly fine. That's not uncommon at all. How they were written makes all the difference, of course. If you aren't sure whether the developer followed best practices for the security of the mailer scripts, that might be of some concern.


6

I've been making use of macros to create a component based architecture in a recent project. I've found this way of working useful in a few different ways: Jumping around your codebase is much easier as you only have to remember what you've named your components or their parent folder to find and edit them. It keeps your main templates easier to scan. You ...


5

There are several config settings which should help... maxInvalidLogins - The number of invalid login attempts Craft will allow within the specified duration before the account gets locked. invalidLoginWindowDuration - The amount of time to track invalid login attempts for a user, for determining if Craft should lock an account. cooldownDuration - The ...


5

I implemented this recently and what I ended up doing is return the content security headers using PHP. Depending on the request path (is it a CP URL or not?), we send CSP headers with unsafe-inline and unsafe-eval or not. Of course, the CP is still unsecured, but what you can do is to specify a custom domain for the CP in your configuration (using the "...


5

You can run the craft setup/security-key console command after cloning the repo. That'll generate a security key for that Craft install and put it in the local .env file. Or for that matter, craft setup will run the whole setup process (database credeitials, security key, etc.). Are there other security considerations to take into account? Keep your ...


4

I ran into this requirement today and initially assumed a plugin would be required, but then I spotted that the native Assets action menu already included a Download File option and it was working just fine with files that weren’t publicly accessible. Maybe we could use that rather than reinventing the wheel? If you check DownloadFileElementAction.php you ...


4

Short answer, no. You'll want to make sure that your DB user has all of the necessary privileges. Just because you're not entering your data into the database doesn't mean that Craft isn't writing its own data into the database. There are several tables responsible for handling data which is automatically generated by Craft, and not managed directly by ...


4

Luke Holder has created a plugin that would help you in this situation. Geo Plugin for Craft CMS


4

Is there a 2-factor authentication plugin for Craft? I've heard of one in private testing, but I'm not aware if they plan to release it publicly or not. Until the official Craft plugin store becomes a thing, the most comprehensive list of Craft plugins available I know of is over on the awesome Straight Up Craft. I want to build a system that someone on ...


3

If you're looking to only allow certain IP addresses to access the entire control panel, you're best bet would be to whitelist them via an .htaccess file. Something like: <Limit GET POST> order deny,allow deny from all allow from 1.2.3.4 </Limit> If you're looking to just allow certain Craft-specific actions by IP address, then you'...


3

Try this: $cookie = new HttpCookie('myCookieName', $data, [ 'expire' => time() + 3600 ]); craft()->request->getCookies()->add( $cookie->name, $cookie ); Your code for reading the cookie is fine. Also – since you use the term "session value" and tagged your question w/ "security" – I'd like to point out that cookies and session variables are ...


3

There is a plugin from Jeroen Kenters called Member Assets which denies access when logged out. If you really need a random url, you could extend his plugin.


3

It depends on what kind of secure infos you write into your templates. I wouldn't put my credit card infos into a twig comment for example, if the template is not above the root. But normally all one could make up from the raw template code is rather uninteresting and not really relevant for further hacking attempts, I'd say. Note: please do NOT put the ...


3

Craft does some basic logging in the form of when an entry was updated/created and the last time a user logged in and from what IP address, etc. If you want anything more detailed than that, you'd need a plugin. There is one called Audit Log that might do what you're looking for.


3

Will it be against the terms and agreements of craft to remove those headers? Will writing a plugin for it be the best way No to both questions – just add the following config values to your /config/general.php file: 'sendPoweredByHeader' => false, 'phpSessionName' => 'WhateverYouWant', Also, check out this excellent post by Brad Bell on the topic of ...


3

<input type="hidden" name="foo" value="{{ 'bar'|hash }}"> and then in your controller: if (($foo = craft()->request->getPost('foo')) !== null) { $foo = craft()->security->validateData($foo); } at which point $foo will either be null (not present), false (present but tampered with), or a string (present and valid)


3

Some good answers already by Luke and khalwat. I wouldn't try to load any templates outside of the normal Craft folder... you get into plugin territory there and it's not necessary. Your templates should always live in the templates folder. That leaves what to do with your static resources. Inline JS/CSS? One thing I didn't see brought up in either answer ...


3

You should always be careful with PHP source files in a public folder. Typically it's fine, however a small mistake in the server's configuration can lead to big problems. It might cause .php files not to be processed by PHP, leading to leaked source files. This famously happened with Facebook in 2007.


3

Each session gets it's own CSRF token, so technically it will be valid as long as a session is valid.


3

Enable CSRF protection in your config again and add {{ getCsrfInput() }} right after the <form> opening tag on all forms on your site, regardless if they are amforms or mailchimp subscribe. I can verify that it won't interfere with the mailchimp plugin as I am currently (and just recently) installed it on a project I'm working on and it works fine.


3

Based on your code - and our comments - you need something like this: <form id="someFormId"> <input type="hidden" name="action" value="sproutForms/entries/saveEntry"> <input type="hidden" name="handle" value="test"> <input type="hidden" name="redirectOnFailure" value="{{ craft.request.getUrl() }}"> <!---some more ...


3

You can share a temporary link to an unpublished entry by clicking on the "Share" button, right next to the "Live Preview" button. Craft 2: Craft 3: This creates a link with a token that will expire automatically. The length of time that the token lasts for can be controlled with the defaultTokenDuration config setting.


Only top voted, non community-wiki answers of a minimum length are eligible