Today I was working on fixing up my continuous integration server (running GitLab’s CI multi-runner). I was making my own custom image based off of the core Ubuntu 16.04 image and all was working perfectly except for the fact that the mysql service would not start up.
This bothered me. I knew that I had the image working before I rebuilt the server, so why weren’t my images working now? Reading through the error logs didn’t really tell me much, but it did end up pointing me in the right direction.
Turns out my host (the machine which was running the docker instance) didn’t have any swap space setup and because of that, the mysql service was not able to run. So, to fix that I ran the following:
I can’t take the credit for the solution, but hopefully it saves you time!
Posted in tools
I must first start this post with a comic on the topic ... it comes from xkcd.com.
Anyways, this shows one of the many reasons why one should never trust any input from a user. This means that you should assume that all users have malicious intent and are attempting to break into your site. Of course, this is not always the case however, when it is, bad things can happen all around. No matter how you are getting data from the user, be it through an input field, URL, hidden field, drop down list etc. users are able to change the information to better suit their attacking desires. This means always make sure that the data is within the bounds of what is expected! What are some examples of bad things which can happen from the user of exploits? I have listed two of the more common threats which I see on a day-to-day basis.
SQL Injection Just say you have a form where you allow the user to select how many records they want to display:
<form method = "post" action = "results.php"> How many records should be displayed? <select type = 'text' name = 'count'> <option value = '5'>5</option> <option value = '10'>10</option> <option value = '15'>15</option> </select> <input type = 'submit' /> </form>
And the back end of your application looks something like this:
$query = "SELECT * FROM `news` LIMIT " . $_POST["count"]; $res = mysql_query($query);
What is to stop the user from modifying one of the values in the drop down list to:
5; DROP TABLE `news`;
Nothing! However, if you don't prevent such a thing from being allowed in your query (i.e. not doing enough data validation), after the user runs that query, your entire 'news' table will be dropped from the system, which was probably not what was originally intended for the script. I have mentioned this method of prevention before, and I'll mention it again, SQL prepared statements. If data is sent in as a parameter rather than as a direct part of the query, there are no chances that the query may be mistaken and have two queries execute instead of one. Cross Site Scripting (XSS) These security vulnerabilities can be fairly hard to track down, however there is always a way. Simple XSS Just say you have your URLs as something like this: http://url.com/read.php?file=temp.php Where in your actual PHP script you have a server side include for whatever value was passed in through $_GET. Well, this is opening up an entirely new can of worms. Yes it works for pages which are on your server, however, it will also work for sites which are off site if you are not careful in your validation. Sample Code:
// This is a VERY bad idea, however it is only an example include($_GET['file']);
If I were to change the URL from: http://url.com/file=temp.php To: http://url.com/file=http://www.google.com By default, PHP will not think anything of it. It will treat the website as a file stream just as it does the 'temp.php' which was originally passed in. And low and behold, somebody is now using your site to access Google. Lesson: validate and verify that the file exists LOCALLY before running the include. Cookie Grabber Since cookies are only accessible on the site which they are associated with, cookie grabbers must use this in order to get the information they need. A fair number of implementations of BBCode which I have seen have allowed for gaping holes because of this. For example, most implementations use regular expressions in order to pick up on the required information (which is what they should be used for). However, since urls and things can have a large number of characters, most programmers choose to use the greedy approach and use the 'anything but newline character' (the period). Regex (something similar to this, as I cannot remember the exact regular expression):
This regular expression will then be replaced in the emitted HTML code to be:
<img alt="" src="$1" />
This is all fine and dandy, and it picks up what is required however, it also has the ability to pick up more than expected and/or desired. For example, if the following was provided it would allow the user to gain access to the cookies which are for a particular site.
This has the potential for changing the emitted HTML into becoming:
<img alt="" src="http://www.google.ca/logos/gabor10-hp.png" />
Effectively causing your web browser to relocate to a different URL with your cookie in the link which they will then log for future use. Of course, if a little extra time was spent in the sanitation of the input problems like this can be filtered out.
Summary: In summary, never ever ever trust user's input. It will only lead you towards worlds of pain. Hope this helps!
Posted in php
I have recently seen posted numerous times that if you run the function 'mysql_real_escape_string' on any data, you are then automatically safe from SQL injection. Well, this isn't the case at all ... To start, let's look at what php's documentation about 'mysql_real_escape_string' says: php.net
Escapes special characters in the unescaped_string, taking into account the current character set of the connection so that it is safe to place it in a mysql_query(). If binary data is to be inserted, this function must be used. mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a. This function must always (with few exceptions) be used to make data safe before sending a query to MySQL.
So, not only does it force you to have the mysql connection (why is this really needed for just escaping a few characters?), it just adds a '\' before some of the characters which could break a query. This is because lots of people write queries as follows:
$query = "SELECT `user_id`, `username`, `startdate` FROM `users` WHERE `username` = '$username'";
However, if $username contains "blarg'; DROP TABLE `users`; --", then mysql_real_escape_string will change it to "blarg\'; DROP TABLE `users`; --" which will not break the query (so the users table will not be dropped). But if the attacker was smarter and used a different representation of it by using %39; (hexadecimal value for '), mysql_real_escape_string will not touch it, so it will go into your query and inconveniently drop your table. This small example shows the the use of 'mysql_real_escape_string' is ineffective in preventing against SQL injection. Instead of using 'mysql_real_escape_string' I would strongly suggest the use of database parameters (prepared statements) for all queries, or create a way which will convert from the %39; to their corresponding values (i.e. html special chars decode) just to make sure that characters you don't want to be in there don't sneak in.
Posted in php