บันทึกการซน Thaiware

อันนี้เป็นบันทึกสมัย QA เปิดใหม่ๆนะครับ ผมแจ้ง bug ไปเมื่อ 13 มกราคม 2013 ครับ ผมถือว่านานแล้วเลยเอาออกมาเล่าสู่กันฟัง หลายอย่างกันไปแล้วครับ แต่เอามาแสดงเป็นอุธาหรณ์สำหรับ Programmer ครับ

อันแรกที่เจอ เป็นผลจากการซนของผมครับ ความซนอย่างหนึ่งของผมคือ ถ้ารู้ว่าเป็น custom web ผมจะลองใส่ ‘ or ‘1’=’1 ลงไปครับ ถ้าเป็นหน้า login แล้วผ่านหรือ error ขึ้น ก็ Jackport ครับ เป็น SQL Injection พื้นฐาน ไม่ขออธิบายนะครับ หาตาม Google ได้ทั่วไป จริงๆทำแบบนี้แล้วเกิด memory limit เพราะเค้าไม่ได้ใส่ limit ไว้เลยดึงข้อมูลทั้งหมดมาใส่ ram แต่มันมากเกินไปใส่ไม่หมด วิธีแก้คือใช้ prepare หรืออย่างน้อยใช้ mysql_escape_string ครับ หรือไม่ก็เอา username ไป select อันเดียว แล้วตรวจ password ด้วย php ครับ

อันที่สอง ผมใช้ Dev Console ของ Chrome แก้ Cookie ตัว acc_member_id กับ acc_type ให้เป็นของ admin ได้ (จริงๆได้แค่ดูข้อมูลของ id=1 แต่คิดว่าถ้าลองดีๆ ก็น่าจะได้สิทธิไม่ยาก) ผมคาดว่าเค้าเอา ID จาก Cookie ไปค้นหาข้อมูลตรงๆใน Database เลยก็เป็นได้ ซึ่งไม่ควรทำ โดยทั่วไปเราไม่ควรเชื่อข้อมูลจากฝั่ง client หรือควรมีมาตรการยืนยันมากกว่านี้

อันที่สาม เป็น ผลมาจากครั้งที่ 2 ครับ ผมคาดว่าเค้าใช้ session ยืนยันตัวตนแทนในกรณีที่มี session ผมก็ใช้วิธีเดียวกับวิธีที่ 2 แต่คราวนี้ผมไม่แน่ใจว่าแก้พวก id กับ type ได้ไหม ใน mail ผมไม่ได้มีข้อมูลด้านนี้ แต่มีข้อมูลอีกแบบคือ ผมสามารถใส่ sql injection ลงไปในช่อง acc_member_id แล้วเกิด error memory limit ขึ้น ซึ่งผมเดาว่ามันคงไปดึงข้อมูลทั้งหมดใน DB ออกมาแน่ๆเลย ในตอนนั้นผมแนะนำให้เค้าใช้ mysqli (หรือ PDO) เพื่อให้ใช้ prepare statement เพื่อป้องกัน sql injection ครับ แต่จริงๆผมลืมแนะนำไปว่า ควรใส่ limit 1 ไว้ด้วย เพื่อประสิทธิภาพที่ดีครับ คือถ้าเจอ 1 ตัวแล้วมันจะหยุดหาไม่หาต่อ แล้วก็หากไม่มี session ควรยืนยันตัวตนผ่านวิธีอื่นไม่ใช่เอา id อย่างเดียวไปหาตรงๆ อย่างเช่นเอา pass มาก md5 หลายๆชั้นใส่ cookie แล้วเวลายืนยันก็ไป select id ออกมา แล้วเอา pass มาทำด้วยวิธีเดียวกันถ้าตรงกับ pass ที่เข้ารหัสใน cookie ค่อยเอาข้อมูลใส่ session [ref to mysqli.prepare]

อันสุดท้าย [สถานะวันที่ 22/11/13 คือยังไม่ได้รับการแก้ไข]  ดังนั้นผมยังไม่บอกไรมาก บอกได้แค่ XSS จ้า

การลบ Mail Queue ทั้งหมดออกจาก server

คือพอดี server ผมมีปัญหาว่าผมลง vBulletin ไว้ แล้วทีนี้ผมตั้งว่าถ้าเกิด error ให้ email หาผม แล้วปัญหามันเกิดเมื่อ วันนึง MySQL มันล่ม และช่วงนั้นคนเข้าเยอะ ผลคือ Mail จำนวนมากถูกส่งมาให้ผม และอีกจำนวนมากค้างอยู่ใน Mail Queue ผมรอ 3 วันมันก็ไม่หมดสักที ผมเลยต้องหาวิธีลบเมลขาออกให้หมด ผลที่ได้คือเจอเว็บนี้ครับ แล้วทำตามคำสั่งนี้ (สำหรับ DirectAdmin นะครับ ตัวอื่นผมไม่ชัวร์)

cd /var/spool
mv exim exim.old
mkdir -p exim/input
mkdir -p exim/msglog
mkdir -p exim/db
chown -R mail:mail exim
/sbin/service exim restart

