So I am not sure if this is possible,but here we go. I want to be able to create a string that functions as normal ,but is not readable. For example:
$password = "//312(!##()";
then I could go something like.
if($input == $password) {
}
Is there anyway I can possibly do this? I may be talking through a hole in my head, but any help on the subject would help.
You can hash the String:
$pw_hash = "098f6bcd4621d373cade4e832627b4f6" //is the hash of "test"
if ($pw_hash == md5($variable)){
//now you know, the variable is "test",
//without writing it plaintext in the sourcecode.
}
But search for hashes. There are better options than md5. Also google for "salt" and get aware of what's the difference between "hashing" and "encrypting".
From your comments, I believe that you want to hide your php source code when deploy the application. I see many developer usually use the base64_encode encode the original PHP code to be a single string and use eval(base64_decode($str)) in their deployed package.
However, that way can only useful with normal user, we can always use an online tool like http://perishablepress.com/tools/decoder/ (or write your own function) to get the original source :)
Related
For my application, written in PHP 5+, I have a common.php which is included from all other pages. Within that I have an include sanitize.php which aims to sanitise any input vars used in the URL. So, targetting $_GET[] values.
This is just to have one place where I can tidy any vars, if used, and use them in the code later.
There seems to be no tidy way, I've seen, to sanitise based on expected/desired inputs. The method I initially looked at was this sanitize.php having a foreach to loop through any vars, lookup the type of sanitization required, and then add the cleaned vars to a separate array for use within my code.
Instead of using PHP sanitization filters, to keep it standard, I thought I'd use regex. Types I want are alphaonly, alphanumeric, email, password. Although "password" would allow some special chars, I want to remove or even escape potentially "hazardous" ones like ' " to then be included into a mysql DB. We have a european userbase so different locales are possible, but I'm hoping that won't be too much of an issue.
Would this be a "good" solution to start from, or am I trying to reinvent the wheel?
Random Page
/mypage.php?c=userid&p=lkasjdlakjsdlakj&z=....
(use SANITIZED_SAFE_INPUT_VARS variable only)
sanitize.php
var aryAllowedGetParamNames = array(
"c" => "alphaonly", //login
"p" => "alphaemail", //password
"e" => "email" //email
//...
);
var sanitizeTypes = array (
"alphaonly" => "[a-zA-Z]",
"alphanumeric" => "[a-zA-Z0-9]",
"email" => "[a-zA-Z0-9]...etc"
);
var SANITIZED_SAFE_INPUT_VARS = array();
foreach ($_GET as $key => $value) {
//apply regex and add value to SANITIZED_SAFE_INPUT_VARS
}
EDIT
There seems to be some opinion about the use of passwords in the URL. I'll explain in a little more detail. Instead of using a POST login prompt with username and password, I am using an ajax async call to _db_tryLogin.php with parameters for userid and password. The username is ALWAYS a 6-ALPHA-only text string, and the password is an md5 of what was typed. I'm aware of the opinions on MD5 not being "safe enough".
The JS currently MD5s the password and sends that to the _db_tryLogin.php.
-> async : _db_login.php?c=ABCDEF&p=SLKDauwfLKASFUWPOjkjafkKoAWOIFHF2733287
This will return an async response of "1" or "0". Both will cause the page to refresh, but if the _db_tryLogin.php page detects the password and userid matches one DB record, then session variables are set and the site knows the user is logged in.
I used MD5 for the async request just to quickly hash the password so it's not transmitted in plaintext.
The _db_tryLogin.php takes the password, which is md5(plainpass) adds a SALT and MD5s again, and then this is what is compared against the usertable in the DB.
DB password stored = md5(SALT.md5(plainpass))
I would to start just regex each variable , apply null if it doesn't match the requirements. Either test what it SHOULD have only, or what it shouldn't have, whichever is smaller:
$safeValue = (preg_match('/^[a-zA-Z0-9]{0,5}$/',$value) ? $value : "");
ALONG with prepared statements with parameter input aka
$query = "SELECT x FROM table WHERE id=?";
bind_param("si",$var,$var)
PHP also comes in with built filters, such as email and others). Example: filter_var($data, FILTER_SANITIZE_EMAIL)
http://php.net/manual/en/filter.filters.sanitize.php
What are you sanitising against? If you're [only] trying to protect your SQL database you're doing it wrong, and should be looking into Prepared Statements.
USER SUBMITTED DATA SHOULD NEVER BE TRUSTED. Accepted, yes, trusted - No.
Rather than going through a long tedious process of allowing certain chararacters, simply disallow (ie remove) characters you don't want to accept, such as non-alphanumeric or backtick characters etc. It may also save you a lot of efforts to use the PHP strip_tags() function.
1) Create your function in your include file. I would recommend creating it in an abstract Static Class, but that's a little beyond the scope of this answer.
2) Within this function/class method add your definitions for what bad characters you're looking for, and the data that these checks would apply to. You seem to have a good idea of your logic process, but be aware that there is no definitively correct code answer, as each programmers' needs from a string are different.
3) using the criteria defined in (2) you can then use the Regex to remove non-valid characters to return a "safe" set of variables.
example:
// Remove backtick, single and double quotes from a variable.
// using PCRE Regex.
$data = preg_relace("/[`"']/","",$data);
4) Use the PHP function strip_tags() to do just that and remove HTML and PHP code from a string.
5) For email validation use the PHP $email = filter_var($data, FILTER_SANITIZE_EMAIL); function, it will be far better than your own simple regex. Use PHP Filter Validations they are intended exactly for your sort of situation.
6) NEVER trust the output data, even if it passes all the checks and regexes you can give it, something may still get through. ALWAYS be VERY wary of user submitted data. NEVER trust it.
7) Use Prepared Statements for your SQL interactions.
8) As a shortcut for number types (int / float) you can use PHP type-casting to force a given varibles to being a certain type and destroying any chance of it being anything else:
$number = $_GET['number']; //can be anything.
$number = (int)$_GET['number']; //must be an integer or zero.
Notes:
Passwords should not be a-z only, but should be as many characters as you are able to choose from, the more the better.
If the efforts you are actioning here are for the case of protecting database security and integrity, you're doing it wrong, and should be using Prepared Statements for your MySQL interactions.
Stop using var to declare variables as this is from PHP4 and is VERY old, it is far better to use the Variable preconditional $ (such as $variable = true;) .
You state:
We have a european userbase so different locales are possible
To which I would highly recommend exploring PHP mb_string functions because natively PHP is not mutlibyte safe.
So I'm busy building a site and trying to test out a sort of filter for certain words but trying to determine which is the best function to use and through what language. I've done a bit of research and in PHP I can use the strpos() function so for example:-
if (strpos($checkstring, 'geordie') !== false) {
$checkstring = 'invalid name';
}
I'm unsure as to whether there is a decent JQuery function that could be used to achieve the same thing. Basically I want to be able to block my friends from using my name or nickname so it would include any and all variations of 'geordie' including lowercase and uppercase as well as getting past it using 'GeoRdie' or something to that affect but also want to stop variations which would be my full nickname 'geordie dave' or 'geordie ****' or even 'geordie dave is a ****'.
I realise that this is probably a bit of a complicated one but there must be a way using perhaps an array of names?
Any help on a function to use would be great and if anyone could possibly give me an example of code that could be used would also be beneficial.
You should probably do it in javascript and in php (client side and server side). The javascript eqivalent of strpos is indexOf. If you only check with javscript, someone could forge a post packet and it would still be accepted by the server. If you are only going to check in one place, make it server side, but for user-friendly-ness, both is preferred.
I think that you should also use PHP strtolower function on $checkstring variable.
In JavaScript, you can use String#indexOf(String) to match exact strings, or RegExp#test(String) for more complicated matching.
if (str.indexOf("geordie") !== -1) {
// `str` contains "geordie" *exactly* (doesn't catch "Geordie" or similar)
}
if (/geordie/i.test(str)) {
// `str` contains "geordie", case-insensitive
}
And I'll second what Alfie said: You can't just do this on the client, because client requests can be spoofed. Client-side validation is purely for making a nice user experience; server-side validation is always required.
I am storing PHP snippets in a MySQL database, I am using mysql_real_escape_string and all is well unless there is a & in the php code and then I get a MySQL error. Is there another why I should try and store this information?
Thanks
#Peter : unless you're building a website for helping developers, you have no reason to put php code into your database, it's a warning : this is gonna be a big nightmare to maintain/debug. Can't you link your pages to some parameters and then in your code use these parameters to build each request ?
it may seems a simple design solution at the beginning "how god I can do whatever I want in all my pages" but it might be the worse you're taking on your poject.
I don't know how to say this but you should really try to consider an other solution. And i'm not speaing about security : if you have an SQL Injection the guy can execute SQL AND php so he can really take all your system/server down, or even attack bigger site with yours (and then you'll be responsible).
I'm really surprised everyone is fine with it.
Use base64_encode when you save snippet into the database and base64_decode when you retreive it.
First, I am going to go on record and say I wholeheartedly agree with remi bourgarel. This is likely a bad idea.
But, from a technical standpoint here's how I'd do this IF I NEEDED TO:
$php_code = '
<?php
$var = "this is a string";
$var = strtoupper($var);
echo $var;
?>
';
$php_code = bin2hex($php_code);
$db->query("INSERT INTO php_code_snips (text_code) VALUES(x'{$php_code}')");
bin2hex will transform the string $php_code from a binary string to a hex string, and the x'{$php_code}' tells mysql to expect a hex string.
This means the string is stored as a string in the DB, and is fully searchable. But, since all chars are encoded as hex during the INSERT the special chars won't cause a problem.
Documentation:
bin2hex
Mysql Hex Values
I need to compress a string so it is shorter for a GET method form. Is there any way to compress a string and it will be decrypted later? That way...
?error=LOTS OF STUFFLOTS OF STUFFLOTS OF STUFFLOTS OF STUFFLOTS OF STUFF
is shorter in some sort of key
?error=somekey
so I can get back the result later. Not using MySQL preferably.
Anyone know a good method for this?
Update: To clarify, I am using a GET because this is a cross site include and a POST will not be accepted into the variable scope of the HTTP included file.
If you're using PHP, the easiest way to send an error message is with the $_SESSION. Simply say session_start(); at the top of the pages, and say $_SESSION['error'] = "TEXT";. Then isset($_SESSION['error']);.
Of course, you could always use $_POST.
I'd use POST instead... Or, come up with your own key mapping (error=1 would map to a long wordy error - like Col. Shrapnel's example).
You could also use a hash table. http://en.wikipedia.org/wiki/Hash_function
Easiest way to make your GET string shorter. Use POST.
(Update: Again, if you control how the form is sent, use POST. Use it. Don't use GET. To be clear, if you can use POST.)
But perhpas you need to pass this data as a regular old link. In that case I guess you could try php's compression functions. Some of the operate directly on strings.
For example, gzcompress() and gzuncompress() could be used to compress/uncompress a string. From the php manual:
<?php
$compressed = gzcompress('Compress me', 9);
$uncompressed = gzuncompress($compressed);
echo $uncompressed;
?>
Of course you'll have to run it through urlencode() and urldecode() - which since I'm sure the compression algorithms will output binary data, may not really save you anything.
Or it may not work at all. Would be interesting to try.
Update: Tested, it's crazy, but it did make your example string smaller.
Not really 'on-the-fly', You might be able to Gzip and then base64 encode, (but base64 encoding increases the size, I just don't know how much)
But really, if you are exceeding the GET size, you should probably just switch to POST.
I'm doing something like the following:
SELECT * FROM table WHERE user='$user';
$myrow = fetchRow() // previously I inserted a pass to the db using base64_encode ex: WRM2gt3R=
$somepass = base64_encode($_POST['password']);
if($myrow[1] != $somepass) echo 'error';
else echo 'welcome';
Im always getting error, I even echo $somepass and $myrow[1] they are the same, but still error. What Am I doing wrong? Thanks
Try using var_dump instead of echo - maybe one of them has a space or newline at the start/end.
Edit:
You must be storing it as CHAR(40): A fixed-length string that is always right-padded with spaces to the specified length when stored
Use VARCHAR or trim()
If $myrow[1] is actually the correct password in base64-encoding, I don't see any errors.
Try this ind the end:
echo "<br />$myrow[1] != $somepass";
What does it say?
And by the way: I don't see any reason to base64-encode the passwords. What are you trying to accomplish?
I think somehow if I do a var_dump() I get:
string(40) "YWRraM2= "
string(8) "YWRraM2="
seems like somehow if I insert the data into the db using the console its adding an extra space to the pass field.
myplacedk: is there any reason why I should not be doing it? I thought it will add an extra leyer of security?
This encoding does two things:
It adds code, making it more complex and easier to make errors
If you view your database on your screen, and someone looks over your shoulder, the passwords may be a bit harder to remember.
So no, it doesn't really add any security. It's just an encoding, it's easy to decode.
Maybe you are mistaking it for md5-hashing or something like that.
Playing around is great, but when it comes to security, I really recommend not using something you don't understand. In the long run, it will do more damage than good.
Some issues:
From your comments elsewhere, I guess that the problem with the current code is that your database field is CHAR(40). A CHAR field always has a fixed size. Try changing the database field type to VARCHAR instead of CHAR.
Using base64_encode before storing in a database is nowhere near secure. Good practice is storing only a one-way hash of the password in the database -- typically md5 or (better) sha1. Then, when the user wants to log in, use the same hash-function on the provided password, and then compare the two hashes.
This has the added benefit of working with passwords longer than 40 characters too.
A sha1 or md5-hash always takes a fixed amount of space, so if you go this route, you don't have to switch your database column to VARCHAR :)