目前分類:程式 (64)

瀏覽方式: 標題列表 簡短摘要

在差不多四月底時收到來自Google通知的這一封信:「您可能無法再存取某些第三方應用程式」。

相關文章已轉發表至 Medium : 

https://medium.com/@bojack.tw/%E5%9C%A8phpmailer%E4%B8%AD%E4%BD%BF%E7%94%A8-oauth2-%E9%80%8F%E9%81%8E-gmail-%E7%99%BC%E4%BF%A1-d8cf752fb5b6

文章標籤

Bojack 發表在 痞客邦 留言(0) 人氣()

今天都在研究 Google reCAPTCHA 這機制,相信大家都已經知道這是個反制機器人登入的好東西

依 iThome 於去年 10/30 說明的這篇文章,目前的 reCAPTCHA 已經出到了 v3,而 v3 和 v2 最大的差別就在於它不再要求使用者與網站之間的互動

而是依使用者的行為計算分數後,再讓網站管理者判斷是否要再進一步進行驗證

分享一下我的作法 ~ 首先要先到 reCAPTCHA Admin Console 建立 v3 的驗證資料,記得要勾選 v3 喔 !

建完之後會得二組金錀,一組是網站本身用的,另一組是用來和 Google 主機連線驗證使用,接下來分享我實作的程式碼

首先這是登入頁面的 index.php 程式

<html>
  <head>
    <title>Google recapcha v3</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://www.google.com/recaptcha/api.js?render=這邊填入網站本身的金錀">      
    </script>
    <script>
      grecaptcha.ready(function() {
      grecaptcha.execute('這邊填入網站本身的金錀', {action: 'homepage'}).then(function(token) {
        var recaptchaResponse = document.getElementById('recaptchaResponse');
        recaptchaResponse.value = token;
      });
  });
  </script>
  </head>
  <body>
    <h1>Google reCAPTHA Test</h1>
    <form id="testform" action="form.php" method="post" >
      <input type="email" name="email" placeholder="輸入email" size="40"><br><br>
      <input type="submit" name="submit" value="送出"><br><br>
      <input type="hidden" value="" name="recaptcha_response" id="recaptchaResponse">
    </form>
  </body>
</html>

接下來這是第二頁 form.php 程式

<?php
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret = '這邊填入和Google連線使用的金錀';
$recaptcha_response = $_POST['recaptcha_response'];

//Make and decode POST request:
$recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
$recaptcha = json_decode($recaptcha);

//如果驗證成功,就進一步計算使用者分數,官方回饋分數為 0-1,分數愈接近 1 就是正常,低於 0.5 以下就有可能是機器人了
if($recaptcha->success==true){
   if($recaptcha->score >= 0.5) {
       echo 'Pass !';
   } else {
       echo 'Spammer';
   }  
} else {
  echo 'Connection failed';
}
?>

大概就是這樣,至於連線 Google 驗證回傳的值請再參考官網相關說明

reCAPTCHA v3

Verifying the user's response

參考資料

1. recaptcha v3 with php

2. https://gist.github.com/webeasystep/85a20c9278dc5c3763ef82848c7d0558

Bojack 發表在 痞客邦 留言(0) 人氣()

假設您的 Wordpress 原來網址是 www.abc.com.tw 因為某種原因要換成 www.def.com.tw,要怎麼做呢 ? 

步驟其實不會太麻煩,不過請先記得先備份您的資料庫 ! 先備份您的資料庫 ! 先備份您的資料庫 ! 

說了很重要的事情三次後,接下來進入正題

第一步驟

登入您的 Wordpress 後台,點選「設定」->「一般」,請將原本舊的 WordPress 位址(URL)網站位址(URL) 直接換成新網址後,拉到最下按「儲存變更」即可

這邊的網址後面不需要加最後面的 / 喔,請注意 ~ 這時就會發現連不到網站後台了,不用擔心

第二步驟

請連進資料庫後台,針對 Wordpress 的 Database 要下幾個關鍵的 SQL 語法,總共有 4 個要做