#หากทำงานได้ปกติ ให้ทำข้างล่างนี้ต่อครับ
rm -rf exim.old

 

วิธีการสุ่มค่าจาก SQL ที่ดีกว่าการใช้ ORDER BY RAND()

โดยทั่วไปเท่าที่ผมเห็น การจะสั่ง sql ให้ดึงแถวที่ต้องการมาโดยเรียงลำดับแบบสุ่มจะใช้วิธี ORDER BY RAND() เช่น

SELECT * FROM `table` WHERE 1 ORDER BY RAND()

แต่วิธีนี้ไม่ใช่วิธีที่ดีเลย เพราะสมมุตว่าข้อมูลมีจะนวน 100000 แถว จะต้องเกิดการ random ค่าทั้งหมด 100000 ครั้ง นอกจากนั้นเมื่อ random เสร็จ ก็ต้องเอาข้อมูลนั้นมาเรียงลำดับใหม่อีกครั้ง ซึ่งในขั้นตอนการเรียง โดยมากแล้ว ตัว Database จะไม่ยอมให้ใช้เนื้อที่เกินจำนวนหนึ่งใน RAM แต่ถ้าข้อมูลเยอะๆแบบนี้ จะใช้การเขียนลง file ก่อน แล้วค่อย sort ซึ่งทำให้ช้ากว่าใน RAM มาก

ดังนั้นผมจึงหาวิธีสุ่มค่าที่มีประสิทธิ์ภาพที่ดีกว่าในเน็ต ซึ่งได้ผลลัพธ์คือเว็บนี้ เค้าแนะนำให้ทำแบบนี้แทนครับ

SELECT  * FROM    (
        SELECT  @cnt := COUNT(*) + 1,
                @lim := 10
        FROM    `table`
) vars
STRAIGHT_JOIN
 (
        SELECT  r.*,
                @lim := @lim - 1
        FROM    `table` r
        WHERE   (@cnt := @cnt - 1)
                AND RAND(20090301) < @lim / @cnt
) i

โดย `table` หมายถึงชื่อตาราง และตรง @lim := 10 หมายถึงต้องการ 10 ตัว ส่วนตัวเลข 20090301 เค้าบอกเป็นเลขอะไรก็ได้ เค้าเอาเลขนี้มาจากวันที่โพส และควรเปลี่ยนทุกครั้ง เพื่อให้ผลไม่เหมือนเดิม

หลักการทำงานคือเหมือนเค้าใช้หลักความน่าจะเป็นแทนการสุ่มมั้งครับ

จริงๆในเว็บต้นฉบับ เค้าบอกมีวิธีสำหรับแถวเดียวอยู่ด้วย แต่ผมไม่สามารถทำความเข้าใจได้ครับ

css ให้ default ในกรณีไม่ hover

บทความนี้เป็นเรื่องของ CSS แบบง่าย คือผมทำงานเรื่องนึง คือเค้าให้ทำ list ที่มี object 3 ตัว และ fix ความสูงไว้ ผมต้องทำตามนี้คือ

  1. ในกรณีไม่ได้ hover li ใดไว้ ให้ li แรกแสดงรายละเอียด
  2. กรณีมีการ hover ให้แสดงรายละเอียดของตัวที่ hover

อันนี้คือสิ่งที่ผมทำได้ http://jsfiddle.net/M4Db5/1/

หลักการของผมคือ ถ้า hover ปกติก็ให้มันแสดง แต่ถ้า containner ไม่ได้ hover ไป hover ที่อื่น ก็ให้เลือกตัวแรก ง่ายๆครับ ไม่ยาก

EDIT: เพิ่ม class default ไว้บอกว่าถ้าไม่ hover จะแสดงตัวไหน

การลงโปรแกรมบน Ubuntu อีกเครื่องหนึ่ง ให้มีโปรแกรมเหมือนเครื่องต้นฉบับทั้งหมด

วิธีการคือ

  1. ไปที่เครื่องหลักที่มีโปรแกรมครบ สั่ง
    dpkg --get-selections | grep -v deinstall > installed-packages-list
  2. ไปที่เครื่องลูกที่เราจะลงโปรแกรมเหมือนเครื่องหลัก
  3. คัดลอก /etc/apt จากเครื่องหลัก ลงเครื่องลูก และคัดลอก installed-package-list จากเครื่องหลักมาไว้ใน home ของเราด้วย
  4. ตั้งค่า Internet เครื่องลูกให้เรียบร้อยใช้ออกเน็ตได้
  5. สั่ง
    sudo apt-get update
  6. สั่ง
    dpkg --set-selections < /media/disk/backup/installed-package-list
  7. ติดตั้ง dselect โดยสั่ง
    sudo apt-get install dselect
  8. เปิด dselect ด้วยสิทธิ์ root
    sudo dselect
  9. เลือก Install จากนั้นโปรแกรมจะลงโปรแกรมทั้งหมดให้อัตโนมัติ

ข้อมูลจาก http://ubuntuforums.org/showthread.php?t=1077135&p=6779737#post6779737