יום שלישי, 13 בדצמבר 2011

פרצת אבטחה חמורה בקליקוויו

לראות ולא להאמין: בקבצי ה-QVW וה-QVD של קליקוויו, נשמר ה-Connection string המלא לבסיס הנתונים, כולל משתמש וסיסמה - בצורה לא מוצפנת.
הפרצה החמורה התגלתה ופורסמה ע"י Luca Jonathan Panetta, בפורום הבינלאומי של קליקויו:
http://community.qlikview.com/thread/40308?start=0&tstart=0
כדי לראות זאת, צריך פשוט לפתוח את הקובץ ב-Notepad ולחפש את המילה password.
דווח שהבעיה תוקנה בגרסה 11, כך שעכשיו יש עוד סיבה טובה לשדרג - ולא לשכוח להריץ שוב את כל המודלים (כולל הישנים שאינם בשימוש), כדי לעדכן את קבצי ה-QVD.
בינתיים מומלץ בחום לוודא שקבצי ה-QVD (וכמובן ה-QVW) מוגנים היטב ואינם נגישים למי שאיננו אמור לדעת את הסיסמה לבסיס הנתונים.

יום שני, 5 בדצמבר 2011

מציאת שדה טקסט ב-DataBase ע"פ ערך, בעזרת QlikView

קורה שאנחנו לא יודעים מהו שם השדה שאנו זקוקים לו ב-DataBase, ולא מצליחים למצוא אותו בעזרת שאילתות על הקטלוג.
אפשר לחפש את השדה ע"פ אחד הערכים שבו (בד"כ בשדה טקסט). ניתן להריץ ב-DataBase פונקציה שרצה על כל הטבלאות ומחפשת בכל שדה טקסט את המחרוזת. פונקציות כאלו מסתובבת ברשת (גם ל-Oracle וגם ל-MS-SQL).
הבעיה היא שהרצת פונקציה דורשת הרשאות כתיבה ל-DataBase - משהו שכדאי להימנע ממנו בתור אנשי BI.
ובכן, ניתן להשתמש ב-QlikView כדי לבצע פעולה דומה.

ראשית, כדי לנטרל הודעות שגיאה שעלולות לצוץ, נגדיר:
set errormode = 0;
ניצור את ההתחברות ל-DataBase, את הסכמה הרצויה, ואת המחרוזת שאנו מעוניינים לחפש:
(connect to db);
set vSchema = 'MySchema';
set vString = 'StringToFind';
נביא את כל הטבלאות וכל השדות:
tabs:
sqltables;

cols:
sqlcolumns;
ניצור טבלת עמודות זמנית, הכוללת רק את הסכמה שלנו, ורק עמודות מסוג טקסט. נצרף לה את סוג הטבלה, ונמחק את הטבלאות הקודמות:
Columns_Temp:
load 
     TABLE_NAME,
     COLUMN_NAME
resident
     cols
where
     TABLE_SCHEMA = '$(vSchema)'
     and DATA_TYPE = 129;

left join
load
     TABLE_NAME,
     TABLE_TYPE
resident
     tabs;

drop tables tabs, cols;

ניצור טבלת עמודות סופית, שבה רק עמודות מטבלאות מסוג "טבלה" (ולא Views וכד'), ונמחק את הטבלה הזמנית:

Columns:
load
     TABLE_NAME,
     COLUMN_NAME
resident
     Columns_Temp
where
     TABLE_TYPE = 'TABLE';

drop table Columns_Temp;

לבסוף, ניצור לולאה שרצה על כל עמודה, ומחפשת בה את המחרוזת:
for x = 0 to NoOfRows('Columns')-1
     let vTable = peek('TABLE_NAME',x, 'Columns');
     let vColumn = peek('COLUMN_NAME',x, 'Columns');
     Results:
     sql select
          $(vColumn) as value,
          '$(vColumn)' as column_name,
          '$(vTable)' as table_name
     from
          $(vSchema).$(vTable)
     where
          $(vColumn) = '$(vString)' ;
next
לאחר ריצת המודל, נקבל בשדות table_name ו-column_name את הטבלה והעמודה (או הטבלאות והעמודות) שבהן נמצא הערך.