UPDATE wp_options SET option_value = replace(option_value, 'https://舊網址', 'https://新網址') WHERE option_name = 'home' OR option_name = 'siteurl';
UPDATE wp_posts SET guid = replace(guid, 'https://舊網址','https://新網址');
UPDATE wp_posts SET post_content = replace(post_content, 'https://舊網址', 'https://新網址');
UPDATE wp_postmeta SET meta_value = replace(meta_value,'https://舊網址','https://新網址');

第一個 SQL 有可能會是 0 筆是正常的喔,另外 SQL 語法裡的 http 或 https 請視您自己網站原本的協定為主,像我的網址都有啟用 https,若您的沒有就請用 http 即可

就這樣,結束 ! 至於您的 Web Server 有另外要調整 Apache or IIS 設定請再自行調整即可 ~

 

Bojack 發表在 痞客邦 留言(0) 人氣()

以下防止 SQL Injection 的程式是參考 AppleBOY 這篇文章 : PHP+MySQL 環境下 SQL Injection 攻防戰

//處理 SQL Injection
if( is_array($_POST) && !get_magic_quotes_gpc())
{
    while( list($k, $v) = each($_POST) )
    {
        $$k = checkhtml(mysql_real_escape_string(trim($v)));
    }
    @reset($_POST);
}

Bojack 發表在 痞客邦 留言(0) 人氣()

去年 2014 年曾用 PHPMailer 寫了一支程式讓它透過 Gmail 去發送,這二天又要拿出來用時發現怎麼一直都寄不出去

開啟 Debug Log 發現 PHPMailer 吐了一堆訊息,裡含有這個網址 https://support.google.com/mail/answer/78754

看了裡面的說明原則上注意三件事即可

1. 首先確認您的 Google 帳戶與密碼是正確的

2. 登入 Google 之後去設定允許安全性較低的應用程式存取您的帳戶,把它設定為開啟

3. 最後請到這裡去授權允許存取 ( 感覺只是解開而已 )

這樣就正常啦 !!

Bojack 發表在 痞客邦 留言(0) 人氣()

今天下載了 PHPMailer,版本是 5.2.8

我的環境都是使用 UTF-8,如果想要將信寄出去都也是走 UTF-8 編碼的話,要做下列二件事

1. 在 class.phpmailer.php 裡設成

public $CharSet = 'UTF-8';

2. 在寄信的程式頁面加入這一行

mb_internal_encoding('UTF-8');

 這樣寄信出去就不會是亂碼囉!

Bojack 發表在 痞客邦 留言(0) 人氣()

這可能是一篇落落長的故事,但我還是要盡力記錄下來 ~ 因為是一個很寶貴的資安事件與經驗

話說我們有一台主機,它的功能是一台委外廠商對外營運的 Web 主機,非常單純 ~ 防火牆就是只有開放 80 Port 可存取

前陣子有一天業管單位說怎麼外面 Internet 的使用者都連不太進來,網路感覺很頓,第一時間我把問題反應給管理 VM 環境的同仁,請他協助查看是否在 VM 環境有異常

而管理 VM 主機的同仁說可能是網路的問題,於是再把問題轉給管理網路的人查看

初步察看的情況,管理網路的同仁說入偵防禦系統有很大量的來自於那台 Web 主機 IP 的異常 log,當下的直覺就是主機可能出問題了

Bojack 發表在 痞客邦 留言(1) 人氣()

瀏覽檔案的頁面

<form id="form1" name="form1" method="post" action="upload.php" enctype="multipart/form-data">
<input name="file1" type="file" id="file1" />
<input type="submit" name="button" id="button" value="上傳檔案" />
</form>

檔案上傳頁,上傳後我把檔名同時也改成當下的時間

$explode_filename = explode (".", $_FILES['file1']['name']);
$upload_filename = date("YmdHis") . "." . $explode_filename[1];
move_uploaded_file($_FILES["file1"]["tmp_name"],iconv("utf-8", "big5", $upload_filename));

