I'm using a form on my website to send an email using the PEAR mail function. The email will send via gmail as described here - http://www.phpmaniac.net/wiki/index.php/Pear_Mail
I will therefore need to include something like the:
<?php
$smtp_params["host"] = "smtp.gmail.com";
$smtp_params["port"] = "25";
$smtp_params["auth"] = true;
$smtp_params["username"] = "user#gmail.com";
$smtp_params["password"] = "pass";
?>
Is it secure to put my username and password in the script like that? Obviously you wouldn't be able to see server-side script like this using 'View Source', but could you grab the source files via a web clipper or something and read the script that way? Thanks
If someone accidently disbles php parsing on you apache, your file will be served as plain text, so i like to keep passwords in config files outside my docroot... Just in case. Several times when building a new php modual for apche i forgot to copy a php.conf file into my httpd/conf.d/ direcoty and started apache without php. i
In theory, any insecure connection can be snooped. However, in this case it would need to be intercepted between your server and gmails smtp server. Also, even if you securly sent the email to the mail server, you have no certainty that they will connect securely to deliver it or the inteded receipient will securely check their email account.
In this case you just care about your basic auth being snooped. Use gmails secure ssl connection
Be safe by assuming all email communication is not secure. (unless you encrypt the message)
You should certainly use SSL/TLS for the connection - simply because sending passwords in plaintext over an unencrypted channel is a bad idea.
The login data inside your PHP script is safe as long as the PHP interpreter works properly and there are no security holes in your PHP scripts that allow an attacker to view the sourcecode of your PHP files.
Against the risk of misconfiguration causing PHP sourcecode to be visible an easy improvement would be storing the config file outside the document root.
Related
I created a PHP application where I have a settings panel, where the user has to provide some data, necessary for the application to work. There are fields regarding SMTP settings, that the user will provide, so that the application can send confirmation emails to customers when t.
In order to do that i save the information provided in the database, one of the required fields is SMTP Password, which i need to save in a raw state, without any hashing. I need it this way because PHPMailer needs the password as it is, not a hash.
I am worried about how secure this method is, because i don't want to save it in plain text, but i also need it this way in order to send emails.
I need some advice regarding this issue.
PS: I forgot to mention that i use XAMPP to develop the application.
Thank you in advance!
You should never store plain text passwords in the database. As other commenters have noted, .env configuration files above the web root are a standard approach. However, the approach you take depends on how your app is hosted. For example, if you are hosting the app on AWS, the recommended approach is to store the credentials as environment variables that can be accessed like so:
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->SMTPAuth = true;
$mail->Host = $_SERVER['SES_HOST'];
$mail->Username = $_SERVER['SES_USERNAME'];
$mail->Password = $_SERVER['SES_PASSWORD'];
$mail->SMTPSecure = 'ssl';
The same approach can be taken using a .env file. Or if you are using Apache, you could add the variables to the httpd.conf file as shown below, and then access them by referencing the $_SERVER global:
SetEnv SES_PASSWORD strongpassword123
Since you mentioned you are using XAMPP (so Apache), open the Apache config and modify the httpd.conf file and add the SetEnv line above to the bottom of that file. After restarting the Apache service, you will be able to reference your value using $_SERVER['var_name'].
We have shared hosting servers which use PHP fastcgi (on IIS) for several clients (shared hosting). Regularly clients use old exploitable code which causes holes in their applications that eventually gets used by hackers to install malicious code. Most of the time this code is being used to send spam from our servers.
We have no control over our clients code, so patching the holes is quite impossible.
We would however like to block the clients sending spam once they send more then X email messages in Y amount of time.
The setup is fastcgi based, so there is little relation between php and the webserver.
PHP sends its mail through SMTP on localhost. The mailserver allows relay of all localhost connections (obviously).
One thing that goes through my mind is setting an environment variable containing an identifier in the fastcgi environment and using php's prepend file option to add a header to all mail send by php's mailer. After that we could use that mail header to identify the spamming culprit.
The option above still would not take care of spam scripts using regular telnet (telnet localhost, HELO, MAIL FROM etc... ) when sending email.
My question to you: is the idea that i've mentioned the best and perhaps only option to deal with our issue? Or are there better solutions for this situation? And if so, please explain how you would deal with the issue.
You can filter that on you MTA (message transfer agent). For example, allow no more than 50 emails in 1 hour for each user in Exim ( http://www.exim.org ) config file (/etc/exim/exim.conf):
begin acl
acl_check_not_smtp:
warn ratelimit = 0 / 1h / strict / $sender_address_local_part
log_message = Sender rate $sender_rate / $sender_rate_perio
acl_not_smtp = acl_not_smtp
begin acl
acl_not_smtp:
deny message = Sender rate overlimit - $sender_rate / $sender_rate_period
ratelimit = 50 / 1h / strict
accept
And no matter how they try to send, via php mail() or other method.
Most shared hosts block the use of PHP's mail() function, as that can be easily exploited. Instead they advice using sendmail or similar scripts which require SMTP authentication before sending. Assuming you're not already doing this, once implemented, you should be able to keep track of number of emails sent from a particular domain/email account and put restrictions on it.
Okay, stick with me on this one. I have not implemented it but it looks good.
The concept here is that you could
run a php file before EVERY page on your customers site
in that php file rename the mail function to mail_internal().
in that php create a new function called mail to do your check / verification that your customer is allowed to send mail, and if they are call the mail_internal() function with the same parameters.
You will have to install the runkit PECL extension
http://us.php.net/manual/en/runkit.installation.php
Changes
in php.ini
auto_prepend_file /var/www/allclients_forcedfile.php
in /var/www/allclients_forcedfile.php
runkit_function_rename ( "mail" , "mail_internal" );
function mail ( $to , $subject , $message, $additional_headers = "", $additional_parameters ="" )
{
$args = func_get_args();
error_log("mail_internal : $_SERVER[HTTP_HOST] : ".implode(" : ",$args));
//lookup whether you want to send more mail for this client maybe by keeping a counter in some file in the $SERVER[DOCUMENT_ROOT]
if($sendmoremail)
return mail_internal ( $args[0], $args[1] , $args[2], $args[3] , $args[4] );
return false;
}
As expected it seems Stack Overflow is not the right place for this question. The provided answers do not expose some clear method to identify FastCGI sessions' connections to the MTA (SMTP) server.
I will go with my initial concept of adding an identifier to php's environment. This identifier can be read in PHP's prepend file by using the getenv() function. This identifier can then be added to mail headers for outgoing mail.
Furthermore I have enabled the mail.add_x_header ini setting which will help identify which script caused the spam run.
I am leaving the question open for the bounty duration, hoping other options will magically appear :)
I do not know too many details except that I access the internet from behind a proxy server (I have the IP and port)
and that I'm running PHP out of localhost (using WAMP)
The mail() isn't able to send emails.
Really new to PHP, so would appreciate help fixing this.
Do you have access to the php.ini file or the ability to override php.ini settings with the ini_set function?
Then you can try and override the SMTP settings and replace it with for example your ISP settings:
http://www.php.net/manual/en/mail.configuration.php#ini.smtp
Apparently you can't set a username/password if required by the SMTP server. So you probably have to use a third-party e-mail library. Try Swift: http://swiftmailer.org/
Or check this post with a similar question: php.ini & SMTP= - how do you pass username & password
I am using postfix for my linux mail server. The goal is to have any incoming mail dumped into a database with the headers and message information, then the e-mail being deleted from the mail server. Is there any way to make postfix post a message to a php file everytime a new e-mail comes in then delete the e-mail message? The only other way I can see to make a script to poll the e-mail server, read each mail and transfer the contents to a database, then delete the messages from the mail server. Being able to have postfix automatically execute the php script for all new incoming mails would be a better choice. If it makes a difference, the mail server and the server with the php file is the same. Any direction in this matter would be greatly appreciated.
use .forward, /etc/aliases, hashtable etc to forward mail to a script.
In /etc/aliases, I have
mysite-confirm: |/home/mysite/confirm.sh
In confirm.sh, I have
#!/bin/sh
basedir=/home/mysite/www
php -d include_path=$basedir/includes -f $basedir/cli/confirm.php
In confirm.php, the magic happens:
$contents = file_get_contents("php://stdin");
do_magic_with_mail($contents);
All quite simple and rigid. The only downside is that you could mail mysite-confirm#any_domain_I_host.com, but you can fix that with the right aliases / virtualmaps etc.
I'm looking for a way to authenticate users through LDAP with PHP (with Active Directory being the provider). Ideally, it should be able to run on IIS 7 (adLDAP does it on Apache). Anyone had done anything similar, with success?
Edit: I'd prefer a library/class with code that's ready to go... It'd be silly to invent the wheel when someone has already done so.
Importing a whole library seems inefficient when all you need is essentially two lines of code...
$ldap = ldap_connect("ldap.example.com");
if ($bind = ldap_bind($ldap, $_POST['username'], $_POST['password'])) {
// log them in!
} else {
// error message
}
You would think that simply authenticating a user in Active Directory would be a pretty simple process using LDAP in PHP without the need for a library. But there are a lot of things that can complicate it pretty fast:
You must validate input. An empty username/password would pass otherwise.
You should ensure the username/password is properly encoded when binding.
You should be encrypting the connection using TLS.
Using separate LDAP servers for redundancy in case one is down.
Getting an informative error message if authentication fails.
It's actually easier in most cases to use a LDAP library supporting the above. I ultimately ended up rolling my own library which handles all the above points: LdapTools (Well, not just for authentication, it can do much more). It can be used like the following:
use LdapTools\Configuration;
use LdapTools\DomainConfiguration;
use LdapTools\LdapManager;
$domain = (new DomainConfiguration('example.com'))
->setUsername('username') # A separate AD service account used by your app
->setPassword('password')
->setServers(['dc1', 'dc2', 'dc3'])
->setUseTls(true);
$config = new Configuration($domain);
$ldap = new LdapManager($config);
if (!$ldap->authenticate($username, $password, $message)) {
echo "Error: $message";
} else {
// Do something...
}
The authenticate call above will:
Validate that neither the username or password is empty.
Ensure the username/password is properly encoded (UTF-8 by default)
Try an alternate LDAP server in case one is down.
Encrypt the authentication request using TLS.
Provide additional information if it failed (ie. locked/disabled account, etc)
There are other libraries to do this too (Such as Adldap2). However, I felt compelled enough to provide some additional information as the most up-voted answer is actually a security risk to rely on with no input validation done and not using TLS.
I do this simply by passing the user credentials to ldap_bind().
http://php.net/manual/en/function.ldap-bind.php
If the account can bind to LDAP, it's valid; if it can't, it's not. If all you're doing is authentication (not account management), I don't see the need for a library.
I like the Zend_Ldap Class, you can use only this class in your project, without the Zend Framework.
PHP has libraries: http://ca.php.net/ldap
PEAR also has a number of packages: http://pear.php.net/search.php?q=ldap&in=packages&x=0&y=0
I haven't used either, but I was going to at one point and they seemed like they should work.
For those looking for a complete example check out http://www.exchangecore.com/blog/how-use-ldap-active-directory-authentication-php/.
I have tested this connecting to both Windows Server 2003 and Windows Server 2008 R2 domain controllers from a Windows Server 2003 Web Server (IIS6) and from a windows server 2012 enterprise running IIS 8.