特別要注意的是,我這二個網頁都是用 UTF-8 編碼,所以在處理檔案時得用 iconv 函式先轉換後再上傳,不然上傳後的檔案會無法開啟喔!

反之,若原本就是用 Big5 在處理的話,那麼就改成這樣即可

$explode_filename = explode (".", $_FILES['file1']['name']);
$upload_filename = date("YmdHis") . "." . $explode_filename[1];
move_uploaded_file($_FILES["file1"]["tmp_name"],$upload_filename);

Bojack 發表在 痞客邦 留言(2) 人氣()

剛研究 PHP 跟 OpenLDAP 驗證的東西,建議是用 MD5 or SSHA 加密比較安全,這篇是在說明怎麼用 SSHA 來驗證

howforge.com - How to create and verify SSHA hash using PHP

There are so many hash. SHA1 is one of them which is widely used in recent years even though it is not safe to use right now. By the way, it is still the default hash function for storing password in LDAP especially OpenLDAP. In order to develop a website with LDAP authentication manually against POSIX account, SSHA hash function or SHA1 is the easiest solution.

function ssha_encode($text) {
  for ($i=1;$i<=10;$i++) {
    $salt .= substr('0123456789abcdef',rand(0,15),1);
  }
  $hash = "{SSHA}".base64_encode(pack("H*",sha1($text.$salt)).$salt);
  return $hash;
}
 
function ssha_check($text,$hash) {
  $ohash = base64_decode(substr($hash,6));
  $osalt = substr($ohash,20);
  $ohash = substr($ohash,0,20);
  $nhash = pack("H*",sha1($text.$osalt));
  return $ohash == $nhash;
}

$password = "test";
$hash = ssha_encode($password);
print "$hash\n";
print var_export(ssha_check($password,$hash),true);

Bojack 發表在 痞客邦 留言(0) 人氣()

單純做個筆記

// Connecting to LDAP
$ldaphost = "ldap://IP:389";
$ldapconn = ldap_connect($ldaphost) or die("Could not connect to $ldaphost");

//要新增的資料
$addperson["objectClass"][0] = "top";
$addperson["objectClass"][1] = "inetOrgPerson";
$addperson["objectClass"][2] = "person";
$addperson["objectClass"][3] = "qmailUser";
$addperson["mailMessageStore"] = "/var/qmail/maildirs/bojack";
$addperson["qmailDotMode"] = "both";
$addperson["sn"] = "Bojack";
//加密方式有 MD5 or SHA
//$newpassword = "{MD5}" . base64_encode(pack("H*",md5($password)));
$newpassword = "{SHA}".base64_encode(pack("H*",sha1($password)));
$addperson["userPassword"] = $newpassword;
$addperson["mailQuotaSize"] = "104857600";
$addperson["mail"] = "bojack@bojack.com";
$addperson["deliveryMode"] = "nolocal";
$addperson["uid"] = "bojack";
$addperson["accountStatus"] = "active";
$addperson["mailHost"] = "smtp.bojack.com";
$addperson["cn"] = "bojack";
$addperson["deliveryProgramPath"] = "/usr/bin/maildrop -w 95";
$addperson["qmailGID"] = "600";
$addperson["qmailUID"] = "600";
$addperson["mailReplyText"] = " ";

if($ldapconn) {
    ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
    ldap_bind($ldapconn,"cn=Manager,dc=bojack,dc=com","Password");
    ldap_add($ldapconn,"uid=bojack,ou=user,dc=bojack,dc=com",$addperson);
}

ldap_close($ldapconn);

Bojack 發表在 痞客邦 留言(0) 人氣()

這陣子裝了 PHP 5.3.4 ... 發現以前的程式都出不來了

原來是以前我都是用

<?

程式碼

?>

而預設 copy 出來的 php.ini 已經把 short_open_tag 設為 off

所以它只會去認

<?php

程式碼

?>

把 short_open_tag 打開成 On 重開 Apache 即可

Bojack 發表在 痞客邦 留言(0) 人氣()

今天裝了一台 PHP 5.3.4 + MySQL 4.1.27 ... 拿了一個很舊的 phpMyAdmin 2.10.1 來 run

一開首頁就會噴出一堆錯誤

Deprecated: Function eregi() is deprecated in /path/to/phpMyadmin/libraries/select_lang.lib.php on line 143

if (($envType == 1 && eregi('^(' . $expr . ')(;q=[0-9]\\.[0-9])?$', $str))
            || ($envType == 2 && eregi('(\(|\[|;[[:space:]])(' . $expr . ')(;|\]|\))', $str))) {

要把上面二行替代成這樣

if (($envType == 1 && preg_match('/^(' . $expr . ')(;q=[0-9]\\.[0-9])?$/', $str))
            || ($envType == 2 && preg_match('/(\(|\[|;[[:space:]])(' . $expr . ')(;|\]|\))/', $str))) {

修完這個問題之後,又跳出了下面這訊息

Deprecated: Function ereg_replace() is deprecated in /path/to/phpMyAdmin/libraries/check_user_privileges.lib.php on line 26

$show_grants_dbname = ereg_replace('^`(.*)`', '\\1',  $show_grants_dbname);

要把上面行再替換成這樣就好了

$show_grants_dbname = preg_replace('/^`(.*)`/i', '\\1',  $show_grants_dbname);

可以參考這篇文章 [ PHP ] PHP 5.2.X 升級 PHP 5.3.X 後不宜使用的function

官網說明:Deprecated features in PHP 5.3.x

Bojack 發表在 痞客邦 留言(0) 人氣()

今天邱董發信有亂碼的問題,爬了一下這一篇使用PHP mail()寄送UTF-8編碼之電子郵件

It's OK !!

Bojack 發表在 痞客邦 留言(0) 人氣()

最近打算開始學 Java 了,以前常聽到 J2EE、J2SE、J2ME,說實在都不知道該如何區別

原來它的分類是這樣的

Java2 Enterprise Edition : 提供企業伺服端應用

Java2 Standard Edition : 提供一般程式開發應用

Java2 Micro Edition : 提供微電腦應用

好的開始是成功的一半,繼續 Go Go Go !!

Bojack 發表在 痞客邦 留言(0) 人氣()

近來在寫一個 PHP 程式,想說要防護一些網頁惡意攻擊

目前用了一個套件是 PHPIDS,可以參考這篇 網站安全的監控平台—PHPIDS文章 來使用

話說我 include 了 example.php 進來後,還是有稍微改了一點程式

把記錄 Log 的部份關了,若有偵測到攻擊也直接 exit 掉程式 !

另外也可以再研究一下這篇 PHP SQL Injection 和 XSS 的偵測程式 和 程式撰寫注意事項 - 2008 ,還蠻詳盡提醒要注意的有哪些

Bojack 發表在 痞客邦 留言(2) 人氣()

先前都沒遇到過,這二天在機器上裝了 Appserv 就出現了,搜尋了一下解決了這問題

/* 時間校時,不然會差8小時 */
date_default_timezone_set("Asia/Taipei");

PHP.LA - 解决PHP的date函數差8個小時的方法

2010-06-15 補充

或是修改 php.ini 就好了

php 5.10 (含)以上的版本

date.timezone = Asia/Taipei

php 5.10 以前的版本

putenv ('TZ=Asia/Taipei');

Bojack 發表在 痞客邦 留言(0) 人氣()

因為自己學校目前是使用 Openwebmail + LDAP 驗證

然而 LDAP 是不分大小寫的,所以就算英文 key 大寫的也可以驗證通過

今天 Google 了一下 Perl 程式的語法,發現將英文轉大寫的語法是 uc,轉成小寫的語法是 lc

所以編輯 .openwebmail.pl 檔案找到下面二段的語法

sub login {
   my $clientip=ow::tool::clientip();
   $loginname=param('loginname')||'';
   $loginname=lc $loginname;
   $loginname=~s/\s//g; # remove space,\t,\n,\r
   $default_logindomain=safedomainname(param('logindomain')||'');

sub autologin {
#auto login with cgi parm or cookie
   $loginname=param('loginname')||cookie('ow-loginname');
   $loginname=lc $loginname;
   $loginname=~s/\s//g; # remove space,\t,\n,\r

這樣就可以了!再也不會有學生因為登入輸入大寫的字母而有問題啦!

Bojack 發表在 痞客邦 留言(1) 人氣()

原 PO 問題如下

※ 引述《gyd (ipod touch之路)》之銘言:
: 以下是計數器的程式碼
: $c=file("counter.txt");
: $visit=$c[0]+1;
: echo "$visit";
: $fp=fopen("counter.txt", "w");

想請問一下
每過一段時間後我都會發現計數器又從0開始算

是code有bug還是?

請問如何解決或是有更佳的程式寫法?


bibo9901 的回答

問題在這個"w"

根據php.net
Open for writing only;place the file pointer at the beginning of the file
and truncate the file to zero length.
If the file does not exist, attempt to create it.

就是說,當執行到 $fp=fopen("counter.txt","w"); 之後
counter.txt 會被清空

這時如果有另一人執行同樣的 php
$c=file("counter") 會變成空的陣列
所以 fputs($fp,$c[0]+1); 會將 1 寫入 counter.txt
看起來就好像是歸零一樣XD

難怪以前我的計數器都會被歸 0

Bojack 發表在 痞客邦 留言(0) 人氣()

AD 的部份

<?php
// connect to AD server
$ldapconn = ldap_connect("AD主機") or die("Could not connect to AD server.");
$set = ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);

$ldap_bd = ldap_bind($ldapconn,"Administrator@AD主機","密碼");
$result = ldap_search($ldapconn,"ou=employee,dc=ad,dc=bojack,dc=com,dc=tw","(CN=bojack)") or die ("Error in query");

$data = ldap_get_entries($ldapconn,$result);

echo $data["count"]. " entries returned\n";

for($i=0; $i<=$data["count"];$i++) {
        for ($j=0;$j<=$data[$i]["count"];$j++) {
                echo $data[$i][$j].": ".$data[$i][$data[$i][$j]][0]."\n<br>";
        }
}
ldap_close($ldapconn);
?>

LDAP 的部份

<?php
// connect to ldap server
$ldapconn = ldap_connect("LDAP 主機")  or die("Could not connect to LDAP server.");
$set = ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);

$ldap_bd = ldap_bind($ldapconn,"cn=root,dc=ldap,dc=bojack,dc=com,dc=tw","密碼");
$result = ldap_search($ldapconn,"ou=employee,dc=ldap,dc=bojack,dc=com,dc=tw","(uid=bojack)") or die ("Error in query");

$data = ldap_get_entries($ldapconn,$result);

echo $data["count"]. " entries returned\n";

for($i=0; $i<=$data["count"];$i++) {
        for ($j=0;$j<=$data[$i]["count"];$j++) {
                echo $data[$i][$j].": ".$data[$i][$data[$i][$j]][0]."\n<br>";
        }
}

/* 若要 show 出某個欄位 */
echo $data[0]["userpassword"][0] ."<br>";

ldap_close($ldapconn);
?>

若要比對密碼是否正確 (以LDAP為例)

<?php
if ($ldapconn) {

if(@ldap_bind($ldapconn,"uid=bojack,ou=employee,dc=ldap,dc=bojack,dc=com,dc=tw","密碼"))
{
        echo "password correct!";
} else {
        echo "wrong password!";
}

}

?>

參考資料

Integrating Active Directory with PHP

PHP程式使用 Windows Server AD 認證身份

Modifying Active Directory passwords through PHP and IIS ( 這一篇有說怎麼改 AD 的密碼,但我試不出來 -_- )

PHP/LDAP - change user password in ad

Bojack 發表在 痞客邦 留言(0) 人氣()

header("HTTP/1.1 403 Forbidden");

感謝張學弟指導

 

Bojack 發表在 痞客邦 留言(0) 人氣()

1 234